Exemple #1
0
mreturn mod_log_archiver(mapi m, void *arg)
{
	jid svcs = (jid) arg;
	xmlnode x;
	char ts[101];
	struct tm now;
	unsigned long ltime;

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

	log_debug("archiving message");

	/* get a copy wrapped w/ a route and stamp it w/ a type='archive' (why not?) */
	x = xmlnode_wrap(xmlnode_dup(m->packet->x), "route");
	xmlnode_put_attrib(x, "type", "archive");

	/* Mark the route with an direction attribute */
	switch (m->e) {
	case es_IN:
		xmlnode_put_attrib(x, "direction", "in");
		break;
	case es_OUT:
		xmlnode_put_attrib(x, "direction", "out");
		break;
	}

	/* Mark the route with a timeStamp attribute */
	time(&ltime);
#ifdef WIN32
	now = *localtime(&ltime);
#else
	localtime_r(&ltime, &now);
#endif

	strftime((char *) ts, 100, "%m/%d/%Y %H:%M:%S", &now);

	xmlnode_put_attrib(x, "stamp", ts);

	/* if there's more than one service, copy to the others */
	for (; svcs->next != NULL; svcs = svcs->next) {
		xmlnode_put_attrib(x, "to", jid_full(svcs));
		deliver(dpacket_new(xmlnode_dup(x)), NULL);
	}

	/* send off to the last (or only) one */
	xmlnode_put_attrib(x, "to", jid_full(svcs));
	deliver(dpacket_new(x), NULL);

	return M_PASS;
}
Exemple #2
0
Request * add_request(RequestType type,const char *from,const char *to,
			const char *id,xmlnode query, void *data,
			Stream *stream){
Request *r;
Session *s;

	r=g_new0(Request,1);
	r->type=type;
	r->id=g_strdup(id);
	r->from=g_strdup(from);
	if (to) r->to=g_strdup(to);
	else r->to=NULL;
	if (query) r->query=xmlnode_dup(query);
	else r->query=NULL;
	r->stream=stream;

	if (type==RT_VCARD || type==RT_SEARCH || type==RT_CHANGE) {
		s=session_get_by_jid(from, stream,0);
		if (s==NULL) return NULL;

		r->hash=id_counter++;
		gg_pubdir50_seq_set((gg_pubdir50_t)data, r->hash);
		gg_pubdir50(s->ggs, (gg_pubdir50_t)data);
		g_hash_table_insert(lookups, &r->hash, r);
	}
	requests=g_list_append(requests,r);
	return r;
}
Exemple #3
0
void con_room_sendwalk(gpointer key, gpointer data, gpointer arg)
{
  xmlnode x = (xmlnode)arg;
  cnu to = (cnu)data;
  cnu from;
  xmlnode output;

  if(x == NULL || to == NULL) 
  {
    log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE);
    return;
  }
  
  if (to->remote == 1)
    return;

  from = (cnu)xmlnode_get_vattrib(x,"cnu");

  if(j_strcmp(xmlnode_get_name(x),"presence") == 0)
  {
    output = add_extended_presence(from, to, x, NULL, NULL, NULL);
    if(jid_cmp(to->realid,from->realid)==0) //own presence
    {
      add_status_code(output, STATUS_MUC_OWN_PRESENCE);
    }
    con_user_send(to, from, output); 
  }
  else
  {
    con_user_send(to, from, xmlnode_dup(x)); /* Need to send duplicate */
  }
}
Exemple #4
0
/* thread safe with sem */
mreturn mod_presence_deliver(mapi m, void *arg)
{
	session cur;

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

	log_debug("deliver phase");

	/* only if we HAVE a user, and it was sent to ONLY the user@server, and there is at least one session available */
	if (m->user != NULL && m->packet->to->resource == NULL && js_session_primary_all_sem(m->user) != NULL) {
		log_debug("broadcasting to %s", m->user->user);

		/* broadcast */
		for (cur = m->user->sessions; cur != NULL; cur = cur->next) {
			if (cur->priority < -128)
				continue;
			js_session_to(cur, jpacket_new(xmlnode_dup(m->packet->x)));
		}
		SEM_UNLOCK(m->user->sem);

		if (jpacket_subtype(m->packet) != JPACKET__PROBE) {
			/* probes get handled by the offline thread as well? */
			xmlnode_free(m->packet->x);
			return M_HANDLED;
		}
	}

	return M_PASS;
}
Exemple #5
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;
}
Exemple #6
0
void _mod_presence_broadcast_trusted(session s, jid notify, xmlnode x)
{
	jid cur;
	xmlnode pres;

	for (cur = notify; cur != NULL; cur = cur->next) {
		if (!js_istrusted(s->u, cur))
			continue;	/* perform insersection search, must be in both */
		s->c_out++;
		pres = xmlnode_dup(x);
		xmlnode_put_attrib(pres, "to", jid_full(cur));

		/* send it to POSTOUT for filter purposes */
		js_post_out_main(s, jpacket_new(pres));
	}
}
Exemple #7
0
Session * session_create(User *user,const char *jid,const char *req_id,
		const xmlnode query,struct stream_s *stream,int delay_login){
Session *s;
char *njid;

	g_message(L_("Creating session for '%s'"),jid);
	njid=jid_normalized(jid,0);
	if (njid==NULL){
		g_message(L_("Bad JID: '%s'"),jid);
		return NULL;
	}

	g_assert(user!=NULL);

	if (user->deleted){
		g_message(L_("User deleted: '%s'"),user->jid);
		return NULL;
	}
	
	s=g_new0(Session,1);
	s->user=user;
	user_ref(user);
	s->gg_status=-1;
	s->jid=g_strdup(jid);
	if (req_id) s->req_id=g_strdup(req_id);
	s->query=xmlnode_dup(query);
	s->current_server=g_list_first(gg_servers);
	s->g_pollfd.fd=-1;

	if (!delay_login && session_try_login(s)){
		session_destroy(s);
		return NULL;
	}

	s->s=stream;

	g_assert(sessions_jid!=NULL);
	g_hash_table_insert(sessions_jid,(gpointer)njid,(gpointer)s);
	return s;
}
Exemple #8
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;
}