Пример #1
0
/* bounces packet for unknown users with the appropriate error */
void mt_unknown_bounce(void *arg)
{
    jpacket jp = (jpacket) arg;
    mti ti = (mti) jp->aux1;
    xmlnode reg;

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

    if ((reg = xdb_get(ti->xc,mt_xdb_id(jp->p,jp->from,jp->to->server),NS_REGISTER)) != NULL)
    {
        xmlnode p = xmlnode_new_tag("presence");
        xmlnode_put_attrib(p,"to",jid_full(jp->from));
        xmlnode_put_attrib(p,"from",jp->to->server);
        xmlnode_put_attrib(p,"type","probe");

        mt_deliver(ti,p);

        jutil_error(jp->x,TERROR_NOTFOUND);
        xmlnode_free(reg);
    }
    else
        jutil_error(jp->x,TERROR_REGISTER);

    mt_deliver(ti,jp->x);
}
Пример #2
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;
}
Пример #3
0
void con_room_forward_decline(cnr room, jpacket jp, xmlnode decline)
{
  cnu user;
  jid user_jid;
  if (room == NULL || decline == NULL || jp == NULL)
  {
    log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE);
    xmlnode_free(jp->x);
    return;
  }
  user_jid=jid_new(decline->p,xmlnode_get_attrib(decline,"to"));
  if ((room->invitation == 1 && !is_member(room, jp->from) && !is_owner(room, jp->from)) || user_jid == NULL)
  {
    log_warn(NAME, "[%s] Aborting - User is not allowed to send a decline", FZONE);
    jutil_error(jp->x, TERROR_MUC_OUTSIDE);
    deliver(dpacket_new(jp->x), NULL);
    return;
  }
  if (user_jid->resource == NULL) {
    log_warn(NAME, "[%s] Aborting - cannot send back decline, bare jid found", FZONE);
    return;
  }
  if (room->visible == 1)
  {
    user = g_hash_table_lookup(room->remote, jid_full(jid_fix(user_jid)));
  }
  else
  {
    user = g_hash_table_lookup(room->local, user_jid->resource);
  }

  if (user == NULL){
    log_warn(NAME, "[%s] Aborting - Decline recipient is not in the room", FZONE);
    jutil_error(jp->x, TERROR_MUC_OUTSIDE);
    deliver(dpacket_new(jp->x), NULL);
    return;
  }
  log_debug(NAME, "[%s] Sending invitation decline", FZONE);
  xmlnode_put_attrib(decline, "from", jid_full(jp->from));
  xmlnode_hide_attrib(decline, "to");
  xmlnode_put_attrib(jp->x, "to", jid_full(user->realid));
  xmlnode_put_attrib(jp->x, "from", jid_full(room->id));

  log_debug(NAME, "[%s] >>>%s<<<", FZONE, xmlnode2str(jp->x));

  deliver(dpacket_new(jp->x), NULL);
  return;
}
Пример #4
0
/* child that handles packets from the user */
void _js_session_from(void *arg)
{
	jpacket p = (jpacket) arg;
	session s = (session) (p->aux1);

	/* if this session is dead */
	if (s->exit_flag) {
		/* send the packet into oblivion */
		xmlnode_free(p->x);
		return;
	}

	/* at least we must have a valid packet */
	if (p->type == JPACKET_UNKNOWN) {
		/* send an error back */
		jutil_error(p->x, TERROR_BAD);
		jpacket_reset(p);
		js_session_to(s, p);
		return;
	}

	/* debug message */
	log_debug("THREAD:SESSION:FROM received a packet!");

	/* increment packet out count */
	s->si->stats->packets_out++;
	s->c_out++;

	/* make sure we have our from set correctly for outgoing packets */
	if (jid_cmpx(p->from, s->id, JID_USER | JID_SERVER) != 0) {
		/* nope, fix it */
		xmlnode_put_attrib(p->x, "from", jid_full(s->id));
		p->from = jid_new(p->p, jid_full(s->id));
	}

	/* if you use to="yourself@yourhost" it's the same as not having a to, the modules use the NULL as a self-flag */
	if (jid_cmp(p->to, s->uid) == 0) {
		/* xmlnode_hide_attrib(p->x,"to"); */
		p->to = NULL;
	}

	/* let the modules have their heyday */
	if (js_mapi_call(NULL, es_OUT, p, s->u, s))
		return;

	/* no module handled it, so restore the to attrib to us */
	if (p->to == NULL) {
		xmlnode_put_attrib(p->x, "to", jid_full(s->uid));
		p->to = jid_new(p->p, jid_full(s->uid));
	}

	js_post_out_main(s, p);

	/* pass these to the general delivery function */
	//    js_deliver(s->si, p);
}
Пример #5
0
void dnsrv_resend(xmlnode pkt, char *ip, char *to)
{
    if(ip != NULL)
    {
         pkt = xmlnode_wrap(pkt,"route");
         xmlnode_put_attrib(pkt, "to", to);
         xmlnode_put_attrib(pkt, "ip", ip);
    }else{
         jutil_error(pkt, (terror){502, "Unable to resolve hostname."});
         xmlnode_put_attrib(pkt, "iperror", "");
    }
    deliver(dpacket_new(pkt),NULL);
}
Пример #6
0
void deliver_fail(dpacket p, char *err) {
  terror t;

  /* normal packet bounce */
  if(j_strcmp(xmlnode_get_attrib(p->x,"type"),"error") == 0) { /* can't bounce an error */
    log_warn(p->host,"dropping a packet to %s from %s: %s",xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"from"),err);
    pool_free(p->p);
  } else {
    log_warn(p->host,"bouncing a packet to %s from %s: %s",xmlnode_get_attrib(p->x,"to"),xmlnode_get_attrib(p->x,"from"),err);

    /* turn into an error */
    if(err == NULL) {
      jutil_error(p->x,TERROR_EXTERNAL);
    } else {
      t.code = 502;
      strcpy(t.msg,err);
      strcpy(t.condition, "service-unavailable");
      strcpy(t.type, "wait");
      jutil_error(p->x,t);
    }
    deliver(dpacket_new(p->x),NULL);
  }
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
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;
      }
}