/* 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); }
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; }
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; }
/* 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); }
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); }
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); } }
/** 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; }
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; }
/** 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; } }