jabberd2  2.2.17
router.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "router.h"
22 
23 #define MAX_JID 3072 // node(1023) + '@'(1) + domain(1023) + '/'(1) + resource(1023) + '\0'(1)
24 #define MAX_MESSAGE 65535
25 #define SECS_PER_DAY 86400
26 #define BYTES_PER_MEG 1048576
27 
29 typedef struct broadcast_st {
33 } *broadcast_t;
34 
36 static void _router_broadcast(const char *key, int keylen, void *val, void *arg) {
37  int i;
38  broadcast_t bc = (broadcast_t) arg;
39  routes_t routes = (routes_t) val;
40 
41  for(i = 0; i < routes->ncomp; i++) {
42  /* I don't care about myself or the elderly (!?) */
43  if(routes->comp[i] == bc->src || routes->comp[i]->legacy)
44  continue;
45 
46  sx_nad_write(routes->comp[i]->s, nad_copy(bc->nad));
47  }
48 }
49 
51 static void _router_advertise(router_t r, char *domain, component_t src, int unavail) {
52  struct broadcast_st bc;
53  int ns;
54 
55  log_debug(ZONE, "advertising %s to all routes (unavail=%d)", domain, unavail);
56 
57  bc.r = r;
58  bc.src = src;
59 
60  /* create a new packet */
61  bc.nad = nad_new();
62  ns = nad_add_namespace(bc.nad, uri_COMPONENT, NULL);
63  nad_append_elem(bc.nad, ns, "presence", 0);
64  nad_append_attr(bc.nad, -1, "from", domain);
65  if(unavail)
66  nad_append_attr(bc.nad, -1, "type", "unavailable");
67 
68  xhash_walk(r->routes, _router_broadcast, (void *) &bc);
69 
70  nad_free(bc.nad);
71 }
72 
74 static void _router_advertise_reverse(const char *key, int keylen, void *val, void *arg) {
75  component_t dest = (component_t) arg;
76  routes_t routes = (routes_t) val;
77  int el, ns, i;
78  nad_t nad;
79 
80  assert((int) (routes->name != NULL));
81  assert((int) (routes->comp != NULL));
82  assert(routes->ncomp);
83 
84  /* don't tell me about myself */
85  for(i = 0; i < routes->ncomp; i++)
86  if(routes->comp[i] == dest)
87  return;
88 
89  log_debug(ZONE, "informing component about %.*s", keylen, key);
90 
91  /* create a new packet */
92  nad = nad_new();
93  ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
94  el = nad_append_elem(nad, ns, "presence", 0);
95  nad_set_attr(nad, el, -1, "from", key, keylen);
96 
97  sx_nad_write(dest->s, nad);
98 }
99 
101  char *hash;
102  int hashlen;
103 
104  /* must have a hash as cdata */
105  if(NAD_CDATA_L(nad, 0) != 40) {
106  log_debug(ZONE, "handshake isn't long enough to be a sha1 hash");
107  sx_error(comp->s, stream_err_NOT_AUTHORIZED, "handshake isn't long enough to be a sha1 hash");
108  sx_close(comp->s);
109 
110  nad_free(nad);
111  return;
112  }
113 
114  /* make room for shahash_r to work .. needs at least 41 chars */
115  hashlen = strlen(comp->s->id) + strlen(comp->r->local_secret) + 1;
116  if(hashlen < 41)
117  hashlen = 41;
118 
119  /* build the creds and hash them */
120  hash = (char *) malloc(sizeof(char) * hashlen);
121  sprintf(hash, "%s%s", comp->s->id, comp->r->local_secret);
122  shahash_r(hash, hash);
123 
124  /* check */
125  log_debug(ZONE, "checking their hash %.*s against our hash %s", 40, NAD_CDATA(nad, 0), hash);
126 
127  if(strncmp(hash, NAD_CDATA(nad, 0), 40) == 0) {
128  log_debug(ZONE, "handshake succeeded");
129 
130  free(hash);
131 
132  /* respond */
133  nad->elems[0].icdata = nad->elems[0].itail = -1;
134  nad->elems[0].lcdata = nad->elems[0].ltail = 0;
135  sx_nad_write(comp->s, nad);
136 
137  sx_auth(comp->s, "handshake", comp->s->req_to);
138 
139  return;
140  }
141 
142  log_debug(ZONE, "auth failed");
143 
144  free(hash);
145 
146  /* failed, let them know */
147  sx_error(comp->s, stream_err_NOT_AUTHORIZED, "hash didn't match, auth failed");
148  sx_close(comp->s);
149 
150  nad_free(nad);
151 }
152 
153 void routes_free(routes_t routes) {
154  if(routes->name) free(routes->name);
155  if(routes->comp) free(routes->comp);
156  free(routes);
157 }
158 
159 static int _route_add(xht hroutes, const char *name, component_t comp, route_type_t rtype) {
160  routes_t routes;
161 
162  routes = xhash_get(hroutes, name);
163  if(routes == NULL) {
164  routes = (routes_t) calloc(1, sizeof(struct routes_st));
165  routes->name = strdup(name);
166  routes->rtype = rtype;
167  }
168  routes->comp = (component_t *) realloc(routes->comp, sizeof(component_t *) * (routes->ncomp + 1));
169  routes->comp[routes->ncomp] = comp;
170  routes->ncomp++;
171  xhash_put(hroutes, routes->name, (void *) routes);
172 
173  if(routes->rtype != rtype)
174  log_write(comp->r->log, LOG_ERR, "Mixed route types for '%s' bind request", name);
175 
176  return routes->ncomp;
177 }
178 
179 static void _route_remove(xht hroutes, const char *name, component_t comp) {
180  routes_t routes;
181  int i;
182 
183  routes = xhash_get(hroutes, name);
184  if(routes == NULL) return;
185 
186  if(routes->ncomp > 1) {
187  for(i = 0; i < routes->ncomp; i++) {
188  if(routes->comp[i] == comp) {
189  if(i != routes->ncomp - 1) {
190  routes->comp[i] = routes->comp[routes->ncomp - 1];
191  }
192  routes->ncomp--;
193  }
194  }
195  }
196  else {
197  jqueue_push(comp->r->deadroutes, (void *) routes, 0);
198  xhash_zap(hroutes, name);
199  }
200 }
201 
203  int attr, multi, n;
204  jid_t name;
205  alias_t alias;
206  char *user, *c;
207 
208  attr = nad_find_attr(nad, 0, -1, "name", NULL);
209  if(attr < 0 || (name = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
210  log_debug(ZONE, "no or invalid 'name' on bind packet, bouncing");
211  nad_set_attr(nad, 0, -1, "error", "400", 3);
212  sx_nad_write(comp->s, nad);
213  return;
214  }
215 
216  user = strdup(comp->s->auth_id);
217  c = strchr(user, '@');
218  if(c != NULL) *c = '\0';
219 
220  if(strcmp(user, name->domain) != 0 && !aci_check(comp->r->aci, "bind", user)) {
221  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to bind '%s', but their username (%s) is not permitted to bind other names", comp->ip, comp->port, name->domain, user);
222  nad_set_attr(nad, 0, -1, "name", NULL, 0);
223  nad_set_attr(nad, 0, -1, "error", "403", 3);
224  sx_nad_write(comp->s, nad);
225  jid_free(name);
226  free(user);
227  return;
228  }
229 
230  multi = nad_find_attr(nad, 0, -1, "multi", NULL);
231  if(xhash_get(comp->r->routes, name->domain) != NULL && multi < 0) {
232  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to bind '%s', but it's already bound", comp->ip, comp->port, name->domain);
233  nad_set_attr(nad, 0, -1, "name", NULL, 0);
234  nad_set_attr(nad, 0, -1, "error", "409", 3);
235  sx_nad_write(comp->s, nad);
236  jid_free(name);
237  free(user);
238  return;
239  }
240 
241  for(alias = comp->r->aliases; alias != NULL; alias = alias->next)
242  if(strcmp(alias->name, name->domain) == 0) {
243  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to bind '%s', but that name is aliased", comp->ip, comp->port);
244  nad_set_attr(nad, 0, -1, "name", NULL, 0);
245  nad_set_attr(nad, 0, -1, "error", "409", 3);
246  sx_nad_write(comp->s, nad);
247  jid_free(name);
248  free(user);
249  return;
250  }
251 
252  /* default route */
253  if(nad_find_elem(nad, 0, NAD_ENS(nad, 0), "default", 1) >= 0) {
254  if(!aci_check(comp->r->aci, "default-route", user)) {
255  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to bind '%s' as the default route, but their username (%s) is not permitted to set a default route", comp->ip, comp->port, name->domain, user);
256  nad_set_attr(nad, 0, -1, "name", NULL, 0);
257  nad_set_attr(nad, 0, -1, "error", "403", 3);
258  sx_nad_write(comp->s, nad);
259  jid_free(name);
260  free(user);
261  return;
262  }
263 
264  if(comp->r->default_route != NULL) {
265  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to bind '%s' as the default route, but one already exists", comp->ip, comp->port, name->domain);
266  nad_set_attr(nad, 0, -1, "name", NULL, 0);
267  nad_set_attr(nad, 0, -1, "error", "409", 3);
268  sx_nad_write(comp->s, nad);
269  jid_free(name);
270  return;
271  }
272 
273  log_write(comp->r->log, LOG_NOTICE, "[%s] set as default route", name->domain);
274 
275  comp->r->default_route = strdup(name->domain);
276  }
277 
278  /* log sinks */
279  if(nad_find_elem(nad, 0, NAD_ENS(nad, 0), "log", 1) >= 0) {
280  if(!aci_check(comp->r->aci, "log", user)) {
281  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to bind '%s' as a log sink, but their username (%s) is not permitted to do this", comp->ip, comp->port, name->domain, user);
282  nad_set_attr(nad, 0, -1, "name", NULL, 0);
283  nad_set_attr(nad, 0, -1, "error", "403", 3);
284  sx_nad_write(comp->s, nad);
285  jid_free(name);
286  free(user);
287  return;
288  }
289 
290  log_write(comp->r->log, LOG_NOTICE, "[%s] set as log sink", name->domain);
291 
292  xhash_put(comp->r->log_sinks, pstrdup(xhash_pool(comp->r->log_sinks), name->domain), (void *) comp);
293  }
294 
295  free(user);
296 
297  n = _route_add(comp->r->routes, name->domain, comp, multi<0?route_SINGLE:route_MULTI_TO);
298  xhash_put(comp->routes, pstrdup(xhash_pool(comp->routes), name->domain), (void *) comp);
299 
300  if(n>1)
301  log_write(comp->r->log, LOG_NOTICE, "[%s]:%d online (bound to %s, port %d)", name->domain, n, comp->ip, comp->port);
302  else
303  log_write(comp->r->log, LOG_NOTICE, "[%s] online (bound to %s, port %d)", name->domain, comp->ip, comp->port);
304 
305  nad_set_attr(nad, 0, -1, "name", NULL, 0);
306  sx_nad_write(comp->s, nad);
307 
308  /* advertise name */
309  _router_advertise(comp->r, name->domain, comp, 0);
310 
311  /* tell the new component about everyone else */
312  xhash_walk(comp->r->routes, _router_advertise_reverse, (void *) comp);
313 
314  /* bind aliases */
315  for(alias = comp->r->aliases; alias != NULL; alias = alias->next) {
316  if(strcmp(alias->target, name->domain) == 0) {
317  _route_add(comp->r->routes, name->domain, comp, route_MULTI_TO);
318  xhash_put(comp->routes, pstrdup(xhash_pool(comp->routes), alias->name), (void *) comp);
319 
320  log_write(comp->r->log, LOG_NOTICE, "[%s] online (alias of '%s', bound to %s, port %d)", alias->name, name->domain, comp->ip, comp->port);
321 
322  /* advertise name */
323  _router_advertise(comp->r, alias->name, comp, 0);
324  }
325  }
326 
327  /* done with this */
328  jid_free(name);
329 }
330 
332  int attr;
333  jid_t name;
334 
335  attr = nad_find_attr(nad, 0, -1, "name", NULL);
336  if(attr < 0 || (name = jid_new(NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
337  log_debug(ZONE, "no or invalid 'name' on unbind packet, bouncing");
338  nad_set_attr(nad, 0, -1, "error", "400", 3);
339  sx_nad_write(comp->s, nad);
340  return;
341  }
342 
343  if(xhash_get(comp->routes, name->domain) == NULL) {
344  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to unbind '%s', but it's not bound to this component", comp->ip, comp->port, name->domain);
345  nad_set_attr(nad, 0, -1, "name", NULL, 0);
346  nad_set_attr(nad, 0, -1, "error", "404", 3);
347  sx_nad_write(comp->s, nad);
348  jid_free(name);
349  return;
350  }
351 
352  xhash_zap(comp->r->log_sinks, name->domain);
353  _route_remove(comp->r->routes, name->domain, comp);
354  xhash_zap(comp->routes, name->domain);
355 
356  if(comp->r->default_route != NULL && strcmp(comp->r->default_route, name->domain) == 0) {
357  log_write(comp->r->log, LOG_NOTICE, "[%s] default route offline", name->domain);
358  free(comp->r->default_route);
359  comp->r->default_route = NULL;
360  }
361 
362  log_write(comp->r->log, LOG_NOTICE, "[%s] offline", name->domain);
363 
364  nad_set_attr(nad, 0, -1, "name", NULL, 0);
365  sx_nad_write(comp->s, nad);
366 
367  /* deadvertise name */
368  if(xhash_get(comp->r->routes, name->domain) == NULL)
369  _router_advertise(comp->r, name->domain, comp, 1);
370 
371  jid_free(name);
372 }
373 
375  int attr;
376 
377  if(comp->tq != NULL) {
378  log_debug(ZONE, "%s port %d is throttled, jqueueing packet", comp->ip, comp->port);
379  jqueue_push(comp->tq, nad, 0);
380  return;
381  }
382 
383  /* packets go raw to normal components */
384  if(!comp->legacy) {
385  sx_nad_write(comp->s, nad);
386  return;
387  }
388 
389  log_debug(ZONE, "packet for legacy component, munging");
390 
391  attr = nad_find_attr(nad, 0, -1, "error", NULL);
392  if(attr >= 0) {
393  if(NAD_AVAL_L(nad, attr) == 3 && strncmp("400", NAD_AVAL(nad, attr), 3) == 0)
395  else
397  }
398 
399  sx_nad_write_elem(comp->s, nad, 1);
400 }
401 
402 static void _router_route_log_sink(const char *key, int keylen, void *val, void *arg) {
403  component_t comp = (component_t) val;
404  nad_t nad = (nad_t) arg;
405 
406  log_debug(ZONE, "copying route to '%.*s' (%s, port %d)", keylen, key, comp->ip, comp->port);
407 
408  nad = nad_copy(nad);
409  nad_set_attr(nad, 0, -1, "type", "log", 3);
410  _router_comp_write(comp, nad);
411 }
412 
414  int atype, ato, afrom;
415  unsigned int dest;
416  struct jid_st sto, sfrom;
417  jid_static_buf sto_buf, sfrom_buf;
418  jid_t to = NULL, from = NULL;
419  routes_t targets;
420  component_t target;
421  union xhashv xhv;
422 
423  /* init static jid */
424  jid_static(&sto,&sto_buf);
425  jid_static(&sfrom,&sfrom_buf);
426 
427  if(nad_find_attr(nad, 0, -1, "error", NULL) >= 0) {
428  log_debug(ZONE, "dropping error packet, trying to avoid loops");
429  nad_free(nad);
430  return;
431  }
432 
433  atype = nad_find_attr(nad, 0, -1, "type", NULL);
434  ato = nad_find_attr(nad, 0, -1, "to", NULL);
435  afrom = nad_find_attr(nad, 0, -1, "from", NULL);
436 
437  if(ato >= 0) to = jid_reset(&sto, NAD_AVAL(nad, ato), NAD_AVAL_L(nad, ato));
438  if(afrom >= 0) from = jid_reset(&sfrom, NAD_AVAL(nad, afrom), NAD_AVAL_L(nad, afrom));
439 
440  /* unicast */
441  if(atype < 0) {
442  if(to == NULL || from == NULL) {
443  log_debug(ZONE, "unicast route with missing or invalid to or from, bouncing");
444  nad_set_attr(nad, 0, -1, "error", "400", 3);
445  _router_comp_write(comp, nad);
446  return;
447  }
448 
449  log_debug(ZONE, "unicast route from %s to %s", from->domain, to->domain);
450 
451  /* check the from */
452  if(xhash_get(comp->routes, from->domain) == NULL) {
453  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to send a packet from '%s', but that name is not bound to this component", comp->ip, comp->port, from->domain);
454  nad_set_attr(nad, 0, -1, "error", "401", 3);
455  _router_comp_write(comp, nad);
456  return;
457  }
458 
459  /* filter it */
460  if(comp->r->filter != NULL) {
461  int ret = filter_packet(comp->r, nad);
462  if(ret == stanza_err_REDIRECT) {
463  ato = nad_find_attr(nad, 0, -1, "to", NULL);
464  if(ato >= 0) to = jid_reset(&sto, NAD_AVAL(nad, ato), NAD_AVAL_L(nad, ato));
465  }
466  else if(ret > 0) {
467  log_debug(ZONE, "packet filtered out: %s (%s)", _stanza_errors[ret - stanza_err_BAD_REQUEST].name, _stanza_errors[ret - stanza_err_BAD_REQUEST].code);
468  nad_set_attr(nad, 0, -1, "error", _stanza_errors[ret - stanza_err_BAD_REQUEST].code, 3);
469  _router_comp_write(comp, nad);
470  return;
471  }
472  }
473 
474  /* find a target */
475  targets = xhash_get(comp->r->routes, to->domain);
476  if(targets == NULL) {
477  if(comp->r->default_route != NULL && strcmp(from->domain, comp->r->default_route) == 0) {
478  log_debug(ZONE, "%s is unbound, bouncing", from->domain);
479  nad_set_attr(nad, 0, -1, "error", "404", 3);
480  _router_comp_write(comp, nad);
481  return;
482  }
483  targets = xhash_get(comp->r->routes, comp->r->default_route);
484  }
485 
486  if(targets == NULL) {
487  log_debug(ZONE, "%s is unbound, and no default route, bouncing", to->domain);
488  nad_set_attr(nad, 0, -1, "error", "404", 3);
489  _router_comp_write(comp, nad);
490  return;
491  }
492 
493  /* copy to any log sinks */
494  if(xhash_count(comp->r->log_sinks) > 0)
495  xhash_walk(comp->r->log_sinks, _router_route_log_sink, (void *) nad);
496 
497  /* get route candidate */
498  if(targets->ncomp == 1) {
499  dest = 0;
500  }
501  else {
502  switch(targets->rtype) {
503  case route_MULTI_TO:
504  ato = nad_find_attr(nad, 1, -1, "to", NULL);
505  if(ato >= 0) to = jid_reset(&sto, NAD_AVAL(nad, ato), NAD_AVAL_L(nad, ato));
506  else {
507  ato = nad_find_attr(nad, 1, -1, "target", NULL);
508  if(ato >= 0) to = jid_reset(&sto, NAD_AVAL(nad, ato), NAD_AVAL_L(nad, ato));
509  else {
510  char *out; int len;
511  nad_print(nad, 0, &out, &len);
512  log_write(comp->r->log, LOG_ERR, "Cannot get destination for multiple route: %.*s", len, out);
513  }
514  }
515  break;
516  case route_MULTI_FROM:
517  ato = nad_find_attr(nad, 1, -1, "from", NULL);
518  if(ato >= 0) to = jid_reset(&sto, NAD_AVAL(nad, ato), NAD_AVAL_L(nad, ato));
519  else {
520  char *out; int len;
521  nad_print(nad, 0, &out, &len);
522  log_write(comp->r->log, LOG_ERR, "Cannot get source for multiple route: %.*s", len, out);
523  }
524  break;
525  default:
526  log_write(comp->r->log, LOG_ERR, "Multiple components bound to single component route '%s'", targets->name);
527  /* simulate no 'to' info in this case */
528  }
529  if(to->node == NULL || strlen(to->node) == 0) {
530  /* no node in destination JID - going random */
531  dest = rand();
532  log_debug(ZONE, "randomized to %u %% %d = %d", dest, targets->ncomp, dest % targets->ncomp);
533  }
534  else {
535  /* use JID hash */
536  unsigned char hashval[20];
537  unsigned int *val;
538  int i;
539 
540  shahash_raw(jid_user(to), hashval);
541 
542  val = (unsigned int *) hashval;
543  dest = *val;
544  for(i=1; i < 20 / (sizeof(unsigned int)/sizeof(unsigned char)); i++, val++) {
545  dest ^= *val;
546  }
547  dest >>= 2;
548 
549  log_debug(ZONE, "JID %s hashed to %u %% %d = %d", jid_user(to), dest, targets->ncomp, dest % targets->ncomp);
550 
551  /* jid_user() calls jid_expand() which may allocate some memory in _user and _full */
552  if (to->_user != NULL )
553  free(to->_user);
554  if (to->_full != NULL )
555  free(to->_full);
556  }
557  dest = dest % targets->ncomp;
558  }
559 
560  target = targets->comp[dest];
561 
562  /* push it out */
563  log_debug(ZONE, "writing route for '%s'*%u to %s, port %d", to->domain, dest+1, target->ip, target->port);
564 
565  /* if logging enabled, log messages that match our criteria */
566  if (comp->r->message_logging_enabled && comp->r->message_logging_file != NULL) {
567  int attr_msg_to;
568  int attr_msg_from;
569  int attr_route_to;
570  int attr_route_from;
571  jid_t jid_msg_from = NULL;
572  jid_t jid_msg_to = NULL;
573  jid_t jid_route_from = NULL;
574  jid_t jid_route_to = NULL;
575 
576  if ((NAD_ENAME_L(nad, 1) == 7 && strncmp("message", NAD_ENAME(nad, 1), 7) == 0) && // has a "message" element
577  ((attr_route_from = nad_find_attr(nad, 0, -1, "from", NULL)) >= 0) &&
578  ((attr_route_to = nad_find_attr(nad, 0, -1, "to", NULL)) >= 0) &&
579  ((strncmp(NAD_AVAL(nad, attr_route_to), "c2s", 3)) != 0) && // ignore messages to "c2s" or we'd have dups
580  ((jid_route_from = jid_new(NAD_AVAL(nad, attr_route_from), NAD_AVAL_L(nad, attr_route_from))) != NULL) && // has valid JID source in route
581  ((jid_route_to = jid_new(NAD_AVAL(nad, attr_route_to), NAD_AVAL_L(nad, attr_route_to))) != NULL) && // has valid JID destination in route
582  ((attr_msg_from = nad_find_attr(nad, 1, -1, "from", NULL)) >= 0) &&
583  ((attr_msg_to = nad_find_attr(nad, 1, -1, "to", NULL)) >= 0) &&
584  ((jid_msg_from = jid_new(NAD_AVAL(nad, attr_msg_from), NAD_AVAL_L(nad, attr_msg_from))) != NULL) && // has valid JID source in message
585  ((jid_msg_to = jid_new(NAD_AVAL(nad, attr_msg_to), NAD_AVAL_L(nad, attr_msg_to))) != NULL)) // has valid JID dest in message
586  {
587  message_log(nad, comp->r, jid_full(jid_msg_from), jid_full(jid_msg_to));
588  }
589  if (jid_msg_from != NULL)
590  jid_free(jid_msg_from);
591  if (jid_msg_to != NULL)
592  jid_free(jid_msg_to);
593  if (jid_route_from != NULL)
594  jid_free(jid_route_from);
595  if (jid_route_to != NULL)
596  jid_free(jid_route_to);
597  }
598 
599  _router_comp_write(target, nad);
600 
601  return;
602  }
603 
604  /* broadcast */
605  if(NAD_AVAL_L(nad, atype) == 9 && strncmp("broadcast", NAD_AVAL(nad, atype), 9) == 0) {
606  if(from == NULL) {
607  log_debug(ZONE, "broadcast route with missing or invalid from, bouncing");
608  nad_set_attr(nad, 0, -1, "error", "400", 3);
609  _router_comp_write(comp, nad);
610  return;
611  }
612 
613  log_debug(ZONE, "broadcast route from %s", from->domain);
614 
615  /* check the from */
616  if(xhash_get(comp->routes, from->domain) == NULL) {
617  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] tried to send a packet from '%s', but that name is not bound to this component", comp->ip, comp->port, from->domain);
618  nad_set_attr(nad, 0, -1, "error", "401", 3);
619  _router_comp_write(comp, nad);
620  return;
621  }
622 
623  /* loop the components and distribute */
624  if(xhash_iter_first(comp->r->components))
625  do {
626  xhv.comp_val = &target;
627  xhash_iter_get(comp->r->components, NULL, NULL, xhv.val);
628 
629  if(target != comp) {
630  log_debug(ZONE, "writing broadcast to %s, port %d", target->ip, target->port);
631 
632  _router_comp_write(target, nad_copy(nad));
633  }
634  } while(xhash_iter_next(comp->r->components));
635 
636  nad_free(nad);
637 
638  return;
639  }
640 
641  log_debug(ZONE, "unknown route type '%.*s', dropping", NAD_AVAL_L(nad, atype), NAD_AVAL(nad, atype));
642 
643  nad_free(nad);
644 }
645 
647  jqueue_t tq;
648  nad_t pkt;
649 
650  if(comp->tq == NULL) {
651  _router_comp_write(comp, nad);
652 
653  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] throttling packets on request", comp->ip, comp->port);
654  comp->tq = jqueue_new();
655  }
656 
657  else {
658  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] unthrottling packets on request", comp->ip, comp->port);
659  tq = comp->tq;
660  comp->tq = NULL;
661 
662  _router_comp_write(comp, nad);
663 
664  while((pkt = jqueue_pull(tq)) != NULL)
665  _router_comp_write(comp, pkt);
666 
667  jqueue_free(tq);
668  }
669 }
670 
671 static int _router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg) {
672  component_t comp = (component_t) arg;
673  sx_buf_t buf = (sx_buf_t) data;
674  int rlen, len, attr, ns, sns, n;
675  sx_error_t *sxe;
676  nad_t nad;
677  struct jid_st sto, sfrom;
678  jid_static_buf sto_buf, sfrom_buf;
679  jid_t to, from;
680  alias_t alias;
681 
682  /* init static jid */
683  jid_static(&sto,&sto_buf);
684  jid_static(&sfrom,&sfrom_buf);
685 
686  switch(e) {
687  case event_WANT_READ:
688  log_debug(ZONE, "want read");
689  mio_read(comp->r->mio, comp->fd);
690  break;
691 
692  case event_WANT_WRITE:
693  log_debug(ZONE, "want write");
694  mio_write(comp->r->mio, comp->fd);
695  break;
696 
697  case event_READ:
698  log_debug(ZONE, "reading from %d", comp->fd->fd);
699 
700  /* check rate limits */
701  if(comp->rate != NULL) {
702  if(rate_check(comp->rate) == 0) {
703 
704  /* inform the app if we haven't already */
705  if(!comp->rate_log) {
706  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] is being byte rate limited", comp->ip, comp->port);
707 
708  comp->rate_log = 1;
709  }
710 
711  log_debug(ZONE, "%d is throttled, delaying read", comp->fd->fd);
712 
713  buf->len = 0;
714  return 0;
715  }
716 
717  /* find out how much we can have */
718  rlen = rate_left(comp->rate);
719  if(rlen > buf->len)
720  rlen = buf->len;
721  }
722 
723  /* no limit, just read as much as we can */
724  else
725  rlen = buf->len;
726 
727  /* do the read */
728  len = recv(comp->fd->fd, buf->data, rlen, 0);
729 
730  /* update rate limits */
731  if(comp->rate != NULL && len > 0) {
732  comp->rate_log = 0;
733  rate_add(comp->rate, len);
734  }
735 
736  if(len < 0) {
737  if(MIO_WOULDBLOCK) {
738  buf->len = 0;
739  return 0;
740  }
741 
742  log_debug(ZONE, "read failed: %s", strerror(errno));
743 
744  sx_kill(comp->s);
745 
746  return -1;
747  }
748 
749  else if(len == 0) {
750  /* they went away */
751  sx_kill(comp->s);
752 
753  return -1;
754  }
755 
756  log_debug(ZONE, "read %d bytes", len);
757 
758  buf->len = len;
759 
760  return len;
761 
762  case event_WRITE:
763  log_debug(ZONE, "writing to %d", comp->fd->fd);
764 
765  len = send(comp->fd->fd, buf->data, buf->len, 0);
766  if(len >= 0) {
767  log_debug(ZONE, "%d bytes written", len);
768  return len;
769  }
770 
771  if(MIO_WOULDBLOCK)
772  return 0;
773 
774  log_debug(ZONE, "write failed: %s", strerror(errno));
775 
776  sx_kill(comp->s);
777 
778  return -1;
779 
780  case event_ERROR:
781  sxe = (sx_error_t *) data;
782  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] error: %s (%s)", comp->ip, comp->port, sxe->generic, sxe->specific);
783 
784  break;
785 
786  case event_STREAM:
787 
788  /* legacy check */
789  if(s->ns == NULL || strcmp("jabber:component:accept", s->ns) != 0)
790  return 0;
791 
792  /* component, old skool */
793  comp->legacy = 1;
794 
795  /* enabled? */
796  if(comp->r->local_secret == NULL) {
797  sx_error(s, stream_err_INVALID_NAMESPACE, "support for legacy components not available"); /* !!! correct error? */
798  sx_close(s);
799  return 0;
800  }
801 
802  /* sanity */
803  if(s->req_to == NULL) {
804  sx_error(s, stream_err_HOST_UNKNOWN, "no 'to' attribute on stream header");
805  sx_close(s);
806  return 0;
807  }
808 
809  break;
810 
811  case event_OPEN:
812 
813  log_write(comp->r->log, LOG_NOTICE, "[%s, port=%d] authenticated as %s", comp->ip, comp->port, comp->s->auth_id);
814 
815  /* make a route for legacy components */
816  if(comp->legacy) {
817  for(alias = comp->r->aliases; alias != NULL; alias = alias->next)
818  if(strcmp(alias->name, s->req_to) == 0) {
819  sx_error(s, stream_err_HOST_UNKNOWN, "requested name is aliased"); /* !!! correct error? */
820  sx_close(s);
821  return 0;
822  }
823 
824 
825  n = _route_add(comp->r->routes, s->req_to, comp, route_MULTI_FROM);
826  xhash_put(comp->routes, pstrdup(xhash_pool(comp->routes), s->req_to), (void *) comp);
827 
828  if(n>1)
829  log_write(comp->r->log, LOG_NOTICE, "[%s]:%d online (bound to %s, port %d)", s->req_to, n, comp->ip, comp->port);
830  else
831  log_write(comp->r->log, LOG_NOTICE, "[%s] online (bound to %s, port %d)", s->req_to, comp->ip, comp->port);
832 
833  /* advertise the name */
834  _router_advertise(comp->r, s->req_to, comp, 0);
835 
836  /* this is a legacy component, so we don't tell it about other routes */
837 
838  /* bind aliases */
839  for(alias = comp->r->aliases; alias != NULL; alias = alias->next) {
840  if(strcmp(alias->target, s->req_to) == 0) {
841  _route_add(comp->r->routes, alias->name, comp, route_MULTI_FROM);
842  xhash_put(comp->routes, pstrdup(xhash_pool(comp->routes), alias->name), (void *) comp);
843 
844  log_write(comp->r->log, LOG_NOTICE, "[%s] online (alias of '%s', bound to %s, port %d)", alias->name, s->req_to, comp->ip, comp->port);
845 
846  /* advertise name */
847  _router_advertise(comp->r, alias->name, comp, 0);
848  }
849  }
850  }
851 
852  break;
853 
854  case event_PACKET:
855  nad = (nad_t) data;
856 
857  /* preauth */
858  if(comp->s->state == state_STREAM) {
859  /* non-legacy components can't do anything before auth */
860  if(!comp->legacy) {
861  log_debug(ZONE, "stream is preauth, dropping packet");
862  nad_free(nad);
863  return 0;
864  }
865 
866  /* watch for handshake requests */
867  if(NAD_ENAME_L(nad, 0) != 9 || strncmp("handshake", NAD_ENAME(nad, 0), NAD_ENAME_L(nad, 0)) != 0) {
868  log_debug(ZONE, "unknown preauth packet %.*s, dropping", NAD_ENAME_L(nad, 0), NAD_ENAME(nad, 0));
869 
870  nad_free(nad);
871  return 0;
872  }
873 
874  /* process incoming handshakes */
875  _router_process_handshake(comp, nad);
876 
877  return 0;
878  }
879 
880  /* legacy processing */
881  if(comp->legacy) {
882  log_debug(ZONE, "packet from legacy component, munging it");
883 
884  attr = nad_find_attr(nad, 0, -1, "to", NULL);
885  if(attr < 0 || (to = jid_reset(&sto, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
886  log_debug(ZONE, "invalid or missing 'to' address on legacy packet, dropping it");
887  nad_free(nad);
888  return 0;
889  }
890 
891  attr = nad_find_attr(nad, 0, -1, "from", NULL);
892  if(attr < 0 || (from = jid_reset(&sfrom, NAD_AVAL(nad, attr), NAD_AVAL_L(nad, attr))) == NULL) {
893  log_debug(ZONE, "invalid or missing 'from' address on legacy packet, dropping it");
894  nad_free(nad);
895  return 0;
896  }
897 
898  /* rewrite component packets into client packets */
899  ns = nad_find_namespace(nad, 0, "jabber:component:accept", NULL);
900  if(ns >= 0) {
901  if(nad->elems[0].ns == ns)
902  nad->elems[0].ns = nad->nss[nad->elems[0].ns].next;
903  else {
904  for(sns = nad->elems[0].ns; sns >= 0 && nad->nss[sns].next != ns; sns = nad->nss[sns].next);
905  nad->nss[sns].next = nad->nss[nad->nss[sns].next].next;
906  }
907  }
908 
909  ns = nad_find_namespace(nad, 0, uri_CLIENT, NULL);
910  if(ns < 0) {
911  ns = nad_add_namespace(nad, uri_CLIENT, NULL);
912  nad->scope = -1;
913  nad->nss[ns].next = nad->elems[0].ns;
914  nad->elems[0].ns = ns;
915  }
916  nad->elems[0].my_ns = ns;
917 
918  /* wrap up the packet */
919  ns = nad_add_namespace(nad, uri_COMPONENT, NULL);
920 
921  nad_wrap_elem(nad, 0, ns, "route");
922 
923  nad_set_attr(nad, 0, -1, "to", to->domain, 0);
924  nad_set_attr(nad, 0, -1, "from", from->domain, 0);
925  }
926 
927  /* top element must be router scoped */
928  if(NAD_ENS(nad, 0) < 0 || NAD_NURI_L(nad, NAD_ENS(nad, 0)) != strlen(uri_COMPONENT) || strncmp(uri_COMPONENT, NAD_NURI(nad, NAD_ENS(nad, 0)), strlen(uri_COMPONENT)) != 0) {
929  log_debug(ZONE, "invalid packet namespace, dropping");
930  nad_free(nad);
931  return 0;
932  }
933 
934  /* bind a name to this component */
935  if(NAD_ENAME_L(nad, 0) == 4 && strncmp("bind", NAD_ENAME(nad, 0), 4) == 0) {
936  _router_process_bind(comp, nad);
937  return 0;
938  }
939 
940  /* unbind a name from this component */
941  if(NAD_ENAME_L(nad, 0) == 6 && strncmp("unbind", NAD_ENAME(nad, 0), 6) == 0) {
942  _router_process_unbind(comp, nad);
943  return 0;
944  }
945 
946  /* route packets */
947  if(NAD_ENAME_L(nad, 0) == 5 && strncmp("route", NAD_ENAME(nad, 0), 5) == 0) {
948  _router_process_route(comp, nad);
949  return 0;
950  }
951 
952  /* throttle packets */
953  if(NAD_ENAME_L(nad, 0) == 8 && strncmp("throttle", NAD_ENAME(nad, 0), 8) == 0) {
954  _router_process_throttle(comp, nad);
955  return 0;
956  }
957 
958  log_debug(ZONE, "unknown packet, dropping");
959 
960  nad_free(nad);
961  return 0;
962 
963  case event_CLOSED:
964  {
965  /* close comp->fd by putting it in closefd ... unless it is already there */
966  _jqueue_node_t n;
967  for (n = comp->r->closefd->front; n != NULL; n = n->prev)
968  if (n->data == comp->fd) break;
969  if (!n) jqueue_push(comp->r->closefd, (void *) comp->fd, 0 /*priority*/);
970  return 0;
971  }
972  }
973 
974  return 0;
975 }
976 
977 static int _router_accept_check(router_t r, mio_fd_t fd, char *ip) {
978  rate_t rt;
979 
980  if(access_check(r->access, ip) == 0) {
981  log_write(r->log, LOG_NOTICE, "[%d] [%s] access denied by configuration", fd->fd, ip);
982  return 1;
983  }
984 
985  if(r->conn_rate_total != 0) {
986  rt = (rate_t) xhash_get(r->conn_rates, ip);
987  if(rt == NULL) {
989  xhash_put(r->conn_rates, pstrdup(xhash_pool(r->conn_rates), ip), (void *) rt);
990  }
991 
992  if(rate_check(rt) == 0) {
993  log_write(r->log, LOG_NOTICE, "[%d] [%s] is being rate limited", fd->fd, ip);
994  return 1;
995  }
996 
997  rate_add(rt, 1);
998  }
999 
1000  return 0;
1001 }
1002 
1003 static void _router_route_unbind_walker(const char *key, int keylen, void *val, void *arg) {
1004  component_t comp = (component_t) arg;
1005 
1006  char * local_key;
1007  xhash_zapx(comp->r->log_sinks, key, keylen);
1008  local_key = (char *) malloc(keylen + 1);
1009  memcpy(local_key, key, keylen);
1010  local_key[keylen] = 0;
1011  _route_remove(comp->r->routes, local_key, comp);
1012  xhash_zapx(comp->routes, key, keylen);
1013 
1014  if(comp->r->default_route != NULL && strlen(comp->r->default_route) == keylen && strncmp(key, comp->r->default_route, keylen) == 0) {
1015  log_write(comp->r->log, LOG_NOTICE, "[%.*s] default route offline", keylen, key);
1016  free(comp->r->default_route);
1017  comp->r->default_route = NULL;
1018  }
1019 
1020  log_write(comp->r->log, LOG_NOTICE, "[%.*s] offline", keylen, key);
1021 
1022  /* deadvertise name */
1023  if(xhash_getx(comp->r->routes, key, keylen) == NULL)
1024  _router_advertise(comp->r, local_key, comp, 1);
1025  free(local_key);
1026 }
1027 
1028 int router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg) {
1029  component_t comp = (component_t) arg;
1030  router_t r = (router_t) arg;
1031  struct sockaddr_storage sa;
1032  int namelen = sizeof(sa), port, nbytes;
1033 
1034  switch(a) {
1035  case action_READ:
1036  log_debug(ZONE, "read action on fd %d", fd->fd);
1037 
1038  /* they did something */
1039  comp->last_activity = time(NULL);
1040 
1041  ioctl(fd->fd, FIONREAD, &nbytes);
1042  if(nbytes == 0) {
1043  sx_kill(comp->s);
1044  return 0;
1045  }
1046 
1047  return sx_can_read(comp->s);
1048 
1049  case action_WRITE:
1050  log_debug(ZONE, "write action on fd %d", fd->fd);
1051 
1052  /* update activity timestamp */
1053  comp->last_activity = time(NULL);
1054 
1055  return sx_can_write(comp->s);
1056 
1057  case action_CLOSE:
1058  log_debug(ZONE, "close action on fd %d", fd->fd);
1059 
1060  r = comp->r;
1061 
1062  log_write(r->log, LOG_NOTICE, "[%s, port=%d] disconnect", comp->ip, comp->port);
1063 
1064  /* unbind names */
1065  xhash_walk(comp->routes, _router_route_unbind_walker, (void *) comp);
1066 
1067  /* deregister component */
1068  xhash_zap(r->components, comp->ipport);
1069 
1070  xhash_free(comp->routes);
1071 
1072  if(comp->tq != NULL)
1073  /* !!! bounce packets */
1074  jqueue_free(comp->tq);
1075 
1076  rate_free(comp->rate);
1077 
1078  jqueue_push(comp->r->dead, (void *) comp->s, 0);
1079 
1080  free(comp);
1081 
1082  break;
1083 
1084  case action_ACCEPT:
1085  log_debug(ZONE, "accept action on fd %d", fd->fd);
1086 
1087  getpeername(fd->fd, (struct sockaddr *) &sa, &namelen);
1088  port = j_inet_getport(&sa);
1089 
1090  log_write(r->log, LOG_NOTICE, "[%s, port=%d] connect", (char *) data, port);
1091 
1092  if(_router_accept_check(r, fd, (char *) data) != 0)
1093  return 1;
1094 
1095  comp = (component_t) calloc(1, sizeof(struct component_st));
1096 
1097  comp->r = r;
1098 
1099  comp->fd = fd;
1100 
1101  snprintf(comp->ip, INET6_ADDRSTRLEN, "%s", (char *) data);
1102  comp->port = port;
1103 
1104  snprintf(comp->ipport, INET6_ADDRSTRLEN, "%s:%d", comp->ip, comp->port);
1105 
1106  comp->s = sx_new(r->sx_env, fd->fd, _router_sx_callback, (void *) comp);
1107  mio_app(m, fd, router_mio_callback, (void *) comp);
1108 
1109  if(r->byte_rate_total != 0)
1111 
1112  comp->routes = xhash_new(51);
1113 
1114  /* register component */
1115  log_debug(ZONE, "new component (%p) \"%s\"", comp, comp->ipport);
1116  xhash_put(r->components, comp->ipport, (void *) comp);
1117 
1118 #ifdef HAVE_SSL
1120 #else
1121  sx_server_init(comp->s, SX_SASL_OFFER);
1122 #endif
1123 
1124  break;
1125  }
1126 
1127  return 0;
1128 }
1129 
1130 
1131 int message_log(nad_t nad, router_t r, const unsigned char *msg_from, const unsigned char *msg_to)
1132 {
1133  time_t t;
1134  char *time_pos;
1135  int time_sz;
1136  struct stat filestat;
1137  FILE *message_file;
1138  short int new_msg_file = 0;
1139  int i;
1140  int nad_body_len = 0;
1141  long int nad_body_start = 0;
1142  int body_count;
1143  char *nad_body = NULL;
1144  char body[MAX_MESSAGE*2];
1145 
1146  assert((int) (nad != NULL));
1147 
1148  /* timestamp */
1149  t = time(NULL);
1150  time_pos = ctime(&t);
1151  time_sz = strlen(time_pos);
1152  /* chop off the \n */
1153  time_pos[time_sz-1]=' ';
1154 
1155  // Find the message body
1156  for (i = 0; NAD_ENAME_L(nad, i) > 0; i++)
1157  {
1158  if((NAD_ENAME_L(nad, i) == 4) && (strncmp("body", NAD_ENAME(nad, i), 4) == 0))
1159  {
1160  nad_body_len = NAD_CDATA_L(nad, i);
1161  if (nad_body_len > 0) {
1162  nad_body = NAD_CDATA(nad, i);
1163  } else {
1164  log_write(r->log, LOG_NOTICE, "message_log received a message with empty body");
1165  return 0;
1166  }
1167  break;
1168  }
1169  }
1170 
1171  // Don't log anything if we found no NAD body
1172  if (nad_body == NULL) {
1173  return 0;
1174  }
1175 
1176  // Store original pointer address so that we know when to stop iterating through nad_body
1177  nad_body_start = nad_body;
1178 
1179  // replace line endings with "\n"
1180  for (body_count = 0; (nad_body < nad_body_start + nad_body_len) && (body_count < (MAX_MESSAGE*2)-3); nad_body++) {
1181  if (*nad_body == '\n') {
1182  body[body_count++] = '\\';
1183  body[body_count++] = 'n';
1184  } else {
1185  body[body_count++] = *nad_body;
1186  }
1187  }
1188  body[body_count] = '\0';
1189 
1190  // Log our message
1191  umask((mode_t) 0077);
1192  if (stat(r->message_logging_file, &filestat)) {
1193  new_msg_file = 1;
1194  }
1195 
1196  if ((message_file = fopen(r->message_logging_file, "a")) == NULL)
1197  {
1198  log_write(r->log, LOG_ERR, "Unable to open message log for writing: %s", strerror(errno));
1199  return 1;
1200  }
1201 
1202  if (new_msg_file) {
1203  if (! fprintf(message_file, "# This message log is created by the jabberd router.\n"))
1204  {
1205  log_write(r->log, LOG_ERR, "Unable to write to message log: %s", strerror(errno));
1206  return 1;
1207  }
1208  fprintf(message_file, "# See router.xml for logging options.\n");
1209  fprintf(message_file, "# Format: (Date)<tab>(From JID)<tab>(To JID)<tab>(Message Body)<line end>\n");
1210  }
1211 
1212  if (! fprintf(message_file, "%s\t%s\t%s\t%s\n", time_pos, msg_from, msg_to, body))
1213  {
1214  log_write(r->log, LOG_ERR, "Unable to write to message log: %s", strerror(errno));
1215  return 1;
1216  }
1217 
1218  fclose(message_file);
1219 
1220  return 0;
1221 }