예제 #1
0
파일: deliver.c 프로젝트: smokku/wpjabber
/* 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");
}
예제 #2
0
파일: mod_log.c 프로젝트: smokku/wpjabber
mreturn mod_log_archiver(mapi m, void *arg)
{
	jid svcs = (jid) arg;
	xmlnode x;
	char ts[101];
	struct tm now;
	unsigned long ltime;

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

	log_debug("archiving message");

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

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

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

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

	xmlnode_put_attrib(x, "stamp", ts);

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

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

	return M_PASS;
}
예제 #3
0
파일: conference_room.c 프로젝트: bcy/muc
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
파일: xdb.c 프로젝트: Doap/transports
/* actually deliver the xdb request */
void xdb_deliver(instance i, xdbcache xc, int another_thread)
{
    xmlnode x;
    char ids[15];

    x = xmlnode_new_tag("xdb");

    if(xc->set)
    {
        xmlnode_put_attrib(x,"type","set");
        xmlnode_insert_tag_node(x,xc->data); /* copy in the data */
        if(xc->act != NULL)
            xmlnode_put_attrib(x,"action",xc->act);
        if(xc->match != NULL)
            xmlnode_put_attrib(x,"match",xc->match);
    }
	else {
	  xmlnode_put_attrib(x,"type","get");
	}
    xmlnode_put_attrib(x,"to",jid_full(xc->owner));
    xmlnode_put_attrib(x,"from",i->id);
    xmlnode_put_attrib(x,"ns",xc->ns);
    sprintf(ids,"%d",xc->id);
    xmlnode_put_attrib(x,"id",ids); /* to track response */

	if (another_thread) {
	  xdb_resend cur = pmalloco(xmlnode_pool(x),sizeof(_xdb_resend));
	  cur->x = x;
	  cur->i = i;
	  mtq_send(NULL,NULL,resend_xdb,(void *)cur);
	}
	else {
	  deliver(dpacket_new(x), i);
	}
}
예제 #5
0
파일: deliver.c 프로젝트: smokku/wpjabber
/* 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);
}
예제 #6
0
파일: base_to.c 프로젝트: smokku/wpjabber
result base_to_deliver(instance id, dpacket p, void *arg)
{
	char *log_data = xmlnode_get_data(p->x);
	char *subject;
	xmlnode message;

	if (log_data == NULL)
		return r_ERR;

	message = xmlnode_new_tag("message");

	xmlnode_insert_cdata(xmlnode_insert_tag(message, "body"), log_data,
			     -1);
	subject =
	    spools(xmlnode_pool(message), "Log Packet from ",
		   xmlnode_get_attrib(p->x, "from"),
		   xmlnode_pool(message));
	xmlnode_insert_cdata(xmlnode_insert_tag(message, "thread"),
			     shahash(subject), -1);
	xmlnode_insert_cdata(xmlnode_insert_tag(message, "subject"),
			     subject, -1);
	xmlnode_put_attrib(message, "from",
			   xmlnode_get_attrib(p->x, "from"));
	xmlnode_put_attrib(message, "to", (char *) arg);

	deliver(dpacket_new(message), id);
	pool_free(p->p);

	return r_DONE;
}
예제 #7
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);
}
예제 #8
0
파일: sessions.c 프로젝트: smokku/wpjabber
/* delivers a route packet to all listeners for this session */
static void js_session_route(session s, xmlnode in)
{
	/* NULL means this is an error from the session ending */
	if (in == NULL) {
		in = xmlnode_new_tag("route");
		xmlnode_put_attrib(in, "type", "error");
		xmlnode_put_attrib(in, "error", "Disconnected");
	} else {
		in = xmlnode_wrap(in, "route");
	}

	xmlnode_put_attrib(in, "from", jid_full(s->route));
	xmlnode_put_attrib(in, "to", jid_full(s->sid));
	deliver(dpacket_new(in), s->si->i);
}
예제 #9
0
파일: deliver.c 프로젝트: smokku/wpjabber
/* always deliver threads */
inline static void js_session_new_mtq(jsmi si, dpacket p)
{
	session s;

	if ((s = js_session_new(si, p)) == NULL) {
		/* session start failed */
		log_warn(p->host, "Unable to create session %s",
			 jid_full(p->id));
		xmlnode_put_attrib(p->x, "type", "error");
		xmlnode_put_attrib(p->x, "error", "Session Failed");
	} else {
		/* reset to the routed id for this session for the reply below */
		xmlnode_put_attrib(p->x, "to", jid_full(s->route));
	}

	/* reply */
	jutil_tofrom(p->x);
	deliver(dpacket_new(p->x), si->i);
}
예제 #10
0
파일: jcr_deliver.c 프로젝트: bcy/muc
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);
  }
}
예제 #11
0
파일: xdb.c 프로젝트: Doap/transports
/** Resend packet in other thread  */
void resend_xdb(void *arg) {
  xdb_resend cur = (xdb_resend)arg;
  deliver(dpacket_new(cur->x), cur->i);
}
예제 #12
0
파일: deliver.c 프로젝트: smokku/wpjabber
/* 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;
}
예제 #13
0
파일: conference_room.c 프로젝트: bcy/muc
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;

}