Exemple #1
0
/* session thread */
mreturn mod_presence_avails(mapi m, void *arg)
{
	modpres mp = (modpres) arg;

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

	if (m->packet->to == NULL)
		return M_PASS;

	log_debug("track presence sent to jids");

	/* handle invisibles: put in I and remove from A */
	if (jpacket_subtype(m->packet) == JPACKET__INVISIBLE) {
		if (mp->I == NULL)
			mp->I = jid_new(m->s->p, jid_full(m->packet->to));
		else
			jid_append(mp->I, m->packet->to);
		mp->A = _mod_presence_whack(m->packet->to, mp->A);
		return M_PASS;
	}

	/* ensure not invisible from before */
	mp->I = _mod_presence_whack(m->packet->to, mp->I);

	/* avails to A */
	if (jpacket_subtype(m->packet) == JPACKET__AVAILABLE)
		jid_append(mp->A, m->packet->to);

	/* unavails from A */
	if (jpacket_subtype(m->packet) == JPACKET__UNAVAILABLE)
		mp->A = _mod_presence_whack(m->packet->to, mp->A);

	return M_PASS;
}
Exemple #2
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 #3
0
mreturn mod_browse_reply(mapi m, void *arg)
{
	xmlnode browse, ns, cur;
	session s;

	if (m->packet->type != JPACKET_IQ)
		return M_IGNORE;
	if (!NSCHECK(m->packet->iq, NS_BROWSE))
		return M_PASS;

	/* first, is this a valid request? */
	switch (jpacket_subtype(m->packet)) {
	case JPACKET__RESULT:
	case JPACKET__ERROR:
		return M_PASS;
	case JPACKET__SET:
		js_bounce(m->si, m->packet->x, TERROR_NOTALLOWED);
		return M_HANDLED;
	}

	log_debug("handling query for user %s", m->user->user);

	/* get this dudes browse info */
	browse = mod_browse_get(m, m->packet->to);

	/* insert the namespaces */
	ns = xdb_get(m->si->xc, m->packet->to, NS_XDBNSLIST);
	for (cur = xmlnode_get_firstchild(ns); cur != NULL;
	     cur = xmlnode_get_nextsibling(cur))
		if (xmlnode_get_attrib(cur, "type") == NULL)
			xmlnode_insert_tag_node(browse, cur);	/* only include the generic <ns>foo</ns> */
	xmlnode_free(ns);

	/* include any connected resources if there's a s10n from them */
	if (js_trust(m->user, m->packet->from)) {
		SEM_LOCK(m->user->sem);
		for (s = m->user->sessions; s != NULL; s = s->next) {
			/* if(s->priority < 0) continue; *** include all resources I guess */
			if (xmlnode_get_tag
			    (browse,
			     spools(m->packet->p, "?jid=", jid_full(s->id),
				    m->packet->p)) != NULL)
				continue;	/* already in the browse result */
			cur = xmlnode_insert_tag(browse, "user");
			xmlnode_put_attrib(cur, "type", "client");
			xmlnode_put_attrib(cur, "jid", jid_full(s->id));
		}
		SEM_UNLOCK(m->user->sem);
	}

	/* XXX include iq:filter forwards */

	jutil_iqresult(m->packet->x);
	jpacket_reset(m->packet);
	xmlnode_insert_tag_node(m->packet->x, browse);
	js_deliver(m->si, m->packet);

	xmlnode_free(browse);
	return M_HANDLED;
}
Exemple #4
0
int at_iq_vcard(ati ti, jpacket jp)
{
    xmlnode data;
    at_session s;

    s = at_session_find_by_jid(ti, jp->from);

    if(jpacket_subtype(jp) != JPACKET__GET ||
      (s && ((!s->icq && jp->to->user) || (s->icq && s->icq_vcard_response))))
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }

    if(!jp->to->user)
    {
        xmlnode_insert_node(jutil_iqresult(jp->x),ti->vcard);
        at_deliver(ti,jp->x);
        return 1;
    }

    if(!s)
        return 0;

    jutil_iqresult(jp->x);
    jp->iq = data = xmlnode_insert_tag(jp->x,"vCard");
    xmlnode_put_attrib(data,"xmlns",NS_VCARD);
    xmlnode_put_attrib(data,"version","3.0");
    xmlnode_put_attrib(data,"prodid","-//HandGen//NONSGML vGen v1.0//EN");
    s->icq_vcard_response = jp;

    aim_icq_getsimpleinfo(s->ass,
                          jp->to->user);
    return 1;
}
Exemple #5
0
int at_iq_disco_items(ati ti, jpacket jp)
{
    xmlnode q;

    if(jpacket_subtype(jp) != JPACKET__GET)
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }

    if(xmlnode_get_attrib(xmlnode_get_tag(jp->x, "query"),"node") != NULL)
    {
        at_bounce(ti, jp, TERROR_NOTALLOWED);
        return 1;
    }

    jutil_iqresult(jp->x);
    q = xmlnode_insert_tag(jp->x, "query");
    xmlnode_put_attrib(q, "xmlns", NS_DISCO_ITEMS);

    at_deliver(ti,jp->x);

    return 1;

}
Exemple #6
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 #7
0
int at_iq_version(ati ti, jpacket jp)
{
    xmlnode os, x, q;
    struct utsname un;

    if(jpacket_subtype(jp) != JPACKET__GET)
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }

    x = jutil_iqresult(jp->x);

    q = xmlnode_insert_tag(x,"query");
    xmlnode_put_attrib(q,"xmlns",NS_VERSION);

    xmlnode_insert_cdata(xmlnode_insert_tag(q,"name"),"AIM Transport",-1);
    xmlnode_insert_cdata(xmlnode_insert_tag(q,"version"), VERSION,-1);

    uname(&un);
    os = xmlnode_insert_tag(q,"os");
    xmlnode_insert_cdata(os,un.sysname,-1);
    xmlnode_insert_cdata(os," ",1);
    xmlnode_insert_cdata(os,un.release,-1);

    at_deliver(ti,x);
    // AGAIN!?!
    return 1;
}
Exemple #8
0
int at_iq_time(ati ti, jpacket jp)
{
    xmlnode x, q;
    time_t t;
    char *tstr;

    if(jpacket_subtype(jp) != JPACKET__GET)
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }
    x = jutil_iqresult(jp->x);

    q = xmlnode_insert_tag(x,"query");
    xmlnode_put_attrib(q,"xmlns",NS_TIME);

    xmlnode_insert_cdata(xmlnode_insert_tag(q,"utc"),jutil_timestamp(),-1);
    xmlnode_insert_cdata(xmlnode_insert_tag(q,"tz"),tzname[0],-1);

    /* create nice display time */
    t = time(NULL);
    tstr = ctime(&t);
    tstr[strlen(tstr) - 1] = '\0'; /* cut off newline */
    xmlnode_insert_cdata(xmlnode_insert_tag(q,"display"),tstr,-1);

    at_deliver(ti,x);
    return 1;
}
Exemple #9
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;
}
Exemple #10
0
void mt_unknown_process(mti ti, jpacket jp)
{
    switch (jp->type)
    {
    case JPACKET_IQ:
        if (jp->to->user != NULL || (ti->con && j_strcmp(ti->con_id,jp->to->server) == 0))
        {
            jp->aux1 = (void *) ti;
            mtq_send(NULL,jp->p,&mt_unknown_bounce,(void *) jp);
        }
        else
        {
            if (j_strcmp(jp->iqns,NS_REGISTER) == 0)
            {
                jp->aux1 = (void *) ti;
                mtq_send(NULL,jp->p,&mt_reg_unknown,(void *) jp);
            }
            else
                mt_iq_server(ti,jp);
        }
        break;

    case JPACKET_MESSAGE:
    case JPACKET_S10N:
        /* message and s10n aren't allowed without a valid session */
        if (jp->to->user != NULL || jpacket_subtype(jp) != JPACKET__SUBSCRIBED)
        {
            jp->aux1 = (void *) ti;
            mtq_send(NULL,jp->p,&mt_unknown_bounce,(void *) jp);
            break;
        }
        /* fall through here to free the node */

    case JPACKET_PRESENCE:
        if (jpacket_subtype(jp) == JPACKET__AVAILABLE && jp->to->user == NULL)
        {
            jp->aux1 = (void *) ti;
            mtq_send(NULL,jp->p,&mt_presence_unknown,(void *) jp);
            break;
        }
        xmlnode_free(jp->x);
    }
}
Exemple #11
0
int at_iq_gateway(ati ti, jpacket jp)
{
    if(jp->to->user != NULL)
    {
        at_bounce(ti, jp, TERROR_NOTALLOWED);
        return 1;
    }

    
    switch(jpacket_subtype(jp))
    {
        case JPACKET__GET:
        {
            xmlnode q;

            jutil_iqresult(jp->x);

            q = xmlnode_insert_tag(jp->x,"query");
            xmlnode_put_attrib(q,"xmlns",NS_GATEWAY);
            xmlnode_insert_cdata(xmlnode_insert_tag(q,"desc"),"Enter the user's screenname",-1);
            xmlnode_insert_tag(q,"prompt");

            break;
        }

        case JPACKET__SET:
        {
            char *user, *id;
    
            user = xmlnode_get_tag_data(jp->iq,"prompt");
            id = user ? spools(jp->p,at_normalize(user),"@",jp->to->server,jp->p) : NULL;
            if (id)
            {
                xmlnode q;

                jutil_iqresult(jp->x);
        
                q = xmlnode_insert_tag(jp->x,"query");
                xmlnode_put_attrib(q,"xmlns",NS_GATEWAY);
                xmlnode_insert_cdata(xmlnode_insert_tag(q,"prompt"),id,-1);
            }
            else
                jutil_error(jp->x,TERROR_BAD);
            break;
        }
        default:
            jutil_error(jp->x,TERROR_BAD);
            break;
    }
    
    at_deliver(ti,jp->x);
    return 1;
}
Exemple #12
0
int at_iq_last(ati ti, jpacket jp)
{
    xmlnode last;
    xmlnode q;
    char str[10];

    /* XXX I can do last if I track logouts in the XDB... not too hard */
    if(jpacket_subtype(jp) != JPACKET__GET)
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }

    if(jp->to->user != NULL)
    {
        at_session s;
        at_buddy buddy;
        char *res;

        s = at_session_find_by_jid(ti, jp->from);
        if(s == NULL)
        {
            at_bounce(ti, jp, TERROR_REGISTER);
            return 1;
        }
        buddy = xhash_get(s->buddies, jp->to->user);
        if(buddy == NULL)
        {
            at_bounce(ti, jp, TERROR_BAD);
            return 1;
        }
         
        jutil_iqresult(jp->x);
        last = xmlnode_insert_tag(jp->x, "query");
        xmlnode_put_attrib(last,"xmlns",NS_LAST);
        sprintf(str, "%d", buddy->idle_time);
        xmlnode_put_attrib(last, "seconds", str);
        at_deliver(ti,jp->x);

        return 1;
    }

    jutil_iqresult(jp->x);
    last = xmlnode_insert_tag(jp->x, "query");
    xmlnode_put_attrib(last,"xmlns",NS_LAST);
    sprintf(str, "%d", time(NULL) - ti->start_time);
    xmlnode_put_attrib(last,"seconds", str);
    at_deliver(ti,jp->x);

    return 1;
}
Exemple #13
0
void at_bounce(ati ti, jpacket p, terror terr)
{
    char *to, *from;
    xmlnode err, x = p->x;
    char code[4];

    to = xmlnode_get_attrib(x, "to");
    from = xmlnode_get_attrib(x, "from");
    xmlnode_put_attrib(x, "from", to);
    xmlnode_put_attrib(x, "to", from);

    if(p->type == JPACKET_S10N && jpacket_subtype(p) == JPACKET__SUBSCRIBE)
    { /* bounce subscriptions only */
        xmlnode_put_attrib(x, "type", "unsubscribed");
        xmlnode_insert_cdata(xmlnode_insert_tag(x, "status"), terr.msg, -1);

        at_deliver(ti,x);
        return;
    }

    if(jpacket_subtype(p) == JPACKET__ERROR || p->type == JPACKET_PRESENCE || p->type == JPACKET_S10N)
    { /* presence/error packets are just dropped */
        xmlnode_free(x);
        return;
    }

    xmlnode_put_attrib(x,"type", "error");
    err = xmlnode_insert_tag(x, "error");

    snprintf(code, 4, "%d", terr.code);
    xmlnode_put_attrib(err, "code", code);
    if(terr.msg != NULL)
        xmlnode_insert_cdata(err, terr.msg, strlen(terr.msg));

    at_deliver(ti,x);
}
Exemple #14
0
mreturn mod_browse_server(mapi m, void *arg)
{
	xmlnode browse, query, x;

	if (m->packet->type != JPACKET_IQ)
		return M_IGNORE;
	if (jpacket_subtype(m->packet) != JPACKET__GET
	    || !NSCHECK(m->packet->iq, NS_BROWSE)
	    || m->packet->to->resource != NULL)
		return M_PASS;

	/* get data from the config file */
	if ((browse = js_config(m->si, "browse")) == NULL)
		return M_PASS;

	log_debug("handling browse query");

	/* build the result IQ */
	query =
	    xmlnode_insert_tag(jutil_iqresult(m->packet->x), "service");
	xmlnode_put_attrib(query, "xmlns", NS_BROWSE);
	xmlnode_put_attrib(query, "type", "jabber");
	xmlnode_put_attrib(query, "jid", m->packet->to->server);
	xmlnode_put_attrib(query, "name", xmlnode_get_data(js_config(m->si, "vCard/FN")));	/* pull name from the server vCard */

	/* copy in the configured services */
	xmlnode_insert_node(query, xmlnode_get_firstchild(browse));

	/* list the admin stuff */
	if (js_admin_jid(m->si, jid_user(m->packet->from), ADMIN_READ)) {
		x = xmlnode_insert_tag(query, "item");
		xmlnode_put_attrib(x, "jid",
				   spools(xmlnode_pool(x),
					  m->packet->to->server, "/admin",
					  xmlnode_pool(x)));
		xmlnode_put_attrib(x, "name", "Online Users");
		xmlnode_insert_cdata(xmlnode_insert_tag(query, "ns"),
				     NS_ADMIN, -1);
	}

	jpacket_reset(m->packet);
	js_deliver(m->si, m->packet);

	return M_HANDLED;
}
Exemple #15
0
int at_iq_browse(ati ti, jpacket jp)
{
    xmlnode q;

    if(jpacket_subtype(jp) != JPACKET__GET)
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }

    if(jp->to->user != NULL)
    {
        q = xmlnode_insert_tag(jutil_iqresult(jp->x),"item");
        xmlnode_put_attrib(q,"xmlns",NS_BROWSE);

        xmlnode_put_attrib(q,"category","user");
        xmlnode_put_attrib(q,"type","client");
        xmlnode_put_attrib(q,"jid",jid_full(jp->to));
        xmlnode_put_attrib(q,"name", jp->to->user);

        at_deliver(ti,jp->x);
        return 1;
    }
    
    q = xmlnode_insert_tag(jutil_iqresult(jp->x),"item");
    xmlnode_put_attrib(q,"xmlns",NS_BROWSE);

    xmlnode_put_attrib(q,"category","service");
    xmlnode_put_attrib(q,"type","aim");
    xmlnode_put_attrib(q,"jid",jp->to->server);
    xmlnode_put_attrib(q,"name",xmlnode_get_tag_data(ti->vcard,"FN"));

    xmlnode_insert_cdata(xmlnode_insert_tag(q,"ns"),NS_DISCO_INFO,-1);
    xmlnode_insert_cdata(xmlnode_insert_tag(q,"ns"),NS_DISCO_ITEMS,-1);
    xmlnode_insert_cdata(xmlnode_insert_tag(q,"ns"),NS_REGISTER,-1);
    xmlnode_insert_cdata(xmlnode_insert_tag(q,"ns"),NS_GATEWAY,-1);

    at_deliver(ti,jp->x);

    // WHY! DAMNIT! WHY?
    return 1;
}
Exemple #16
0
mreturn mod_agents_handler(mapi m, void *arg)
{
	if (m->packet->type != JPACKET_IQ)
		return M_IGNORE;

	if (jpacket_subtype(m->packet) != JPACKET__GET)
		return M_PASS;
	if (m->s != NULL
	    && (m->packet->to != NULL
		&& j_strcmp(jid_full(m->packet->to),
			    m->packet->from->server) != 0))
		return M_PASS;	/* for session calls, only answer to=NULL or to=server */

	if (NSCHECK(m->packet->iq, NS_AGENT))
		return mod_agents_agent(m);
	if (NSCHECK(m->packet->iq, NS_AGENTS))
		return mod_agents_agents(m);

	return M_PASS;
}
Exemple #17
0
result mt_receive(instance i, dpacket d, void *arg)
{
    jpacket jp;
    mti ti;
    session s;

    switch(d->type)
    {
    case p_NONE:
    case p_NORM:
        jp = jpacket_new(d->x);
        if (jp->from && jp->from->user && jp->type != JPACKET_UNKNOWN &&
            jpacket_subtype(jp) != JPACKET__ERROR)
        {
            mti ti = (mti) arg;
            session s = mt_session_find(ti,jp->from);

            lowercase(jp->from->server);
            lowercase(jp->from->user);


            if (s != NULL)
                mt_session_process(s,jp);
            else
                mt_unknown_process(ti,jp);
        }
        else
        {
            log_warn(NULL,"Invalid packet");
            xmlnode_free(d->x);
        }
        break;

    default:
        return r_ERR;

    }

    return r_DONE;
}
Exemple #18
0
/** Process presence from Jabber */
void it_presence(session s, jpacket jp)
{
    log_debug(ZONE,"Session[%s], handling presence",jid_full(s->id));

    switch (jpacket_subtype(jp))
    {
    case JPACKET__PROBE:
      if (jp->to->user) {
        UIN_t uin;
        contact c;
        uin = it_jid2uin(jp->to);
      
		if (j_strcmp(jp->to->server,s->ti->sms_id)==0) {
		  uin = SMS_CONTACT;
		}

        if (uin == SMS_CONTACT)
          c = it_sms_get(s,jp->to->user);
        else
          c = it_contact_get(s,uin);

        if (c != NULL)
          it_contact_send_presence(c,NULL);
		else {
		  c = it_unknown_contact_add(s, jp->to->user, uin);
		  if (c != NULL)
			it_contact_send_presence(c,NULL);
		}
      }
      break;

    case JPACKET__INVISIBLE:
      {
      icqstatus status;
      char *text;

      if (jp->to->user) /* presence to groupchat here */
        break;

      /* update users presence */
      s->p_db = ppdb_insert(s->p_db,jp->from,jp->x);

      text = xmlnode_get_tag_data(jp->x,"status");
      
      if (text != NULL)
        strncpy(s->status_text,text,MAX_STATUS_TEXT);
      else
        s->status_text[0] = '\0';
      
      status = ICQ_STATUS_INVISIBLE;
      if (status != s->status) {
        s->status = status;
        /* propagate to C++ backend */
        SendStatus(s);
      }
      
      /* echo.... */
      /* only when connected */
      if (!s->connected) {
        xmlnode_free(jp->x);
        return;
      }
      
      xmlnode_put_attrib(jp->x,"from",jid_full(jp->to));
      xmlnode_put_attrib(jp->x,"to",jid_full(jid_user(jp->from)));
      it_deliver(s->ti,jp->x);
      return;
      }

    case JPACKET__AVAILABLE:
      {
        icqstatus status;
        char *text;

        if (jp->to->user) /* presence to groupchat here */
            break;

        log_debug(ZONE,"presence");

        /* update user's presence */
        s->p_db = ppdb_insert(s->p_db,jp->from,jp->x);

        text = xmlnode_get_tag_data(jp->x,"status");

        if (text != NULL) {
          strncpy(s->status_text,text,MAX_STATUS_TEXT);
        }
        else
          s->status_text[0] = '\0';
    
        status = jit_show2status(xmlnode_get_tag_data(jp->x,"show"));
        if (status != s->status) {
          s->status = status;
          /* Always set status regardless of being connected or not */
          /* Client class will set this status */
          /* after connecting */
          SendStatus(s);
        }

        /* echo.... */
        /* only when connected */
        if (!s->connected) {
          xmlnode_free(jp->x);
          return;
        }
    
        xmlnode_put_attrib(jp->x,"from",jid_full(jp->to));
        xmlnode_put_attrib(jp->x,"to",jid_full(jid_user(jp->from)));
        it_deliver(s->ti,jp->x);
        return;
    }

    case JPACKET__UNAVAILABLE:
        if (jp->to->user == NULL)
        { /* kill the session if there are no available resources left */
          s->p_db = ppdb_insert(s->p_db,jp->from,jp->x);
          if (ppdb_primary(s->p_db,s->id) == NULL){
            if (!s->exit_flag)
              EndClient(s); // will call it_session_end
          }
        }

    default:
        break;
    }

    xmlnode_free(jp->x);
}
Exemple #19
0
/** Callback processing incoming Jabber packets. */
result it_receive(instance i, dpacket d, void *arg) {
    iti ti = (iti) arg;
    jpacket jp;
    session s;
    session_ref alt_s;
    unsigned char *user;
    
    log_debug(ti->i->id,"Packet received: %s\n",xmlnode2str(d->x)); 

    switch(d->type) {
    case p_ROUTE: {
      /* ignore */
      return r_PASS;
    }
            
    case p_NONE:
    case p_NORM:
      jp = jpacket_new(d->x);
      break;

    default:
      return r_ERR;
    }

    if (!jp->from ||/* !jp->from->user ||*/ jp->type == JPACKET_UNKNOWN /* || jpacket_subtype(jp) == JPACKET__ERROR */)
    { /* ignore invalid packets */
        xmlnode_free(jp->x);
        return r_DONE;
    }

    /* JID user part should be case insensitive */
    /* convert user part of from JID to lower case */
    if(jp->from->user != NULL) 
	  for(user = jp->from->user; *user != '\0'; user++)
		if(*user < 128)
		  *user = tolower(*user);
	/* Mangle "from" JID, save original attribute for XDB conversion */
	xmlnode_put_attrib(jp->x, "origfrom", xmlnode_get_attrib(jp->x, "from"));
	xmlnode_put_attrib(jp->x, "from", jid_full(jp->from));

    SEM_LOCK(ti->sessions_sem);
    s = (session) wpxhash_get(ti->sessions,jid_full(jid_user(jp->from)));
    alt_s = (session_ref) wpxhash_get(ti->sessions_alt,jp->to->user);
    if (s != NULL) {
      if (s->exit_flag) {
    SEM_UNLOCK(ti->sessions_sem);
    log_alert("exit flag","message to exiting session");
    if (jp->type != JPACKET_PRESENCE){
      jutil_error(jp->x,TERROR_NOTFOUND);
      it_deliver(ti,jp->x);
    }
    else
      xmlnode_free(jp->x);
      } else if ((alt_s != NULL) && (
               (jp->type == JPACKET_MESSAGE)            // all messages
            || ((jp->type == JPACKET_IQ) && (j_strcmp(xmlnode_get_attrib(jp->iq,"xmlns"),NS_VCARD) == -1)) // all IQs except of vCard
            || (jp->type == JPACKET_PRESENCE) )) {      // all presences _targeted_to_specific_user_
        // rewriting "to" and "from" and putting packet back on the wire
        xmlnode_put_attrib(jp->x, "from", jid_full(it_uin2jid(jp->p,s->uin,jp->to->server)));
        xmlnode_put_attrib(jp->x, "to", jid_full(alt_s->s->orgid));
        SEM_UNLOCK(ti->sessions_sem);
        it_deliver(ti,jp->x);
      } else {
        jp->aux1 = (void *) s;
        mtq_send(s->q,jp->p,it_session_jpacket,(void *) jp);
        SEM_UNLOCK(ti->sessions_sem);
      }
    }
    else {
	  SEM_UNLOCK(ti->sessions_sem);

      if(jpacket_subtype(jp)!=JPACKET__ERROR)
    it_unknown(ti,jp);
      else
    xmlnode_free(jp->x);
    }
    return r_DONE;
}
Exemple #20
0
int at_iq_disco_info(ati ti, jpacket jp)
{
    xmlnode q, info;

    if(jpacket_subtype(jp) != JPACKET__GET)
    {
        at_bounce(ti, jp, TERROR_BAD);
        return 1;
    }

    if(xmlnode_get_attrib(xmlnode_get_tag(jp->x, "query"),"node") != NULL)
    {
        at_bounce(ti, jp, TERROR_NOTALLOWED);
        return 1;
    }

    if(jp->to->user != NULL)
    {
        q = xmlnode_insert_tag(jutil_iqresult(jp->x),"query");
        xmlnode_put_attrib(q,"xmlns",NS_DISCO_INFO);

	info = xmlnode_insert_tag(q, "identity");
	xmlnode_put_attrib(info, "category", "client");
	xmlnode_put_attrib(info, "type", "pc");
	xmlnode_put_attrib(info, "name", jp->to->user);

	info = xmlnode_insert_tag(q, "feature");
	xmlnode_put_attrib(info, "var", NS_VCARD);

	info = xmlnode_insert_tag(q, "feature");
	xmlnode_put_attrib(info, "var", NS_LAST);

	info = xmlnode_insert_tag(q, "feature");
	xmlnode_put_attrib(info, "var", NS_TIME);

	info = xmlnode_insert_tag(q, "feature");
	xmlnode_put_attrib(info, "var", NS_VERSION);
	
        at_deliver(ti,jp->x);
        return 1;
    }
 
    q = xmlnode_insert_tag(jutil_iqresult(jp->x),"query");
    xmlnode_put_attrib(q,"xmlns",NS_DISCO_INFO);

    info = xmlnode_insert_tag(q, "identity");
    xmlnode_put_attrib(info, "category", "gateway");
    xmlnode_put_attrib(info, "type", "aim");
    xmlnode_put_attrib(info,"name",xmlnode_get_tag_data(ti->vcard,"FN"));

    info = xmlnode_insert_tag(q, "feature");
    xmlnode_put_attrib(info, "var", NS_VCARD);

    info = xmlnode_insert_tag(q, "feature");
    xmlnode_put_attrib(info, "var", NS_LAST);

    info = xmlnode_insert_tag(q, "feature");
    xmlnode_put_attrib(info, "var", NS_TIME);

    info = xmlnode_insert_tag(q, "feature");
    xmlnode_put_attrib(info, "var", NS_VERSION);

    info = xmlnode_insert_tag(q, "feature");
    xmlnode_put_attrib(info, "var", NS_GATEWAY);

    info = xmlnode_insert_tag(q, "feature");
    xmlnode_put_attrib(info, "var", NS_REGISTER);
    
    at_deliver(ti,jp->x);
    return 1;
}
Exemple #21
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;
}
Exemple #22
0
mreturn mod_browse_set(mapi m, void *arg)
{
	xmlnode browse, cur;
	jid id, to;

	if (m->packet->type != JPACKET_IQ)
		return M_IGNORE;
	if (!NSCHECK(m->packet->iq, NS_BROWSE)
	    || jpacket_subtype(m->packet) != JPACKET__SET)
		return M_PASS;
	if (m->packet->to != NULL)
		return M_PASS;	/* if its to someone other than ourselves */

	log_debug("handling set request %s", xmlnode2str(m->packet->iq));

	/* no to implies to ourselves */
	if (m->packet->to != NULL)
		to = m->packet->to;
	else
		to = m->user->id;

	/* if we set to a resource, we need to make sure that resource's browse is in the users browse */
	if (to->resource != NULL) {
		browse = mod_browse_get(m, to);	/* get our browse info */
		xmlnode_hide_attrib(browse, "xmlns");	/* don't need a ns as a child */
		for (cur = xmlnode_get_firstchild(browse); cur != NULL;
		     cur = xmlnode_get_nextsibling(cur))
			xmlnode_hide(cur);	/* erase all children */
		xdb_act(m->si->xc, m->user->id, NS_BROWSE, "insert", spools(m->packet->p, "?jid=", jid_full(to), m->packet->p), browse);	/* insert and match replace */
		xmlnode_free(browse);
	}

	/* get the id of the new browse item */
	if ((cur = xmlnode_get_firstchild(m->packet->iq)) == NULL
	    || (id =
		jid_new(m->packet->p,
			xmlnode_get_attrib(cur, "jid"))) == NULL) {
		js_bounce(m->si, m->packet->x, TERROR_NOTACCEPTABLE);
		return M_HANDLED;
	}

	/* insert the new item into the resource it was sent to */
	xmlnode_hide_attrib(cur, "xmlns");	/* just in case, to make sure it inserts */
	if (xdb_act
	    (m->si->xc, to, NS_BROWSE, "insert",
	     spools(m->packet->p, "?jid=", jid_full(id), m->packet->p),
	     cur)) {
		js_bounce(m->si, m->packet->x, TERROR_UNAVAIL);
		return M_HANDLED;
	}

	/* if the new data we're inserting is to one of our resources, update that resource's browse */
	if (jid_cmpx(m->user->id, id, JID_USER | JID_SERVER) == 0
	    && id->resource != NULL) {
		/* get the old */
		browse = mod_browse_get(m, id);
		/* transform the new one into the old one */
		xmlnode_put_attrib(cur, "xmlns", NS_BROWSE);
		xmlnode_insert_node(cur, xmlnode_get_firstchild(browse));
		xdb_set(m->si->xc, id, NS_BROWSE, cur);	/* replace the resource's browse w/ this one */
		xmlnode_free(browse);
	}

	/* send response to the user */
	jutil_iqresult(m->packet->x);
	jpacket_reset(m->packet);
	js_session_to(m->s, m->packet);

	return M_HANDLED;
}
Exemple #23
0
/** Got a subscription request from Jabber */
void it_s10n(session s, jpacket jp)
{
  UIN_t uin;
  contact c;

  if (jp->to->user == NULL) {
    /* ignore s10n to the transport */
    xmlnode_free(jp->x);
    return;
  }

  uin = it_jid2uin(jp->to);
  if (uin == 0 || uin == s->uin) {
    jutil_error(jp->x,TERROR_BAD);
    it_deliver(s->ti,jp->x);
    return;
  }

  if (s->connected == 0) {
    queue_elem queue;

    /* add to circle queue */
    queue = pmalloco(jp->p,sizeof(_queue_elem));
    queue->elem = (void *)jp;
    /* next = NULL */

    QUEUE_PUT(s->queue,s->queue_last,queue);
    return;
  }

  /* we're connected, go on */
  log_debug(ZONE,"presence packet uin = %d",uin);
  
  /* check for SMS_CONTACT */
  if (j_strcmp(jp->to->server,s->ti->sms_id)==0) {
	uin = SMS_CONTACT;
  }
  
  if (uin == SMS_CONTACT)
    c = it_sms_get(s,jp->to->user);
  else
    c = it_contact_get(s,uin);
  
  switch (jpacket_subtype(jp))
      {
      case JPACKET__SUBSCRIBE:
        if (c == NULL) {
          /* if sms contact */
          if (uin == SMS_CONTACT) {
            /* if not our sms id */
            if (j_strcmp(jp->to->server,s->ti->sms_id)) {
              log_debug(ZONE,"not our sms %s",jp->to->server);
              xmlnode_free(jp->x);
              break;
            }
            c = it_sms_add(s,jp->to->user);
            log_debug(ZONE,"sms add");
          }
          else     
            c = it_contact_add(s,uin);
        }

        log_debug(ZONE,"subscribe");

		it_contact_subscribe(c,NULL);

        xmlnode_free(jp->x);
        break;
    
      case JPACKET__SUBSCRIBED:
        /* after asking */
        if (c) {
          it_contact_subscribed(c,jp);      
          log_debug(ZONE,"subscribed");
        }
        
        xmlnode_free(jp->x);
        break;
        
      case JPACKET__UNSUBSCRIBE:    
        if (c) {
          /* will remove user from icq contacts 
             inform main jabber roster unsubscribed */
          it_contact_unsubscribe(c);
          log_debug(ZONE,"unsubscribe");      
        }
        
        xmlnode_free(jp->x);
        break; 
        
      case JPACKET__UNSUBSCRIBED:
        /* when icq ask for subscribe we have that contacts in our roster 
           remove contact if exist */
        if (c) {      
          it_contact_unsubscribed(c,jp);
          log_debug(ZONE,"unsubscribed");
        }
        
        xmlnode_free(jp->x);
        break;
        
      default:
        xmlnode_free(jp->x);
        break;
      }
}
Exemple #24
0
mreturn mod_stats_server(mapi m, void *arg)
{
	xmlnode cur;
	int i;

	if (m->packet->type != JPACKET_IQ)
		return M_IGNORE;
	if (jpacket_subtype(m->packet) != JPACKET__GET)
		return M_PASS;
	if (!NSCHECK(m->packet->iq, NS_STATS))
		return M_PASS;
	if (m->packet->to->resource)
		return M_PASS;

	/* get data from the config file */
	i = 0;
	if (xmlnode_get_tag(js_config(m->si, "stats"), "allow_all") !=
	    NULL)
		i = 1;

	log_debug("handling stats get %s", jid_full(m->packet->from));

	/* check if admin */
	if ((i == 0) &&
	    (!js_admin_jid(m->si, jid_user(m->packet->from), ADMIN_READ)))
	{
		jutil_error(m->packet->x, TERROR_AUTH);
		jpacket_reset(m->packet);
		js_deliver(m->si, m->packet);
		return M_HANDLED;
	}

	/* check if any stat have given iq query */
	cur = xmlnode_get_firstchild(m->packet->iq);
	for (; cur != NULL; cur = xmlnode_get_nextsibling(cur)) {
		if (xmlnode_get_type(cur) != NTYPE_TAG)
			continue;
		break;
	}
	if (cur != NULL)
		cur = xmlnode_get_firstchild(m->packet->iq);

	jutil_tofrom(m->packet->x);
	xmlnode_put_attrib(m->packet->x, "type", "result");

	/* return available stats */
	if (!cur) {
		for (i = 0; available_stats[i]; i++) {
			xmlnode_put_attrib(xmlnode_insert_tag
					   (m->packet->iq, "stat"), "name",
					   available_stats[i]);
		}
		jpacket_reset(m->packet);
		js_deliver(m->si, m->packet);
		return M_HANDLED;
	}

	/* return server stats */
	/* cur is already first stat */
	for (; cur != NULL; cur = xmlnode_get_nextsibling(cur)) {
		char *name;
		char buf[31];
		int found;

		if (xmlnode_get_type(cur) != NTYPE_TAG)
			continue;
		if (j_strcmp(xmlnode_get_name(cur), "stat") != 0)
			continue;

		name = xmlnode_get_attrib(cur, "name");

		if (!name)
			continue;

		log_debug("get stats for %s", name);

		found = 0;
		for (i = 0; available_stats[i]; i++) {

			if (j_strcmp(available_stats[i], name) != 0)
				continue;

			log_debug("stats for %s", name);
			/* give stats */

			found = 1;

			/* time/uptime */
			if (j_strcmp(name, "time/uptime") == 0) {
				snprintf(buf, 30, "%d",
					 time(NULL) -
					 m->si->stats->started);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units",
						   "seconds");
			}

			/* users/online */
			if (j_strcmp(name, "users/online") == 0) {
				snprintf(buf, 30, "%d",
					 m->si->stats->sessioncount);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units", "users");
			}

			if (j_strcmp(name, "users/max_online_today") == 0) {
				snprintf(buf, 30, "%d",
					 m->si->stats->session_max_today);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units", "users");
			}

			if (j_strcmp(name, "users/max_online_yesterday") ==
			    0) {
				snprintf(buf, 30, "%d",
					 m->si->stats->
					 session_max_yesterday);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units", "users");
			}

			if (j_strcmp(name, "users/registered_today") == 0) {
				snprintf(buf, 30, "%d",
					 m->si->stats->
					 users_registered_today);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units", "users");
			}

			if (j_strcmp(name, "users/registered_from_start")
			    == 0) {
				snprintf(buf, 30, "%d",
					 m->si->stats->
					 users_registered_from_start);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units", "users");
			}

			if (j_strcmp(name, "bandwidth/packets-in") == 0) {
				snprintf(buf, 30, "%lu",
					 m->si->stats->packets_in);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units",
						   "packets");
			}

			if (j_strcmp(name, "bandwidth/packets-out") == 0) {
				snprintf(buf, 30, "%lu",
					 m->si->stats->packets_out);
				xmlnode_put_attrib(cur, "value", buf);
				xmlnode_put_attrib(cur, "units",
						   "packets");
			}
#ifndef WIN32
			if (j_strcmp(name, "memory/usage") == 0) {
				long mem = get_memory_usage();
				if (mem > 0) {
					snprintf(buf, 30, "%lu", mem);
					xmlnode_put_attrib(cur, "value",
							   buf);
					xmlnode_put_attrib(cur, "units",
							   "bytes");
				} else
					found = 0;
			}
#endif
			break;
		}

		if (found <= 0) {
			xmlnode err;
			err = xmlnode_insert_tag(cur, "error");
			xmlnode_put_attrib(err, "code", "404");
			xmlnode_insert_cdata(err, "Not Found", -1);
		}
	}

	jpacket_reset(m->packet);
	js_deliver(m->si, m->packet);
	return M_HANDLED;
}