Beispiel #1
0
/* NOTE: any jpacket sent to deliver *MUST* match jpacket_new(p->x),
 * jpacket is simply a convenience wrapper
 */
void js_deliver(jsmi si, jpacket p)
{

	if (p->to == NULL) {
		log_warn(NULL, "jsm: Invalid Recipient, returning data %s",
			 xmlnode2str(p->x));
		js_bounce(si, p->x, TERROR_BAD);
		return;
	}

	if (p->from == NULL) {
		log_warn(NULL, "jsm: Invalid Sender, discarding data %s",
			 xmlnode2str(p->x));
		xmlnode_free(p->x);
		return;
	}

	log_debug("deliver(to[%s],from[%s],type[%d],packet[%s])",
		  jid_full(p->to), jid_full(p->from), p->type,
		  xmlnode2str(p->x));

	/* is it our */
	if (j_strcmp(si->host, p->to->server) == 0) {
		js_deliver_local(si, p);
		return;
	}

	deliver(dpacket_new(p->x), si->i);
}
Beispiel #2
0
/* handle a packet from jabberd */
result at_phandler(instance i,dpacket p,void *arg)
{
    int ret;
    ati ti;
    at_mtq_data amd;

    if(i == NULL || p == NULL) 
        return r_ERR;

    ti = (ati)arg;

    switch(p->type)
    {
    case p_NONE:
    case p_NORM:
        log_debug(ZONE, "[AT] we got a packet from jabberd: %s", xmlnode2str(p->x));
        amd = pmalloco(p->p, sizeof(_at_mtq_data));
        amd->jp = jpacket_new(p->x);
        amd->p = p->p;
        amd->ti = ti;

        mtq_send(NULL, p->p, at_parse_packet, (void *)amd);
        return r_DONE;
    default:
        log_debug(ZONE, "[AT] ignoring packet from jabberd: %s", xmlnode2str(p->x));
        return r_PASS;
    }
}
Beispiel #3
0
void deliver(dpacket d, void *a) {
  extern jcr_instance jcr;

  if (d == NULL)
    return;

  while (jcr->stream_state != _STREAM_CONNECTED) {
    log_debug(JDBG, "Stream not ready ... waiting to queue pkts");
    sleep(1);
  }

  log_debug(JDBG, "queued %d bytes : >>> %s <<<", strlen(xmlnode2str(d->x)), xmlnode2str(d->x));
  g_async_queue_push(jcr->dqueue, d);
}
Beispiel #4
0
void dnsrv_process_xstream_io(int type, xmlnode x, void* arg)
{
     dns_io di            = (dns_io)arg;
     char* hostname       = NULL;
     char* ipaddr         = NULL;
     char* resendhost     = NULL;
     dns_packet_list head = NULL;
     dns_packet_list heado = NULL;

     /* Node Format: <host ip="201.83.28.2">foo.org</host> */
     if (type == XSTREAM_NODE)
     {    
          log_debug(ZONE,"incoming resolution: %s",xmlnode2str(x));
          hostname = xmlnode_get_data(x);

          /* whatever the response was, let's cache it */
          xmlnode_free((xmlnode)xhash_get(di->cache_table,hostname)); /* free any old cache, shouldn't ever be any */
          xmlnode_put_vattrib(x,"t",(void*)time(NULL));
          xhash_put(di->cache_table,hostname,(void*)x);

          /* Get the hostname and look it up in the hashtable */
          head = xhash_get(di->packet_table, hostname);
          /* Process the packet list */
          if (head != NULL)
          {
               ipaddr = xmlnode_get_attrib(x, "ip");
               resendhost = xmlnode_get_attrib(x, "to");

               /* Remove the list from the hashtable */
               xhash_zap(di->packet_table, hostname);
               
               /* Walk the list and insert IPs */
               while(head != NULL)
               {
                    heado = head;
                    /* Move to next.. */
                    head = head->next;
                    /* Deliver the packet */
                    dnsrv_resend(heado->packet->x, ipaddr, resendhost);
               }
          }
          /* Host name was not found, something is _TERRIBLY_ wrong! */
          else
               log_debug(ZONE, "Resolved unknown host/ip request: %s\n", xmlnode2str(x));

          return; /* we cached x above, so we don't free it below :) */
     }
     xmlnode_free(x);
} 
Beispiel #5
0
/* do not create t.m.p file. We don't need this file
   because xdb_file moule is thread safe and there is no way
   to acces the file in many threads 
   
   returns 
    1 write oki
    0 if maxsize reached, not written
	-1 error */
int xdb_file2file(char * file, xmlnode node, int maxsize)
{
  char *doc;
  int fd, i, docsize;
  
  if(file == NULL || node == NULL)
	return -1;
  
  doc = xmlnode2str(node);
  docsize = strlen(doc);

  if (maxsize && (docsize >= maxsize))
	return 0;

  fd = open(file, O_CREAT | O_WRONLY | O_TRUNC, 0600);
  if(fd < 0)
	return -1;

  i = write(fd,doc,strlen(doc));
  if(i < 0) {
	close(fd);
	return -1;
  }

  close(fd);

  return 1;
}
Beispiel #6
0
/* always deliver threads */
static void js_outgoing_packet(jsmi si, jpacket jp, dpacket p)
{
	session s = NULL;
	udata u;

	/* attempt to locate the session by matching the special resource */
	u = js_user(si, p->id, 0);
	if (u == NULL) {
		log_notice(p->host,
			   "Bouncing packet intended for nonexistant user: %s",
			   xmlnode2str(p->x));
		deliver_fail(dpacket_new(p->x), "Invalid User");
		return;
	}

	SEM_LOCK(u->sem);
	for (s = u->sessions; s != NULL; s = s->next)
		if (j_strcmp(p->id->resource, s->route->resource) == 0)
			break;
	SEM_UNLOCK(u->sem);

	THREAD_DEC(u->ref);

	if (s != NULL) {	/* just pass to the session normally */
		js_session_from(s, jp);
		return;
	}

	log_notice(p->host, "Bouncing %s packet intended for session %s",
		   xmlnode_get_name(jp->x), jid_full(p->id));
	deliver_fail(dpacket_new(p->x), "Invalid Session");
}
Beispiel #7
0
/* Coprocess functionality */
void dnsrv_child_process_xstream_io(int type, xmlnode x, void* args)
{
     dns_io di = (dns_io)args;
     char*  hostname;
     char*  str = NULL;
     dns_resend_list iternode = NULL;

     if (type == XSTREAM_NODE)
     {
          /* Get the hostname out... */
          hostname = xmlnode_get_data(x);
          log_debug(ZONE, "dnsrv: Recv'd lookup request for %s", hostname);
          if (hostname != NULL)
          {
               /* For each entry in the svclist, try and resolve using
                  the specified service and resend it to the specified host */
               iternode = di->svclist;
               while (iternode != NULL)
               {
                    str = srv_lookup(x->p, iternode->service, hostname);
                    if (str != NULL)
                    {
                         log_debug(ZONE, "Resolved %s(%s): %s\tresend to:%s", hostname, iternode->service, str, iternode->host);
                         xmlnode_put_attrib(x, "ip", str);
                         xmlnode_put_attrib(x, "to", iternode->host);
                         break;
                    }
                    iternode = iternode->next;
               }
               str = xmlnode2str(x);
               write(di->out, str, strlen(str));
          }
     }
     xmlnode_free(x);
}
Beispiel #8
0
int xmlnode2file(char *file, xmlnode node)
{
    char *doc, *ftmp;
    int fd, i;

    if(file == NULL || node == NULL)
        return -1;

    ftmp = spools(xmlnode_pool(node),file,".t.m.p",xmlnode_pool(node));
    fd = open(ftmp, O_CREAT | O_WRONLY | O_TRUNC, 0600);
    if(fd < 0)
        return -1;

    doc = xmlnode2str(node);
    i = write(fd,doc,strlen(doc));
    if(i < 0)
        return -1;

    close(fd);

    if(rename(ftmp,file) < 0)
    {
        unlink(ftmp);
        return -1;
    }
    return 1;
}
Beispiel #9
0
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);
}
Beispiel #10
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;
}
Beispiel #11
0
result xdb_results(instance id, dpacket p, void *arg)
{
	xdbcache xc = (xdbcache) arg;
	xdbrequest_p cur, last;
	unsigned int idnum;
	char *idstr;

	if (p->type != p_NORM || *(xmlnode_get_name(p->x)) != 'x')
		return r_PASS;	/* yes, we are matching ANY <x*> element */

	log_debug("xdb_results checking xdb packet %s", xmlnode2str(p->x));

	if ((idstr = xmlnode_get_attrib(p->x, "id")) == NULL)
		return r_ERR;

	idnum = atoi(idstr);

	SEM_LOCK(xc->sem);

	for (last = NULL, cur = xc->first;
	     (cur) && (cur->id != idnum); last = cur, cur = cur->next);

	if (!cur) {
		pool_free(p->p);
		SEM_UNLOCK(xc->sem);
		return r_DONE;
	}

	/* associte only a non-error packet w/ waiting cache */
	if (j_strcmp(xmlnode_get_attrib(p->x, "type"), "error") == 0) {
		cur->data = NULL;
		pool_free(p->p);
	} else
		cur->data = p->x;

	if (!last)
		xc->first = cur->next;
	else
		last->next = cur->next;

	cur->external = 0;
	SEM_UNLOCK(xc->sem);

	cur->preblock = 1;
	return r_DONE;
}
Beispiel #12
0
result dnsrv_deliver(instance i, dpacket p, void* args)
{
     dns_io di = (dns_io)args;
     xmlnode c;
     int timeout = di->cache_timeout;
     char *ip;
     jid to;

     /* if we get a route packet, it has to be to *us* and have the child as the real packet */
     if(p->type == p_ROUTE)
     {
        if(j_strcmp(p->host,i->id) != 0 || (to = jid_new(p->p,xmlnode_get_attrib(xmlnode_get_firstchild(p->x),"to"))) == NULL)
            return r_ERR;
        p->x=xmlnode_get_firstchild(p->x);
        p->id = to;
        p->host = to->server;
     }

     /* Ensure this packet doesn't already have an IP */
     if(xmlnode_get_attrib(p->x, "ip") || xmlnode_get_attrib(p->x, "iperror"))
     {
        log_notice(p->host, "dropping looping dns lookup request: %s", xmlnode2str(p->x));
        xmlnode_free(p->x);
        return r_DONE;
     }

     /* try the cache first */
     if((c = xhash_get(di->cache_table, p->host)) != NULL)
     {
         /* if there's no IP, cached failed lookup, time those out 10 times faster! (weird, I know, *shrug*) */
         if((ip = xmlnode_get_attrib(c,"ip")) == NULL)
            timeout = timeout / 10;
         if((time(NULL) - (int)xmlnode_get_vattrib(c,"t")) > timeout)
         { /* timed out of the cache, lookup again */
             xmlnode_free(c);
             xhash_zap(di->cache_table,p->host);
         }else{
             /* yay, send back right from the cache */
             dnsrv_resend(p->x, ip, xmlnode_get_attrib(c,"to"));
             return r_DONE;
         }
     }

    dnsrv_lookup(di, p);
    return r_DONE;
}
Beispiel #13
0
result xdb_results(instance id, dpacket p, void *arg)
{
    xdbcache xc = (xdbcache)arg;
    xdbcache curx;
    int idnum;
    char *idstr;

    if(p->type != p_NORM || *(xmlnode_get_name(p->x)) != 'x') return r_PASS; /* yes, we are matching ANY <x*> element */

    log_debug(ZONE,"xdb_results checking xdb packet %s",xmlnode2str(p->x));

    if((idstr = xmlnode_get_attrib(p->x,"id")) == NULL) return r_ERR;

    idnum = atoi(idstr);

    pthread_mutex_lock(&(xc->sem));
    for(curx = xc->next; curx->id != idnum && curx != xc; curx = curx->next); /* spin till we are where we started or find our id# */

    /* we got an id we didn't have cached, could be a dup, ignore and move on */
    if(curx->id != idnum)
    {
	  pool_free(p->p);
	  pthread_mutex_unlock(&(xc->sem));
	  return r_DONE;
    }

    /* associte only a non-error packet w/ waiting cache */
    if(j_strcmp(xmlnode_get_attrib(p->x,"type"),"error") == 0) {
	  curx->data = NULL;
	  pool_free(p->p); // very bad memory leak
	} 
	else
	  curx->data = p->x;

    /* remove from ring */
    curx->prev->next = curx->next;
    curx->next->prev = curx->prev;
    pthread_mutex_unlock(&(xc->sem));


    /* free the thread! */
    curx->preblock = 1;

    return r_DONE; /* we processed it */
}
Beispiel #14
0
/* Hostname lookup requested */
void dnsrv_lookup(dns_io d, dpacket p)
{
    dns_packet_list l, lnew;
    xmlnode req;
    char *reqs;

    /* make sure we have a child! */
    if(d->out <= 0)
    {
        deliver_fail(p, "DNS Resolver Error");
        return;
    }

    /* Attempt to lookup this hostname in the packet table */
    l = (dns_packet_list)xhash_get(d->packet_table, p->host);

    /* IF: hashtable has the hostname, a lookup is already pending,
       so push the packet on the top of the list (most recent at the top) */
    if (l != NULL)
    {
         log_debug(ZONE, "dnsrv: Adding lookup request for %s to pending queue.", p->host);
         lnew = pmalloco(p->p, sizeof(_dns_packet_list));
         lnew->packet = p;
         lnew->stamp = time(NULL);
         lnew->next = l;
         xhash_put(d->packet_table, p->host, lnew);
         return;
    }

    /* insert the packet into the packet_table using the hostname
       as the key and send a request to the coprocess */
    log_debug(ZONE, "dnsrv: Creating lookup request queue for %s", p->host);
    l = pmalloco(p->p, sizeof(_dns_packet_list));
    l->packet = p;
    l->stamp  = time(NULL);
    xhash_put(d->packet_table, p->host, l);
    req = xmlnode_new_tag_pool(p->p,"host");
    xmlnode_insert_cdata(req,p->host,-1);

    reqs = xmlnode2str(req);
    log_debug(ZONE, "dnsrv: Transmitting lookup request: %s", reqs);
    pth_write(d->out, reqs, strlen(reqs));
}
Beispiel #15
0
void jabber_node(Stream *s,xmlnode x){
char *name;

	packets_in++;
	name=xmlnode_get_name(x);
	if (strcmp(name,"stream:stream")==0)
		jabber_stream_start(s,x);
	else if (strcmp(name,"handshake")==0)
		jabber_handshake(s,x);
	else if (strcmp(name,"stream:error")==0)
		jabber_stream_error(s,x);
	else if (strcmp(name,"iq")==0)
		jabber_iq(s,x);
	else if (strcmp(name,"presence")==0)
		jabber_presence(s,x);
	else if (strcmp(name,"message")==0)
		jabber_message(s,x);
	else g_warning(N_("Unsupported tag: %s"),xmlnode2str(x));
	xmlnode_free(x);
}
Beispiel #16
0
void session_print(Session *s,int indent){
char *space,*space1;
GList *it;
Resource *r,*cr;
char *njid;

	space=g_strnfill(indent*2,' ');
	space1=g_strnfill((indent+1)*2,' ');
	njid=jid_normalized(s->jid,0);
	g_message(L_("%sSession: %p"),space,s);
	g_message("%sJID: %s",space,s->jid);
	g_message(L_("%sUser:"******"%sResources:"),space);
	cr=session_get_cur_resource(s);
	for(it=g_list_first(s->resources);it;it=g_list_next(it)){
		r=(Resource *)it->data;
		g_message(L_("%sResource: %p%s"),space1,r,(r==cr)?N_(" (current)"):"");
		if (njid && r->name) g_message("%sJID: %s/%s",space1,njid,r->name);
		else g_message("%sJID: %s",space1,s->jid);
		g_message(L_("%sPriority: %i"),space1,r->priority);
		g_message(L_("%sAvailable: %i"),space1,r->available);
		if (r->show)
			g_message(L_("%sShow: %s"),space1,r->show);
		if (r->status)
			g_message(L_("%sStatus: %s"),space1,r->status);
	}
	g_message(L_("%sGG session: %p"),space,s->ggs);
	g_message(L_("%sGSource: %p"),space,s->g_source);
	g_message(L_("%sStream: %p"),space,s->s);
	g_message(L_("%sConnected: %i"),space,s->connected);
	g_message(L_("%sRequest id: %s"),space,s->req_id?s->req_id:"(null)");
	g_message(L_("%sRequest query: %s"),space,s->query?xmlnode2str(s->query):"(null)");
	g_message(L_("%sWaiting for ping: %i"),space,(int)s->waiting_for_pong);
	g_free(njid);
	g_free(space1);
	g_free(space);
}
Beispiel #17
0
/* any thread */
result js_packet(instance i, dpacket p, void *arg)
{
	jsmi si = (jsmi) arg;
	jpacket jp = NULL;
	session s = NULL;
	packet_thread_p pt;
	udata u;

	char *type, *authto;

	log_debug("incoming packet %s", xmlnode2str(p->x));

	/* if this is a routed packet */
	if (p->type == p_ROUTE) {
		type = xmlnode_get_attrib(p->x, "type");

		/* new session requests */
		if (j_strcmp(type, "session") == 0) {
			js_session_new_mtq(si, p);
			return r_DONE;
		}

		/* get the internal jpacket */
		if (xmlnode_get_firstchild(p->x) != NULL)	/* XXX old libjabber jpacket_new() wasn't null safe, this is just safety */
			jp = jpacket_new(xmlnode_get_firstchild(p->x));


		/* auth/reg requests */
		if (jp != NULL && j_strcmp(type, "auth") == 0) {
			/* check and see if we're configured to forward auth packets for processing elsewhere */
			if ((authto =
			     xmlnode_get_data(js_config(si, "auth"))) !=
			    NULL) {
				xmlnode_put_attrib(p->x, "oto", xmlnode_get_attrib(p->x, "to"));	/* preserve original to */
				xmlnode_put_attrib(p->x, "to", authto);
				deliver(dpacket_new(p->x), i);
				return r_DONE;
			}

			/* internally, hide the route to/from addresses on the authreg request */
			xmlnode_put_attrib(jp->x, "to",
					   xmlnode_get_attrib(p->x, "to"));
			xmlnode_put_attrib(jp->x, "from",
					   xmlnode_get_attrib(p->x,
							      "from"));
			xmlnode_put_attrib(jp->x, "route",
					   xmlnode_get_attrib(p->x,
							      "type"));
			jpacket_reset(jp);
			jp->aux1 = (void *) si;

			pt = pmalloco(jp->p, sizeof(packet_thread_t));
			pt->jp = jp;
			fast_mtq_send(si->mtq_authreg, pt);
			return r_DONE;
		}

		/* if it's an error */
		if (j_strcmp(type, "error") == 0) {

			/* look for users online */
			u = js_user(si, p->id, 1);
			if (u == NULL) {
				/* if this was a message,
				   it should have been delievered to that session, store offline */
				if (jp != NULL
				    && jp->type == JPACKET_MESSAGE) {
					pt = pmalloco(jp->p,
						      sizeof
						      (packet_thread_t));
					pt->jp = jp;
					fast_mtq_send(si->mtq_deliver, pt);
					return r_DONE;
				}

				xmlnode_free(p->x);
				return r_DONE;
				/*
				   log_notice(p->host,
				   "Bouncing packet intended for nonexistant user: %s",
				   xmlnode2str(p->x));
				   deliver_fail(dpacket_new(p->x), "Invalid User");
				   return r_DONE;
				 */
			}

			if (p->id->resource != NULL) {
				SEM_LOCK(u->sem);
				for (s = u->sessions; s != NULL;
				     s = s->next)
					if (j_strcmp
					    (p->id->resource,
					     s->route->resource) == 0)
						break;
				SEM_UNLOCK(u->sem);

				if (s != NULL) {
					s->sid = NULL;	/* they generated the error,
							   no use in sending there anymore! */
					js_session_end(s, "Disconnected");
				}
			} else {
				session temp;
				/* a way to boot an entire user off */
				SEM_LOCK(u->sem);
				for (s = u->sessions; s != NULL;) {
					temp = s;
					s = s->next;
					js_session_end_nosem(temp,
							     "Removed");
				}
				u->pass = NULL;	/* so they can't log back in */

				SEM_UNLOCK(u->sem);

				xmlnode_free(p->x);
				THREAD_DEC(u->ref);
				return r_DONE;
			}

			THREAD_DEC(u->ref);

			/* if this was a message,
			   it should have been delievered to that session, store offline */
			if (jp != NULL && jp->type == JPACKET_MESSAGE) {
				pt = pmalloco(jp->p,
					      sizeof(packet_thread_t));
				pt->jp = jp;
				fast_mtq_send(si->mtq_deliver, pt);
				return r_DONE;
			}

			/* drop and return */
			if (xmlnode_get_firstchild(p->x) != NULL)
				log_notice(p->host,
					   "Dropping a bounced session packet to %s",
					   jid_full(p->id));

			xmlnode_free(p->x);
			return r_DONE;
		}

		/* uhh, empty packet, *shrug* */
		if (jp == NULL) {
			log_notice(p->host,
				   "Dropping an invalid or empty route packet: %s",
				   xmlnode2str(p->x), jid_full(p->id));
			xmlnode_free(p->x);
			return r_DONE;
		}

		/* ============================================================== */


		/* attempt to locate the session by matching the special resource */
		u = js_user(si, p->id, 1);
		if (u == NULL) {
			/* only when route packet to users not online */
			pt = pmalloco(p->p, sizeof(packet_thread_t));
			pt->p = p;
			pt->jp = jp;
			fast_mtq_send(si->mtq_deliver, pt);
			return r_DONE;
		}

		/* user is online :) */
		SEM_LOCK(u->sem);
		for (s = u->sessions; s != NULL; s = s->next)
			if (j_strcmp(p->id->resource, s->route->resource)
			    == 0)
				break;
		SEM_UNLOCK(u->sem);

		THREAD_DEC(u->ref);

		if (s != NULL) {	/* just pass to the session normally */
			js_session_from(s, jp);
			return r_DONE;
		}

		log_notice(p->host,
			   "Bouncing %s packet intended for session %s",
			   xmlnode_get_name(jp->x), jid_full(p->id));
		deliver_fail(dpacket_new(p->x), "Invalid Session");
		return r_DONE;
	}

	/* normal server-server packet, should we make sure it's not spoofing us?  if so, if ghash_get(p->to->server) then bounce w/ security error */

	jp = jpacket_new(p->x);
	if (jp == NULL) {
		log_warn(p->host, "Dropping invalid incoming packet: %s",
			 xmlnode2str(p->x));
		xmlnode_free(p->x);
		return r_DONE;
	}

	pt = pmalloco(jp->p, sizeof(packet_thread_t));
	pt->jp = jp;
	fast_mtq_send(si->mtq_deliver, pt);
	return r_DONE;
}
Beispiel #18
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;
}
Beispiel #19
0
int jabber_presence(struct stream_s *stream,xmlnode tag){
char *type;
char *from;
char *to;
xmlnode prio_n;
xmlnode show_n;
xmlnode status_n;
char *show,*status;
int priority;
char *tmp;
User *u;

	type=xmlnode_get_attrib(tag,"type");
	from=xmlnode_get_attrib(tag,"from");
	to=xmlnode_get_attrib(tag,"to");

	if (from) u=user_get_by_jid(from);
	else u=NULL;
	user_load_locale(u);

	if (!acl_is_allowed(from,tag)){
		if (type && !strcmp(type,"error")){
			debug("Ignoring forbidden presence error");
			return -1;
		}
		if (!from) return -1;
		presence_send_error(stream,to,from,405,_("Not allowed"));
		return -1;
	}

	show_n=xmlnode_get_tag(tag,"show");
	if (show_n) show=xmlnode_get_data(show_n);
	else show=NULL;

	status_n=xmlnode_get_tag(tag,"status");
	if (status_n) status=xmlnode_get_data(status_n);
	else status=NULL;

	prio_n=xmlnode_get_tag(tag,"priority");
	if (prio_n){
		tmp=xmlnode_get_data(prio_n);
		if (tmp) priority=atoi(tmp);
		else priority=-1;
	}
	else priority=-1;

	if (!type) type="available";

	if (!from || !to){
		if (strcmp(type,"error"))
			presence_send_error(stream,to,from,406,_("Not Acceptable"));
		g_warning(N_("Bad <presence/>: %s"),xmlnode2str(tag));
		return -1;
	}

	if (!jid_is_my(to)){
		if (strcmp(type,"error"))
			presence_send_error(stream,to,from,406,_("Not Acceptable"));
		g_warning(N_("Wrong 'to' in %s"),xmlnode2str(tag));
		return -1;
	}

	if (!strcmp(type,"available")){
		if (jid_has_uin(to))
			return presence_direct_available(stream,from,to);
		else
			return presence(stream,from,to,1,show,status,priority);
	}
	else if (!strcmp(type,"unavailable")){
		if (jid_has_uin(to))
			return presence_direct_unavailable(stream,from,to);
		else
			return presence(stream,from,to,0,show,status,priority);
	}
	if (!strcmp(type,"invisible")){
		if (jid_has_uin(to))
			return presence_direct_unavailable(stream,from,to);
		else
			return presence(stream,from,to,-1,show,status,priority);
	}
	else if (!strcmp(type,"subscribe"))
		return presence_subscribe(stream,from,to);
	else if (!strcmp(type,"unsubscribe"))
		return presence_unsubscribe(stream,from,to);
	else if (!strcmp(type,"subscribed"))
		return presence_subscribed(stream,from,to);
	else if (!strcmp(type,"unsubscribed"))
		return presence_unsubscribed(stream,from,to);
	else if (!strcmp(type,"probe"))
		return presence_probe(stream,from,to);
	else if (!strcmp(type,"error")){
		g_warning(N_("Error presence received: %s"),xmlnode2str(tag));
		return 0;
	}

	g_warning(N_("Unsupported type in %s"),xmlnode2str(tag));
	presence_send_error(stream,to,from,501,_("Not Implemented"));
	return -1;
}
Beispiel #20
0
int user_save(User *u){
FILE *f;
char *fn;
char *str;
char *njid;
int r;
xmlnode xml,tag,ctag,userlist;

	g_assert(u!=NULL);
	str=strchr(u->jid,'/');
	g_assert(str==NULL);

	if (!u->confirmed){
		g_message(L_("Not saving user '%s' - account not confirmed."),u->jid);
		return -1;
	}

	g_debug(L_("Saving user '%s'"),u->jid);
	njid=jid_normalized(u->jid,0);
	g_assert(njid!=NULL);
	fn=g_strdup_printf("%s.new",njid);
	f=fopen(fn,"w");
	if (!f){
		g_warning(L_("Couldn't open '%s': %s"),fn,g_strerror(errno));
		g_free(fn);
		g_free(njid);
		return -1;
	}
	xml=xmlnode_new_tag("user");
	tag=xmlnode_insert_tag(xml,"version");
	str=g_strdup_printf("%08x",USER_FILE_FORMAT_VERSION);
	xmlnode_put_attrib(tag,"file_format",str);
	g_free(str);
	tag=xmlnode_insert_tag(xml,"jid");
	xmlnode_insert_cdata(tag,u->jid,-1);
	set_subscribe(tag, u->subscribe);
	tag=xmlnode_insert_tag(xml,"uin");
	str=g_strdup_printf("%lu",(unsigned long)u->uin);
	xmlnode_insert_cdata(tag,str,-1);
	g_free(str);
	tag=xmlnode_insert_tag(xml,"password");
	xmlnode_insert_cdata(tag,u->password,-1);

	if (u->last_sys_msg>0){
		tag=xmlnode_insert_tag(xml,"last_sys_msg");
		str=g_strdup_printf("%i",u->last_sys_msg);
		xmlnode_insert_cdata(tag,str,-1);
		g_free(str);
	}

	if (u->invisible) tag=xmlnode_insert_tag(xml,"invisible");
	if (u->friends_only) tag=xmlnode_insert_tag(xml,"friendsonly");
	if (u->ignore_unknown) tag=xmlnode_insert_tag(xml,"ignore_unknown");
	if (u->locale){
		tag=xmlnode_insert_tag(xml,"locale");
		xmlnode_insert_cdata(tag,u->locale,-1);
	}
	if (u->status){
		tag=xmlnode_insert_tag(xml,"status");
		xmlnode_insert_cdata(tag,to_utf8(u->status),-1);
	}

	if (u->contacts){
		GList *it;
		Contact *c;

		userlist=xmlnode_insert_tag(xml,"userlist");
		for(it=g_list_first(u->contacts);it;it=it->next){
			c=(Contact *)it->data;
			ctag=xmlnode_insert_tag(userlist,"contact");
			str=g_strdup_printf("%lu",(unsigned long)c->uin);
			xmlnode_put_attrib(ctag,"uin",str);
			if (c->ignored) xmlnode_put_attrib(ctag,"ignored","ignored");
			if (c->blocked) xmlnode_put_attrib(ctag,"blocked","blocked");
			set_subscribe(ctag, c->subscribe);
			g_free(str);
		}
	}

	str=xmlnode2str(xml);
	r=fputs(str,f);
	if (r<0){
		g_warning(L_("Couldn't save '%s': %s"),u->jid,g_strerror(errno));
		fclose(f);
		unlink(fn);
		xmlnode_free(xml);
		g_free(fn);
		g_free(njid);
		return -1;
	}
	fclose(f);
	r=unlink(njid);
	if (r && errno!=ENOENT){
		g_warning(L_("Couldn't unlink '%s': %s"),njid,g_strerror(errno));
		xmlnode_free(xml);
		g_free(fn);
		g_free(njid);
		return -1;
	}

	r=rename(fn,njid);
	if (r){
		g_warning(L_("Couldn't rename '%s' to '%s': %s"),fn,u->jid,g_strerror(errno));
		xmlnode_free(xml);
		g_free(fn);
		g_free(njid);
		return -1;
	}

	xmlnode_free(xml);
	g_free(fn);
	g_free(njid);
	return 0;
}
Beispiel #21
0
/* Handles logging for each room, simply returning if logfile is not defined */
void con_room_log(cnr room, char *nick, char *message)
{
  time_t t;
  xmlnode xml;
  jid user;
  char *output;
  char timestr[80];
  size_t timelen = 79;
  FILE *logfile;
  pool p;

  if(message == NULL || room == NULL) 
  {
    log_warn(NAME, "[%s] ERR: Aborting - NULL reference found - ", FZONE);
    return;
  }

  logfile = room->logfile;

  if(logfile == NULL) 
  {
    log_debug(NAME, "[%s] Logging not enabled for this room", FZONE);
    return;
  }

  p = pool_heap(1024);

  /* nicked from mod_time */
  t = time(NULL);
  
  if(room->logformat == LOG_XHTML)
    strftime(timestr, timelen, "<a name=\"t%H:%M:%S\" href=\"#t%H:%M:%S\">[%H:%M:%S]</a>", localtime(&t));
  else
    strftime(timestr, timelen, "[%H:%M:%S]", localtime(&t));

  if(room->logformat == LOG_XML)
  {
    xml = jutil_msgnew("groupchat", jid_full(room->id) , NULL, strescape(p, message));

    user = jid_new(xmlnode_pool(xml), jid_full(room->id));
    jid_set(user, strescape(p, nick), JID_RESOURCE);
    xmlnode_put_attrib(xml, "from", jid_full(user));

    jutil_delay(xml, NULL);

    fprintf(logfile, "%s\n", xmlnode2str(xml));

    xmlnode_free(xml);
  }
  else if(room->logformat == LOG_XHTML)
  {
    if(nick)
    {
      if(j_strncmp(message, "/me ", 4) == 0)
      {
        output = extractAction(_con_room_xhtml_strescape(p, message), p);
        fprintf(logfile, "<span class=\"time\">%s</span> * <span class=\"nick\">%s</span>%s<br />\n", timestr, strescape(p, nick), output);

      }
      else
      {
        fprintf(logfile, "<span class=\"time\">%s</span> &lt;<span class=\"nick\">%s</span>&gt; %s<br />\n", timestr, strescape(p, nick), _con_room_xhtml_strescape(p, message));
      }
    }
    else
    {
      fprintf(logfile, "<span class=\"time\">%s</span> --- %s<br />\n", timestr, message);
    }
  }
  else
  {
    if(nick)
    {
      if(j_strncmp(message, "/me ", 4) == 0)
      {
        output = extractAction(message, p);
        fprintf(logfile, "%s * %s%s\n", timestr, nick, output);
      }
      else
      {
        fprintf(logfile, "%s <%s> %s\n", timestr, nick, message);
      }
    }
    else
    {
      fprintf(logfile, "%s --- %s\n", timestr, message);
    }
  }

  fflush(logfile);
  pool_free(p);
  return;
}
Beispiel #22
0
void dnsrv(instance i, xmlnode x)
{
     xdbcache xc = NULL;
     xmlnode  config = NULL;
     xmlnode  iternode   = NULL;
     dns_resend_list tmplist = NULL;

     /* Setup a struct to hold dns_io handles */
     dns_io di;
     di = pmalloco(i->p, sizeof(_dns_io));

     di->mempool = i->p;

     /* Load config from xdb */
     xc = xdb_cache(i);
     config = xdb_get(xc, jid_new(xmlnode_pool(x), "config@-internal"), "jabber:config:dnsrv");

     /* Build a list of services/resend hosts */
     iternode = xmlnode_get_lastchild(config);
     while (iternode != NULL)
     {
          if (j_strcmp("resend", xmlnode_get_name(iternode)) != 0)
          {
               iternode = xmlnode_get_prevsibling(iternode);
               continue;
          }

          /* Allocate a new list node */
          tmplist = pmalloco(di->mempool, sizeof(_dns_resend_list));
          tmplist->service = pstrdup(di->mempool, xmlnode_get_attrib(iternode, "service"));
          tmplist->host    = pstrdup(di->mempool, xmlnode_get_data(iternode));
          /* Insert this node into the list */
          tmplist->next = di->svclist;    
          di->svclist = tmplist;
          /* Move to next child */
          iternode = xmlnode_get_prevsibling(iternode);
     }
     log_debug(ZONE, "dnsrv debug: %s\n", xmlnode2str(config));

     /* Setup the hash of dns_packet_list */
     di->packet_table = xhash_new(j_atoi(xmlnode_get_attrib(config,"queuemax"),101));
     di->packet_timeout = j_atoi(xmlnode_get_attrib(config,"queuetimeout"),60);
     register_beat(di->packet_timeout, dnsrv_beat_packets, (void *)di);


     /* Setup the internal hostname cache */
     di->cache_table = xhash_new(j_atoi(xmlnode_get_attrib(config,"cachemax"),1999));
     di->cache_timeout = j_atoi(xmlnode_get_attrib(config,"cachetimeout"),3600); /* 1 hour dns cache? XXX would be nice to get the right value from dns! */

     xmlnode_free(config);

     /* spawn a thread that get's forked, and wait for it since it sets up the fd's */
     pth_join(pth_spawn(PTH_ATTR_DEFAULT,(void*)dnsrv_thread,(void*)di),NULL);

     if(di->pid < 0)
     {
         log_error(i->id,"dnsrv failed to start, unable to fork and/or create pipes");
         return;
     }

     /* Start IO thread */
     pth_spawn(PTH_ATTR_DEFAULT, dnsrv_process_io, di);

     /* Register an incoming packet handler */
     register_phandler(i, o_DELIVER, dnsrv_deliver, (void*)di);
     /* register a cleanup function */
     pool_cleanup(i->p, dnsrv_shutdown, (void*)di);
}
Beispiel #23
0
void con_room_send_invite(cnu sender, xmlnode node)
{
  xmlnode result;
  xmlnode element;
  xmlnode invite;
  xmlnode pass;
  char *body, *user, *reason, *inviter;
  cnr room;
  pool p;

  if(sender == NULL || node == NULL) 
  {
    log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE);
    return;
  }

  log_debug(NAME, "[%s] Sending room invite", FZONE);

  room = sender->room;

  invite = xmlnode_get_tag(node, "invite");
  user = xmlnode_get_attrib(invite, "to");
  reason = xmlnode_get_tag_data(invite, "reason");

  p = xmlnode_pool(node);

  if(room->visible == 1)
  {
    inviter = jid_full(sender->realid);
  }
  else
  {
    inviter = jid_full(sender->localid);
  }

  xmlnode_put_attrib(invite, "from", inviter);
  xmlnode_hide_attrib(invite, "to");

  if(reason == NULL)
  {
    reason = spools(p, "None given", p);
  }

  body = spools(p, "You have been invited to the ", jid_full(room->id), " room by ", inviter, "\nReason: ", reason, p);

  result = jutil_msgnew("normal", user , "Invitation", body);
  xmlnode_put_attrib(result, "from", jid_full(room->id));

  xmlnode_insert_node(result, node);

  if(room->secret != NULL)
  {
    pass = xmlnode_get_tag(result, "x");
    xmlnode_insert_cdata(xmlnode_insert_tag(pass, "password"), room->secret, -1);
  }

  element = xmlnode_insert_tag(result, "x");
  xmlnode_put_attrib(element, "jid", jid_full(room->id));
  xmlnode_put_attrib(element, "xmlns", NS_X_CONFERENCE);
  xmlnode_insert_cdata(element, reason, -1);

  log_debug(NAME, "[%s] >>>%s<<<", FZONE, xmlnode2str(result));

  deliver(dpacket_new(result), NULL);
  return;

}
Beispiel #24
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;
}
Beispiel #25
0
int jabber_message(struct stream_s *stream,xmlnode tag){
char *type;
char *from;
char *to;
char *subject;
char *body;
int chat;
xmlnode subject_n;
xmlnode body_n;
Session *s;
User *u;

	body_n=xmlnode_get_tag(tag,"body");
	if (body_n!=NULL) body=xmlnode_get_data(body_n);
	else body=NULL;

	subject_n=xmlnode_get_tag(tag,"subject");
	if (subject_n!=NULL) subject=xmlnode_get_data(subject_n);
	else subject=NULL;

	from=xmlnode_get_attrib(tag,"from");
	to=xmlnode_get_attrib(tag,"to");
	type=xmlnode_get_attrib(tag,"type");

	if (!acl_is_allowed(from,tag)){
		if (type && !strcmp(type,"error")){
			debug("Ignoring forbidden message error");
			return -1;
		}
		if (!from) return -1;
		message_send_error(stream,to,from,NULL,405,_("Not allowed"));
		return -1;
	}

	if (from) u=user_get_by_jid(from);
	else u=NULL;
	user_load_locale(u);

	if (!type || !strcmp(type,"normal")) chat=0;
	else if (!strcmp(type,"chat")) chat=1;
	else if (!strcmp(type,"error")){
		g_warning(N_("Error message received: %s"),xmlnode2str(tag));
		return 0;
	}
	else{
		g_warning(N_("Unsupported message type"));
		message_send_error(stream,to,from,body,500,_("Internal Server Error"));
		return -1;
	}

	if (!to || !jid_is_my(to)){
		g_warning(N_("Bad 'to' in: %s"),xmlnode2str(tag));
		message_send_error(stream,to,from,body,400,_("Bad Request"));
		return -1;
	}

	if (!jid_has_uin(to)){
		return message_to_me(stream,from,to,body,tag);
	}

	if (!from){
		g_warning(N_("Anonymous message? %s"),xmlnode2str(tag));
		message_send_error(stream,to,from,body,400,_("Bad Request"));
		return -1;
	}

	s=session_get_by_jid(from,NULL,0);
	if (!s || !s->connected){
		g_warning(N_("%s not logged in. While processing %s"),from,xmlnode2str(tag));
		message_send_error(stream,to,from,body,407,_("Not logged in"));
		return -1;
	}

	if (subject)
		body=g_strdup_printf("Subject: %s\n%s",subject,body);
	session_send_message(s,jid_get_uin(to),chat,string_to_gg(body));
	if (subject)
		g_free(body);

	return 0;
}
Beispiel #26
0
/* returns a valid nick from the list, x is the first <nick>foo</nick> xmlnode, checks siblings */
char *con_room_nick(cnr room, cnu user, xmlnode x)
{
  char *nick = NULL;
  xmlnode cur;
  int count = 1;

  if(room == NULL || user == NULL) 
  {
    log_warn(NAME, "[%s] Aborting - NULL attribute found", FZONE);
    return NULL;
  }

  log_debug(NAME, "[%s] looking for valid nick in room %s from starter %s", FZONE, jid_full(room->id), xmlnode2str(x));

  /* make-up-a-nick phase */
  if(x == NULL)
  {
    nick = pmalloco(user->p, j_strlen(user->realid->user) + 10);
    log_debug(NAME, "[%s] Malloc: Nick = %d", FZONE, j_strlen(user->realid->user) + 10);

    sprintf(nick, "%s", user->realid->user);
    while(g_hash_table_lookup(room->local, nick) != NULL)
      sprintf(nick, "%s%d", user->realid->user,count++);
    return nick;
  }

  /* scan the list */
  for(cur = x; cur != NULL; cur = xmlnode_get_nextsibling(cur))
  {
    if(j_strcmp(xmlnode_get_name(cur),"nick") == 0 && (nick = xmlnode_get_data(cur)) != NULL)
      if(g_hash_table_lookup(room->local, nick) == NULL)
        break;
  }

  if(is_registered(room->master, jid_full(jid_user(user->realid)), nick) == -1)
    nick = NULL;

  return nick;
}
Beispiel #27
0
void jcr_queue_deliver(void *a) {
  extern jcr_instance jcr;
  GIOStatus rc = G_IO_STATUS_NORMAL;
  GString *buffer;
  gsize bytes;
  int left, len, pkts;
  dpacket d;
  GTimeVal timeout;

  int buf_size = j_atoi(xmlnode_get_data(xmlnode_get_tag(jcr->config,"send-buffer")), 8192);

  log_warn(JDBG, "packet delivery thread starting.");
  buffer = g_string_new(NULL);
  while(TRUE) {

    g_string_set_size(buffer, 0);
    pkts = 0;
    g_get_current_time(&timeout);
    g_time_val_add(&timeout, (5 * G_USEC_PER_SEC));
    d = (dpacket)g_async_queue_timed_pop(jcr->dqueue, &timeout);

    if (d == NULL) {
      if (jcr->stream_state == _STREAM_CONNECTED)
         continue;
      else
         break;
    }

    g_string_append(buffer, xmlnode2str(d->x));
    xmlnode_free(d->x);
    d = NULL;
    left = len = buffer->len;
    pkts++;

    while ((g_async_queue_length(jcr->dqueue) > 0) && (buffer->len < buf_size)) {
      d = (dpacket)g_async_queue_pop(jcr->dqueue);
      g_string_append(buffer, xmlnode2str(d->x));
      xmlnode_free(d->x);
      d = NULL;
      left = len = buffer->len;
      pkts++;
    }

    //   log_debug(JDBG, "%d '%s'", len, buf);

    while ((left > 0) && (rc == G_IO_STATUS_NORMAL)) {
      rc = g_io_channel_write_chars(jcr->gio, (buffer->str+(len - left)), left, &bytes, NULL);
      left = left - bytes;

      if (rc != G_IO_STATUS_NORMAL) {
        log_warn(JDBG, "Send packet failed, dropping packet");
      }

      log_debug(JDBG, "wrote %d packets of %d bytes", pkts, bytes);
      //    fprintf(stderr, "wrote %d packets of %d bytes\n", pkts, bytes);
      if (left==0){
        //queue is empty, flushing the socket
        g_io_channel_flush(jcr->gio, NULL);
      }
    }
  }
  log_warn(JDBG, "packet delivery thread exiting.");
  log_warn(JDBG, "  Last DvryQ Buffer='%.*s'", buffer->len, buffer->str);
  g_string_free(buffer, TRUE);
}
Beispiel #28
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;
}