예제 #1
0
mreturn mod_roster_auto_in_s10n(mapi m, void *arg)
{
	xmlnode reply, x;

	log_debug("AUTO ROSTER");

	//in not s10n
	if (m->packet->type != JPACKET_S10N)
		return M_IGNORE;
	//if no to
	if (m->packet->to == NULL)
		return M_PASS;
	//if from me
	if (jid_cmpx(m->s->uid, m->packet->from, JID_USER | JID_SERVER) ==
	    0)
		return M_PASS;

	log_debug("handling incoming s10n");

	switch (jpacket_subtype(m->packet)) {
	case JPACKET__SUBSCRIBE:
		log_debug("SUBSCRIBE");
		reply =
		    jutil_presnew(JPACKET__SUBSCRIBED,
				  jid_full(m->packet->from), NULL);
		js_session_from(m->s, jpacket_new(reply));
		reply =
		    jutil_presnew(JPACKET__SUBSCRIBE,
				  jid_full(m->packet->from), NULL);
		js_session_from(m->s, jpacket_new(reply));
		break;
	case JPACKET__SUBSCRIBED:
		break;
	case JPACKET__UNSUBSCRIBE:
		log_debug("UNSUBSCRIBE");
		//reply = jutil_presnew(JPACKET__UNSUBSCRIBED, jid_full(m->packet->from),NULL);
		//js_session_from(m->s, jpacket_new(reply));
		//remove account.
		reply = jutil_iqnew(JPACKET__SET, NS_ROSTER);
		x = xmlnode_get_tag(reply, "query");
		x = xmlnode_insert_tag(x, "item");
		xmlnode_put_attrib(x, "jid",
				   jid_full(jid_user(m->packet->from)));
		xmlnode_put_attrib(x, "subscription", "remove");
		js_session_from(m->s, jpacket_new(reply));

		// reply = jutil_iqnewpresnew(JPACKET__UNSUBSCRIBE, jid_full(m->packet->from),NULL);
		// js_session_from(m->s, jpacket_new(reply));
		break;
	case JPACKET__UNSUBSCRIBED:
		break;
	}

	xmlnode_free(m->packet->x);
	return M_HANDLED;
}
예제 #2
0
파일: conference_room.c 프로젝트: bcy/muc
void con_room_leaveall(gpointer key, gpointer data, gpointer arg)
{
  cnu user = (cnu)data;
  xmlnode info = (xmlnode)arg;
  char *alt, *reason;
  xmlnode presence;
  xmlnode tag;
  xmlnode element;
  xmlnode node;
  xmlnode destroy;

  log_debug(NAME, "[%s] reason :  %s", FZONE, xmlnode2str(info));
  if(user == NULL) 
  {
    log_warn(NAME, "[%s] Aborting - NULL user attribute found", FZONE);
    return;
  }
  
  if (user->remote == 1)
    return;

  presence = jutil_presnew(JPACKET__UNAVAILABLE, NULL, NULL);
  tag = xmlnode_insert_tag(presence,"x");
  xmlnode_put_attrib(tag, "xmlns", NS_MUC_USER);

  element = xmlnode_insert_tag(tag, "item");
  xmlnode_put_attrib(element, "role", "none");
  xmlnode_put_attrib(element, "affiliation", "none");

  if (info != NULL)
  {
    destroy = xmlnode_insert_tag(tag, "destroy");
    reason = xmlnode_get_tag_data(info, "reason");
    node = xmlnode_insert_tag(destroy, "reason");

    if(reason != NULL)
    {
      xmlnode_insert_cdata(node, reason, -1);
    }

    alt = xmlnode_get_attrib(info, "jid");

    if (alt != NULL)
    {
      xmlnode_put_attrib(destroy, "jid", alt);
    }
  }

  con_user_send(user, user, presence);
}
예제 #3
0
파일: sessions.c 프로젝트: smokku/wpjabber
/* child that cleans up a session
   session thread */
void _js_session_end(session s)
{
	xmlnode x, temp;

	/* debug message */
	log_debug("THREAD:SESSION exiting");

	/* only for moules es_END */
	temp = s->presence;
	if (temp != NULL
	    && j_strcmp(xmlnode_get_attrib(temp, "type"),
			"unavailable") != 0) {
		/* create a new presence packet with the reason the user is unavailable */
		x = jutil_presnew(JPACKET__UNAVAILABLE, NULL, NULL);
		xmlnode_put_attrib(x, "from", jid_full(s->id));

		/* free the old presence packet */
		s->presence = x;
	} else {
		temp = NULL;
	}

	/* make sure the service knows the session is gone */
	if (s->sid != NULL)
		js_session_route(s, NULL);

	/* let the modules have their heyday */
	js_mapi_call(NULL, es_END, NULL, s->u, s);

	/* let the user struct go  */
	THREAD_DEC(s->u->ref);

	/* free old presence */
	if (temp)
		xmlnode_free(temp);

	/* free the session's presence state */
	temp = s->presence;
	s->presence = NULL;

	s->q->count--;

	/* free the session's memory pool */
	register_beat(60, js_session_free, s);

	/* free unavailable presence we have set */
	if (temp)
		xmlnode_free(temp);
}
예제 #4
0
/* session thread */
mreturn mod_presence_in(mapi m, void *arg)
{
	modpres mp = (modpres) arg;
	xmlnode pres;

	if (m->packet->type != JPACKET_PRESENCE)
		return M_IGNORE;

	log_debug("incoming filter for %s", jid_full(m->s->id));

	if (jpacket_subtype(m->packet) == JPACKET__PROBE) {
		/* reply with our presence */
		if (m->s->presence == NULL) {
			log_debug("probe from %s and no presence to return", jid_full(m->packet->from));
		} else if (!mp->invisible && js_trust(m->user, m->packet->from) && !_mod_presence_search(m->packet->from, mp->I)) {
			/* compliment of I in T */
			log_debug("got a probe, responding to %s", jid_full(m->packet->from));
			pres = xmlnode_dup(m->s->presence);
			xmlnode_put_attrib(pres, "to", jid_full(m->packet->from));
			js_session_from(m->s, jpacket_new(pres));
		} else if (mp->invisible && js_trust(m->user, m->packet->from) && _mod_presence_search(m->packet->from, mp->A)) {
			/* when invisible, intersection of A and T */
			log_debug("got a probe when invisible, responding to %s", jid_full(m->packet->from));
			pres = jutil_presnew(JPACKET__AVAILABLE, jid_full(m->packet->from), NULL);
			js_session_from(m->s, jpacket_new(pres));
		} else {
			log_debug("%s attempted to probe by someone not qualified", jid_full(m->packet->from));
		}
		xmlnode_free(m->packet->x);
		return M_HANDLED;
	}

	if (jid_cmp(m->packet->from, m->s->id) == 0) {
		/* this is our presence, don't send to ourselves */
		xmlnode_free(m->packet->x);
		return M_HANDLED;
	}

	/* if a presence packet bounced, remove from the A list */
	if (jpacket_subtype(m->packet) == JPACKET__ERROR)
		mp->A = _mod_presence_whack(m->packet->from, mp->A);

	/* doh! this is a user, they should see invisibles as unavailables */
	if (jpacket_subtype(m->packet) == JPACKET__INVISIBLE)
		xmlnode_put_attrib(m->packet->x, "type", "unavailable");

	return M_PASS;
}
예제 #5
0
파일: sessions.c 프로젝트: smokku/wpjabber
/*
 *  js_session_new -- creates a new session, registers the resource for it
 *
 *  Sets up all the data associated with the new session, then send it a
 *  start spacket, which basically notifies all modules about the new session
 *
 *  returns
 *	a pointer to the new session
 */
session js_session_new(jsmi si, dpacket dp)
{
	pool p;
	session s, cur;
	udata u;
	int i;
	char routeres[10];

	/* screen out illegal calls */
	if (dp == NULL || dp->id->user == NULL || dp->id->resource == NULL
	    || xmlnode_get_attrib(dp->x, "from") == NULL)
		return NULL;

	if ((u = js_user(si, dp->id, 0)) == NULL)
		return NULL;

	if (u->scount >= MAX_USER_SESSIONS) {
		THREAD_DEC(u->ref);
		return NULL;
	}


	log_debug("session_create %s", jid_full(dp->id));

	/* create session */
	p = pool_heap(1024);
	s = pmalloco(p, sizeof(struct session_struct));
	s->p = p;
	s->si = si;

	/* save authorative remote session id */
	s->sid = jid_new(p, xmlnode_get_attrib(dp->x, "from"));

	/* session identity */
	s->id = jid_new(p, jid_full(dp->id));
	/* id bez resource */
	s->uid = jid_user(s->id);
	s->route = jid_new(p, jid_full(dp->id));
	snprintf(routeres, 9, "%X", s);
	jid_set(s->route, routeres, JID_RESOURCE);
	s->res = pstrdup(p, dp->id->resource);
	s->u = u;

	jid_full(s->sid);
	jid_full(s->uid);
	jid_full(s->id);
	jid_full(s->route);

	{
		register char *text;
		text = xmlnode_get_attrib(dp->x, "ip");
		if (text) {
			s->ip =
			    pstrdup(s->p, xmlnode_get_attrib(dp->x, "ip"));
			xmlnode_hide_attrib(dp->x, "ip");
		} else
			s->ip = "none";
	}

	/* default settings */
	s->exit_flag = 0;
	s->roster = 0;
	s->priority = -129;
	s->presence = jutil_presnew(JPACKET__UNAVAILABLE, NULL, NULL);
	xmlnode_put_attrib(s->presence, "from", jid_full(s->id));
	s->c_in = s->c_out = 0;

	for (i = 0; i < es_LAST; i++)
		s->events[i] = NULL;

	SEM_LOCK(u->sem);

	if (u->sessions != NULL) {
		s->q = get_mtq_queue(si, u->sessions->q);

		for (cur = u->sessions; cur != NULL; cur = cur->next)
			if (j_strcmp(dp->id->resource, cur->res) == 0)
				js_session_end_nosem(cur,
						     "Replaced by new connection");
	} else {
		s->q = get_mtq_queue(si, NULL);
	}

	/* make sure we're linked with the user */
	s->next = s->u->sessions;
	s->u->sessions = s;
	s->u->scount++;

	SEM_UNLOCK(u->sem);

	/* session start */
	{
		packet_thread_p pt;
		pt = malloc(sizeof(packet_thread_t));
		pt->s = s;
		pt->type = 0;
		fast_mtq_send(s->q->mtq, pt);
	}

	THREAD_DEC(u->ref);
	return s;
}
예제 #6
0
/* session thread */
mreturn mod_presence_out(mapi m, void *arg)
{
	xmlnode pnew, delay, pold;
	modpres mp = (modpres) arg;
	session cur = NULL;
	int oldpri, newpri;
	char *priority;

	if (m->packet->type != JPACKET_PRESENCE)
		return M_IGNORE;

	if (m->packet->to != NULL
	    || jpacket_subtype(m->packet) == JPACKET__PROBE
	    || jpacket_subtype(m->packet) == JPACKET__ERROR)
		return M_PASS;

	log_debug("new presence from %s of %s", jid_full(m->s->id), xmlnode2str(m->packet->x));

	/* pre-existing conditions (no, we are not an insurance company) */
	oldpri = m->s->priority;

	/* check that the priority is in the valid range */
	priority = xmlnode_get_tag_data(m->packet->x, "priority");
	if (priority == NULL) {
		newpri = 0;
	} else {
		newpri = j_atoi(priority, 0);
		if (newpri < -128 || newpri > 127) {
			log_notice("mod_presence", "got presence with invalid priority value from %s", jid_full(m->s->id));
			xmlnode_free(m->packet->x);
			return M_HANDLED;
		}
	}

	/* invisible mode is special, don't you wish you were special too? */
	if (jpacket_subtype(m->packet) == JPACKET__INVISIBLE) {
		log_debug("handling invisible mode request");

		/* if we get this and we're available, it means go unavail first then reprocess this packet, nifty trick :) */
		if (oldpri >= -128) {
			js_session_from(m->s,
					jpacket_new(jutil_presnew
						    (JPACKET__UNAVAILABLE,
						     NULL,
						     xmlnode_get_tag_data(m->packet->x,"status")
						    )));
			js_session_from(m->s, m->packet);
			return M_HANDLED;
		}

		/* now, pretend we come online :) */
		/* (this is the handling of the reinjected invisible presence
		 * or an initial invisible presence) */
		mp->invisible = 1;
		mod_presence_roster(m, NULL);	/* send out probes to users we are subscribed to */
		m->s->priority = newpri;

		/* store presence in xdb? */
		if (mp->conf->pres_to_xdb > 0)
			mod_presence_store(m);

		xmlnode_free(m->packet->x);	/* we do not broadcast invisible presences without a to attribute */

		return M_HANDLED;
	}

	/* our new presence */
	pnew = xmlnode_dup(m->packet->x);

	/* store presence in xdb? */
	if (mp->conf->pres_to_xdb > 0)
		mod_presence_store(m);

	/* stamp the sessions presence */
	delay = xmlnode_insert_tag(pnew, "x");
	xmlnode_put_attrib(delay, "xmlns", NS_DELAY);
	xmlnode_put_attrib(delay, "from", jid_full(m->s->id));
	xmlnode_put_attrib(delay, "stamp", jutil_timestamp());

	/* our old presence */
	pold = m->s->presence;
	m->s->presence = pnew;
	m->s->priority = jutil_priority(pnew);

	log_debug("presence oldp %d newp %d", oldpri, m->s->priority);

	/* if we're going offline now, let everyone know */
	if (m->s->priority < -128) {
		/* jutil_priority returns -129 in case the "type" attribute is missing */
		if (!mp->invisible)
			/* bcc's don't get told if we were invisible */
			_mod_presence_broadcast(m->s, mp->conf->bcc, m->packet->x, NULL);
		_mod_presence_broadcast(m->s, mp->A, m->packet->x, NULL);
		_mod_presence_broadcast(m->s, mp->I, m->packet->x, NULL);

		/* reset vars */
		mp->invisible = 0;
		mp->A->next = NULL;
		mp->I = NULL;

		xmlnode_free(m->packet->x);
		xmlnode_free(pold);
		return M_HANDLED;
	}

	/* available presence updates, intersection of A and T */
	if (oldpri >= -128 && !mp->invisible) {
		_mod_presence_broadcast_trusted(m->s, mp->A, m->packet->x);
		xmlnode_free(m->packet->x);
		xmlnode_free(pold);
		return M_HANDLED;
	}

	/* at this point we're coming out of the closet */
	mp->invisible = 0;

	/* make sure we get notified for any presence about ourselves */
	/* XXX: the following is the original code: it caused existing presences
	 * to be stamped several times and the presence to be sent out twice.

	 pnew = jutil_presnew(JPACKET__PROBE,jid_full(m->s->uid),NULL);
	 xmlnode_put_attrib(pnew,"from",jid_full(m->s->uid));
	 js_session_from(m->s, jpacket_new(pnew));

	 */
	/* XXX: I think this should be okay as well: */

	/* send us all presences of our other resources */
	for (cur = m->user->sessions; cur != NULL; cur = cur->next) {
		pool pool_for_existing_presence = NULL;
		xmlnode duplicated_presence = NULL;
		jpacket packet = NULL;

		/* skip our own session (and sanity check) */
		if (cur == m->s || cur->presence == NULL) {
			continue;
		}

		/* send the presence to us: we need a new pool as js_session_to() will free the packet's pool  */
		pool_for_existing_presence = pool_new();
		duplicated_presence =
		    xmlnode_dup_pool(pool_for_existing_presence,
				     cur->presence);
		xmlnode_put_attrib(duplicated_presence, "to",
				   jid_full(m->user->id));
		packet = jpacket_new(duplicated_presence);
		js_session_to(m->s, packet);
	}

	/* probe s10ns and populate A */
	mod_presence_roster(m, mp->A);

	/* we broadcast this baby! */
	_mod_presence_broadcast(m->s, mp->conf->bcc, m->packet->x, NULL);
	_mod_presence_broadcast(m->s, mp->A, m->packet->x, NULL);

	xmlnode_free(m->packet->x);
	xmlnode_free(pold);

	return M_HANDLED;
}