jabberd2  2.3.4
main.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 "c2s.h"
22 
23 #include <stringprep.h>
24 
25 static sig_atomic_t c2s_shutdown = 0;
26 sig_atomic_t c2s_lost_router = 0;
27 static sig_atomic_t c2s_logrotate = 0;
28 static sig_atomic_t c2s_sighup = 0;
29 
30 static void _c2s_signal(int signum)
31 {
32  c2s_shutdown = 1;
33  c2s_lost_router = 0;
34 }
35 
36 static void _c2s_signal_hup(int signum)
37 {
38  c2s_logrotate = 1;
39  c2s_sighup = 1;
40 }
41 
42 static void _c2s_signal_usr1(int signum)
43 {
44  set_debug_flag(0);
45 }
46 
47 static void _c2s_signal_usr2(int signum)
48 {
49  set_debug_flag(1);
50 }
51 
53 static void _c2s_pidfile(c2s_t c2s) {
54  const char *pidfile;
55  FILE *f;
56  pid_t pid;
57 
58  pidfile = config_get_one(c2s->config, "pidfile", 0);
59  if(pidfile == NULL)
60  return;
61 
62  pid = getpid();
63 
64  if((f = fopen(pidfile, "w+")) == NULL) {
65  log_write(c2s->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno));
66  return;
67  }
68 
69  if(fprintf(f, "%d", pid) < 0) {
70  log_write(c2s->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno));
71  fclose(f);
72  return;
73  }
74 
75  fclose(f);
76 
77  log_write(c2s->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile);
78 }
80 static void _c2s_config_expand(c2s_t c2s)
81 {
82  const char *str, *ip, *mask;
83  char *req_domain, *to_address, *to_port;
84  config_elem_t elem;
85  int i;
87 
89 
90  c2s->id = config_get_one(c2s->config, "id", 0);
91  if(c2s->id == NULL)
92  c2s->id = "c2s";
93 
94  c2s->router_ip = config_get_one(c2s->config, "router.ip", 0);
95  if(c2s->router_ip == NULL)
96  c2s->router_ip = "127.0.0.1";
97 
98  c2s->router_port = j_atoi(config_get_one(c2s->config, "router.port", 0), 5347);
99 
100  c2s->router_user = config_get_one(c2s->config, "router.user", 0);
101  if(c2s->router_user == NULL)
102  c2s->router_user = "jabberd";
103  c2s->router_pass = config_get_one(c2s->config, "router.pass", 0);
104  if(c2s->router_pass == NULL)
105  c2s->router_pass = "secret";
106 
107  c2s->router_pemfile = config_get_one(c2s->config, "router.pemfile", 0);
108 
109  c2s->router_cachain = config_get_one(c2s->config, "router.cachain", 0);
110 
111  c2s->router_private_key_password = config_get_one(c2s->config, "router.private_key_password", 0);
112  c2s->router_ciphers = config_get_one(c2s->config, "router.ciphers", 0);
113 
114  c2s->retry_init = j_atoi(config_get_one(c2s->config, "router.retry.init", 0), 3);
115  c2s->retry_lost = j_atoi(config_get_one(c2s->config, "router.retry.lost", 0), 3);
116  if((c2s->retry_sleep = j_atoi(config_get_one(c2s->config, "router.retry.sleep", 0), 2)) < 1)
117  c2s->retry_sleep = 1;
118 
119  c2s->log_type = log_STDOUT;
120  if(config_get(c2s->config, "log") != NULL) {
121  if((str = config_get_attr(c2s->config, "log", 0, "type")) != NULL) {
122  if(strcmp(str, "file") == 0)
123  c2s->log_type = log_FILE;
124  else if(strcmp(str, "syslog") == 0)
125  c2s->log_type = log_SYSLOG;
126  }
127  }
128 
129  if(c2s->log_type == log_SYSLOG) {
130  c2s->log_facility = config_get_one(c2s->config, "log.facility", 0);
131  c2s->log_ident = config_get_one(c2s->config, "log.ident", 0);
132  if(c2s->log_ident == NULL)
133  c2s->log_ident = "jabberd/c2s";
134  } else if(c2s->log_type == log_FILE)
135  c2s->log_ident = config_get_one(c2s->config, "log.file", 0);
136 
137  c2s->packet_stats = config_get_one(c2s->config, "stats.packet", 0);
138 
139  c2s->local_ip = config_get_one(c2s->config, "local.ip", 0);
140  if(c2s->local_ip == NULL)
141  c2s->local_ip = "0.0.0.0";
142 
143  c2s->local_port = j_atoi(config_get_one(c2s->config, "local.port", 0), 0);
144 
145  c2s->local_pemfile = config_get_one(c2s->config, "local.pemfile", 0);
146 
147  c2s->local_cachain = config_get_one(c2s->config, "local.cachain", 0);
148 
149  c2s->local_private_key_password = config_get_one(c2s->config, "local.private_key_password", 0);
150 
151  c2s->local_verify_mode = j_atoi(config_get_one(c2s->config, "local.verify-mode", 0), 0);
152 
153  c2s->local_ciphers = config_get_one(c2s->config, "local.ciphers", 0);
154 
155  c2s->local_ssl_port = j_atoi(config_get_one(c2s->config, "local.ssl-port", 0), 0);
156 
157  c2s->http_forward = config_get_one(c2s->config, "local.httpforward", 0);
158 
159  c2s->websocket = (config_get(c2s->config, "io.websocket") != NULL);
160 
161  c2s->io_max_fds = j_atoi(config_get_one(c2s->config, "io.max_fds", 0), 1024);
162 
163  c2s->compression = (config_get(c2s->config, "io.compression") != NULL);
164 
165  c2s->io_check_interval = j_atoi(config_get_one(c2s->config, "io.check.interval", 0), 0);
166  c2s->io_check_idle = j_atoi(config_get_one(c2s->config, "io.check.idle", 0), 0);
167  c2s->io_check_keepalive = j_atoi(config_get_one(c2s->config, "io.check.keepalive", 0), 0);
168 
169  c2s->pbx_pipe = config_get_one(c2s->config, "pbx.pipe", 0);
170 
171  elem = config_get(c2s->config, "stream_redirect.redirect");
172  if(elem != NULL)
173  {
174  for(i = 0; i < elem->nvalues; i++)
175  {
177  if(!sr) {
178  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting");
179  exit(1);
180  }
181  req_domain = j_attr((const char **) elem->attrs[i], "requested_domain");
182  to_address = j_attr((const char **) elem->attrs[i], "to_address");
183  to_port = j_attr((const char **) elem->attrs[i], "to_port");
184 
185  if(req_domain == NULL || to_address == NULL || to_port == NULL) {
186  log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping");
187  continue;
188  }
189 
190  // Note that to_address should be RFC 3986 compliant
191  sr->to_address = to_address;
192  sr->to_port = to_port;
193 
194  xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr);
195  }
196  }
197 
198  c2s->ar_module_name = config_get_one(c2s->config, "authreg.module", 0);
199 
200  if(config_get(c2s->config, "authreg.mechanisms.traditional.plain") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_PLAIN;
201  if(config_get(c2s->config, "authreg.mechanisms.traditional.digest") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_DIGEST;
202  if(config_get(c2s->config, "authreg.mechanisms.traditional.cram-md5") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_CRAMMD5;
203 
204  if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.plain") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_PLAIN;
205  if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.digest") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_DIGEST;
206  if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.cram-md5") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_CRAMMD5;
207 
208  elem = config_get(c2s->config, "io.limits.bytes");
209  if(elem != NULL)
210  {
211  c2s->byte_rate_total = j_atoi(elem->values[0], 0);
212  if(c2s->byte_rate_total != 0)
213  {
214  c2s->byte_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 1);
215  c2s->byte_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);
216  }
217  }
218 
219  elem = config_get(c2s->config, "io.limits.stanzas");
220  if(elem != NULL)
221  {
222  c2s->stanza_rate_total = j_atoi(elem->values[0], 0);
223  if(c2s->stanza_rate_total != 0)
224  {
225  c2s->stanza_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 1);
226  c2s->stanza_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);
227  }
228  }
229 
230  elem = config_get(c2s->config, "io.limits.connects");
231  if(elem != NULL)
232  {
233  c2s->conn_rate_total = j_atoi(elem->values[0], 0);
234  if(c2s->conn_rate_total != 0)
235  {
236  c2s->conn_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5);
237  c2s->conn_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5);
238  }
239  }
240 
241  c2s->stanza_size_limit = j_atoi(config_get_one(c2s->config, "io.limits.stanzasize", 0), 0);
242 
243  /* tweak timed checks with rate times */
244  if(c2s->io_check_interval == 0) {
245  if(c2s->byte_rate_total != 0)
246  c2s->io_check_interval = c2s->byte_rate_wait;
247 
248  if(c2s->stanza_rate_total != 0 && c2s->io_check_interval > c2s->stanza_rate_wait)
250  }
251 
252  str = config_get_one(c2s->config, "io.access.order", 0);
253  if(str == NULL || strcmp(str, "deny,allow") != 0)
254  c2s->access = access_new(0);
255  else
256  c2s->access = access_new(1);
257 
258  elem = config_get(c2s->config, "io.access.allow");
259  if(elem != NULL)
260  {
261  for(i = 0; i < elem->nvalues; i++)
262  {
263  ip = j_attr((const char **) elem->attrs[i], "ip");
264  mask = j_attr((const char **) elem->attrs[i], "mask");
265 
266  if(ip == NULL)
267  continue;
268 
269  if(mask == NULL)
270  mask = "255.255.255.255";
271 
272  access_allow(c2s->access, ip, mask);
273  }
274  }
275 
276  elem = config_get(c2s->config, "io.access.deny");
277  if(elem != NULL)
278  {
279  for(i = 0; i < elem->nvalues; i++)
280  {
281  ip = j_attr((const char **) elem->attrs[i], "ip");
282  mask = j_attr((const char **) elem->attrs[i], "mask");
283 
284  if(ip == NULL)
285  continue;
286 
287  if(mask == NULL)
288  mask = "255.255.255.255";
289 
290  access_deny(c2s->access, ip, mask);
291  }
292  }
293 }
294 
295 static void _c2s_hosts_expand(c2s_t c2s)
296 {
297  char *realm;
298  config_elem_t elem;
299  char id[1024];
300  int i;
301 
302  elem = config_get(c2s->config, "local.id");
303  if(!elem) {
304  log_write(c2s->log, LOG_NOTICE, "no local.id configured - skipping local domains configuration");
305  return;
306  }
307  for(i = 0; i < elem->nvalues; i++) {
308  host_t host = (host_t) pmalloco(xhash_pool(c2s->hosts), sizeof(struct host_st));
309  if(!host) {
310  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new host, aborting");
311  exit(1);
312  }
313 
314  realm = j_attr((const char **) elem->attrs[i], "realm");
315 
316  /* stringprep ids (domain names) so that they are in canonical form */
317  strncpy(id, elem->values[i], 1024);
318  id[1023] = '\0';
319  if (stringprep_nameprep(id, 1024) != 0) {
320  log_write(c2s->log, LOG_ERR, "cannot stringprep id %s, aborting", id);
321  exit(1);
322  }
323 
324  host->realm = (realm != NULL) ? realm : pstrdup(xhash_pool(c2s->hosts), id);
325 
326  host->host_pemfile = j_attr((const char **) elem->attrs[i], "pemfile");
327 
328  host->host_cachain = j_attr((const char **) elem->attrs[i], "cachain");
329 
330  host->host_verify_mode = j_atoi(j_attr((const char **) elem->attrs[i], "verify-mode"), 0);
331 
332  host->host_private_key_password = j_attr((const char **) elem->attrs[i], "private-key-password");
333 
334  host->host_ciphers = j_attr((const char **) elem->attrs[i], "ciphers");
335 
336 #ifdef HAVE_SSL
337  if(host->host_pemfile != NULL) {
338  if(c2s->sx_ssl == NULL) {
340  if(c2s->sx_ssl == NULL) {
341  log_write(c2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm);
342  host->host_pemfile = NULL;
343  }
344  } else {
345  if(sx_ssl_server_addcert(c2s->sx_ssl, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode, host->host_private_key_password, host->host_ciphers) != 0) {
346  log_write(c2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm);
347  host->host_pemfile = NULL;
348  }
349  }
350  }
351 #endif
352 
353  host->host_require_starttls = (j_attr((const char **) elem->attrs[i], "require-starttls") != NULL);
354 
355  host->ar_module_name = j_attr((const char **) elem->attrs[i], "authreg-module");
356  if(host->ar_module_name) {
357  if((host->ar = authreg_init(c2s, host->ar_module_name)) == NULL) {
358  log_write(c2s->log, LOG_NOTICE, "failed to load %s authreg module - using default", host->realm);
359  host->ar = c2s->ar;
360  }
361  } else
362  host->ar = c2s->ar;
363 
364  host->ar_register_enable = (j_attr((const char **) elem->attrs[i], "register-enable") != NULL);
365  host->ar_register_oob = j_attr((const char **) elem->attrs[i], "register-oob");
366  if(host->ar_register_enable || host->ar_register_oob) {
367  host->ar_register_instructions = j_attr((const char **) elem->attrs[i], "instructions");
368  if(host->ar_register_instructions == NULL) {
369  if(host->ar_register_oob)
370  host->ar_register_instructions = "Only web based registration is possible with this server.";
371  else
372  host->ar_register_instructions = "Enter a username and password to register with this server.";
373  }
374  } else
375  host->ar_register_password = (j_attr((const char **) elem->attrs[i], "password-change") != NULL);
376 
377  /* check for empty <id/> CDATA - XXX this "1" is VERY config.c dependant !!! */
378  if(! strcmp(id, "1")) {
379  /* remove the realm even if set */
380  host->realm = NULL;
381 
382  /* skip if vHost already configured */
383  if(! c2s->vhost)
384  c2s->vhost = host;
385 
386  /* add meaningful log "id" */
387  strcpy(id, "default vHost");
388  } else {
389  /* insert into vHosts xhash */
390  xhash_put(c2s->hosts, pstrdup(xhash_pool(c2s->hosts), id), host);
391  }
392 
393  log_write(c2s->log, LOG_NOTICE, "[%s] configured; realm=%s, authreg=%s, registration %s, using PEM:%s",
394  id, (host->realm != NULL ? host->realm : "no realm set"),
395  (host->ar_module_name ? host->ar_module_name : c2s->ar_module_name),
396  (host->ar_register_enable ? "enabled" : "disabled"),
397  (host->host_pemfile ? host->host_pemfile : "Default"));
398  }
399 }
400 
401 static int _c2s_router_connect(c2s_t c2s) {
402  log_write(c2s->log, LOG_NOTICE, "attempting connection to router at %s, port=%d", c2s->router_ip, c2s->router_port);
403 
404  c2s->fd = mio_connect(c2s->mio, c2s->router_port, c2s->router_ip, NULL, c2s_router_mio_callback, (void *) c2s);
405  if(c2s->fd == NULL) {
406  if(errno == ECONNREFUSED)
407  c2s_lost_router = 1;
408  log_write(c2s->log, LOG_NOTICE, "connection attempt to router failed: %s (%d)", MIO_STRERROR(MIO_ERROR), MIO_ERROR);
409  return 1;
410  }
411 
412  c2s->router = sx_new(c2s->sx_env, c2s->fd->fd, c2s_router_sx_callback, (void *) c2s);
413  sx_client_init(c2s->router, 0, NULL, NULL, NULL, "1.0");
414 
415  return 0;
416 }
417 
418 static int _c2s_sx_sasl_callback(int cb, void *arg, void **res, sx_t s, void *cbarg) {
419  c2s_t c2s = (c2s_t) cbarg;
420  const char *my_realm, *mech;
421  sx_sasl_creds_t creds;
422  static char buf[3072];
423  char mechbuf[256];
424  struct jid_st jid;
425  jid_static_buf jid_buf;
426  int i, r;
427  sess_t sess;
428  char skey[44];
429  host_t host;
430 
431  /* init static jid */
432  jid_static(&jid,&jid_buf);
433 
434  /* retrieve our session */
435  assert(s != NULL);
436  sprintf(skey, "%d", s->tag);
437 
438  /*
439  * Retrieve the session, note that depending on the operation,
440  * session may be null.
441  */
442  sess = xhash_get(c2s->sessions, skey);
443 
444  switch(cb) {
446 
447  if(s->req_to == NULL) /* this shouldn't happen */
448  my_realm = "";
449 
450  else {
451  /* get host for request */
452  host = xhash_get(c2s->hosts, s->req_to);
453  if(host == NULL) {
454  log_write(c2s->log, LOG_ERR, "SASL callback for non-existing host: %s", s->req_to);
455  *res = (void *)NULL;
456  return sx_sasl_ret_FAIL;
457  }
458 
459  my_realm = host->realm;
460  if(my_realm == NULL)
461  my_realm = s->req_to;
462  }
463 
464  strncpy(buf, my_realm, 256);
465  *res = (void *)buf;
466 
467  log_debug(ZONE, "sx sasl callback: get realm: realm is '%s'", buf);
468  return sx_sasl_ret_OK;
469  break;
470 
471  case sx_sasl_cb_GET_PASS:
472  assert(sess != NULL);
473  creds = (sx_sasl_creds_t) arg;
474 
475  log_debug(ZONE, "sx sasl callback: get pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);
476 
477  if(sess->host->ar->get_password && (sess->host->ar->get_password)(
478  sess->host->ar, sess, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm: "", buf) == 0) {
479  *res = buf;
480  return sx_sasl_ret_OK;
481  }
482 
483  return sx_sasl_ret_FAIL;
484 
486  assert(sess != NULL);
487  creds = (sx_sasl_creds_t) arg;
488 
489  log_debug(ZONE, "sx sasl callback: check pass (authnid=%s, realm=%s)", creds->authnid, creds->realm);
490 
491  if(sess->host->ar->check_password != NULL) {
492  if ((sess->host->ar->check_password)(
493  sess->host->ar, sess, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm : "", (char *)creds->pass) == 0)
494  return sx_sasl_ret_OK;
495  else
496  return sx_sasl_ret_FAIL;
497  }
498 
499  if(sess->host->ar->get_password != NULL) {
500  if ((sess->host->ar->get_password)(sess->host->ar, sess, (char *)creds->authnid, (creds->realm != NULL) ? (char *)creds->realm : "", buf) != 0)
501  return sx_sasl_ret_FAIL;
502 
503  if (strcmp(creds->pass, buf)==0)
504  return sx_sasl_ret_OK;
505  }
506 
507  return sx_sasl_ret_FAIL;
508  break;
509 
511  assert(sess != NULL);
512  creds = (sx_sasl_creds_t) arg;
513 
514  /* we need authzid to validate */
515  if(creds->authzid == NULL || creds->authzid[0] == '\0')
516  return sx_sasl_ret_FAIL;
517 
518  /* authzid must be a valid jid */
519  if(jid_reset(&jid, creds->authzid, -1) == NULL)
520  return sx_sasl_ret_FAIL;
521 
522  /* and have domain == stream to addr */
523  if(!s->req_to || (strcmp(jid.domain, s->req_to) != 0))
524  return sx_sasl_ret_FAIL;
525 
526  /* and have no resource */
527  if(jid.resource[0] != '\0')
528  return sx_sasl_ret_FAIL;
529 
530  /* and user has right to authorize as */
531  if (sess->host->ar->user_authz_allowed) {
532  if (sess->host->ar->user_authz_allowed(sess->host->ar, sess, (char *)creds->authnid, (char *)creds->realm, (char *)creds->authzid))
533  return sx_sasl_ret_OK;
534  } else {
535  if (strcmp(creds->authnid, jid.node) == 0 &&
536  (sess->host->ar->user_exists)(sess->host->ar, sess, jid.node, jid.domain))
537  return sx_sasl_ret_OK;
538  }
539 
540  return sx_sasl_ret_FAIL;
541 
543  /* generate a jid for SASL ANONYMOUS */
544  jid_reset(&jid, s->req_to, -1);
545 
546  /* make node a random string */
547  jid_random_part(&jid, jid_NODE);
548 
549  strcpy(buf, jid.node);
550 
551  *res = (void *)buf;
552 
553  return sx_sasl_ret_OK;
554  break;
555 
557  mech = (char *)arg;
558 
559  i=0;
560  while(i<sizeof(mechbuf) && mech[i]!='\0') {
561  mechbuf[i]=tolower(mech[i]);
562  i++;
563  }
564  mechbuf[i]='\0';
565 
566  /* get host for request */
567  host = xhash_get(c2s->hosts, s->req_to);
568  if(host == NULL) {
569  log_write(c2s->log, LOG_WARNING, "SASL callback for non-existing host: %s", s->req_to);
570  return sx_sasl_ret_FAIL;
571  }
572 
573  /* Determine if our configuration will let us use this mechanism.
574  * We support different mechanisms for both SSL and normal use */
575  if (strcmp(mechbuf, "digest-md5") == 0) {
576  /* digest-md5 requires that our authreg support get_password */
577  if (host->ar->get_password == NULL)
578  return sx_sasl_ret_FAIL;
579  } else if (strcmp(mechbuf, "plain") == 0) {
580  /* plain requires either get_password or check_password */
581  if (host->ar->get_password == NULL && host->ar->check_password == NULL)
582  return sx_sasl_ret_FAIL;
583  }
584 
585  /* Using SSF is potentially dangerous, as SASL can also set the
586  * SSF of the connection. However, SASL shouldn't do so until after
587  * we've finished mechanism establishment
588  */
589  if (s->ssf>0) {
590  r = snprintf(buf, sizeof(buf), "authreg.ssl-mechanisms.sasl.%s",mechbuf);
591  if (r < -1 || r > sizeof(buf))
592  return sx_sasl_ret_FAIL;
593  if(config_get(c2s->config,buf) != NULL)
594  return sx_sasl_ret_OK;
595  }
596 
597  r = snprintf(buf, sizeof(buf), "authreg.mechanisms.sasl.%s",mechbuf);
598  if (r < -1 || r > sizeof(buf))
599  return sx_sasl_ret_FAIL;
600 
601  /* Work out if our configuration will let us use this mechanism */
602  if(config_get(c2s->config,buf) != NULL)
603  return sx_sasl_ret_OK;
604  else
605  return sx_sasl_ret_FAIL;
606  default:
607  break;
608  }
609 
610  return sx_sasl_ret_FAIL;
611 }
612 static void _c2s_time_checks(c2s_t c2s) {
613  sess_t sess;
614  time_t now;
615  union xhashv xhv;
616 
617  now = time(NULL);
618 
619  if(xhash_iter_first(c2s->sessions))
620  do {
621  xhv.sess_val = &sess;
622  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
623 
624  if(c2s->io_check_idle > 0 && sess->s && now > sess->last_activity + c2s->io_check_idle) {
625  log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] timed out", sess->fd->fd, sess->ip, sess->port);
626 
627  sx_error(sess->s, stream_err_HOST_GONE, "connection timed out");
628  sx_close(sess->s);
629 
630  continue;
631  }
632 
633  if(c2s->io_check_keepalive > 0 && now > sess->last_activity + c2s->io_check_keepalive && sess->s->state >= state_STREAM) {
634  log_debug(ZONE, "sending keepalive for %d", sess->fd->fd);
635 
636  sx_raw_write(sess->s, " ", 1);
637  }
638 
639  if(sess->rate != NULL && sess->rate->bad != 0 && rate_check(sess->rate) != 0) {
640  /* read the pending bytes when rate limit is no longer in effect */
641  log_debug(ZONE, "reading throttled %d", sess->fd->fd);
642  sess->s->want_read = 1;
643  sx_can_read(sess->s);
644  }
645 
646  } while(xhash_iter_next(c2s->sessions));
647 }
648 
649 static void _c2s_ar_free(const char *module, int modulelen, void *val, void *arg) {
650  authreg_t ar = (authreg_t) val;
651  authreg_free(ar);
652 }
653 
654 JABBER_MAIN("jabberd2c2s", "Jabber 2 C2S", "Jabber Open Source Server: Client to Server", "jabberd2router\0")
655 {
656  c2s_t c2s;
657  char *config_file;
658  int optchar;
659  int mio_timeout;
660  sess_t sess;
661  bres_t res;
662  union xhashv xhv;
663  time_t check_time = 0;
664  const char *cli_id = 0;
665 
666 #ifdef HAVE_UMASK
667  umask((mode_t) 0027);
668 #endif
669 
670  srand(time(NULL));
671 
672 #ifdef HAVE_WINSOCK2_H
673 /* get winsock running */
674  {
675  WORD wVersionRequested;
676  WSADATA wsaData;
677  int err;
678 
679  wVersionRequested = MAKEWORD( 2, 2 );
680 
681  err = WSAStartup( wVersionRequested, &wsaData );
682  if ( err != 0 ) {
683  /* !!! tell user that we couldn't find a usable winsock dll */
684  return 0;
685  }
686  }
687 #endif
688 
689  jabber_signal(SIGINT, _c2s_signal);
690  jabber_signal(SIGTERM, _c2s_signal);
691 #ifdef SIGHUP
693 #endif
694 #ifdef SIGPIPE
695  jabber_signal(SIGPIPE, SIG_IGN);
696 #endif
699 
700 
701  c2s = (c2s_t) calloc(1, sizeof(struct c2s_st));
702 
703  /* load our config */
704  c2s->config = config_new();
705 
706  config_file = CONFIG_DIR "/c2s.xml";
707 
708  /* cmdline parsing */
709  while((optchar = getopt(argc, argv, "Dc:hi:?")) >= 0)
710  {
711  switch(optchar)
712  {
713  case 'c':
714  config_file = optarg;
715  break;
716  case 'D':
717 #ifdef DEBUG
718  set_debug_flag(1);
719 #else
720  printf("WARN: Debugging not enabled. Ignoring -D.\n");
721 #endif
722  break;
723  case 'i':
724  cli_id = optarg;
725  break;
726  case 'h': case '?': default:
727  fputs(
728  "c2s - jabberd client-to-server connector (" VERSION ")\n"
729  "Usage: c2s <options>\n"
730  "Options are:\n"
731  " -c <config> config file to use [default: " CONFIG_DIR "/c2s.xml]\n"
732  " -i id Override <id> config element\n"
733 #ifdef DEBUG
734  " -D Show debug output\n"
735 #endif
736  ,
737  stdout);
738  config_free(c2s->config);
739  free(c2s);
740  return 1;
741  }
742  }
743 
744  if(config_load_with_id(c2s->config, config_file, cli_id) != 0)
745  {
746  fputs("c2s: couldn't load config, aborting\n", stderr);
747  config_free(c2s->config);
748  free(c2s);
749  return 2;
750  }
751 
752  c2s->stream_redirects = xhash_new(11);
753 
754  _c2s_config_expand(c2s);
755 
756  c2s->ar_modules = xhash_new(5);
757  if(c2s->ar_module_name == NULL) {
758  log_write(c2s->log, LOG_NOTICE, "no default authreg module specified in config file");
759  }
760  else if((c2s->ar = authreg_init(c2s, c2s->ar_module_name)) == NULL) {
761  access_free(c2s->access);
762  config_free(c2s->config);
763  log_free(c2s->log);
764  free(c2s);
765  exit(1);
766  }
767 
768  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
769  log_write(c2s->log, LOG_NOTICE, "starting up");
770 
771  _c2s_pidfile(c2s);
772 
773  c2s->sessions = xhash_new(1023);
774 
775  c2s->conn_rates = xhash_new(101);
776 
777  c2s->dead = jqueue_new();
778 
779  c2s->dead_sess = jqueue_new();
780 
781  c2s->sx_env = sx_env_new();
782 
783 #ifdef USE_WEBSOCKET
784  /* possibly wrap in websocket */
785  if(c2s->websocket) {
787  }
788 #else
789  if(c2s->http_forward) {
790  log_write(c2s->log, LOG_ERR, "httpforward available only with websocket support built-in");
791  }
792 #endif
793 
794 #ifdef HAVE_SSL
795  /* get the ssl context up and running */
796  if(c2s->local_pemfile != NULL) {
798  if(c2s->sx_ssl == NULL) {
799  log_write(c2s->log, LOG_ERR, "failed to load local SSL pemfile, SSL will not be available to clients");
800  c2s->local_pemfile = NULL;
801  }
802  }
803 
804  /* try and get something online, so at least we can encrypt to the router */
805  if(c2s->sx_ssl == NULL && c2s->router_pemfile != NULL) {
807  if(c2s->sx_ssl == NULL) {
808  log_write(c2s->log, LOG_ERR, "failed to load router SSL pemfile, channel to router will not be SSL encrypted");
809  c2s->router_pemfile = NULL;
810  }
811  }
812 #endif
813 
814 #ifdef HAVE_LIBZ
815  /* get compression up and running */
816  if(c2s->compression)
818 #endif
819 
820  /* get stanza ack up */
822 
823  /* and user IP address plugin */
825 
826  /* get sasl online */
827  c2s->sx_sasl = sx_env_plugin(c2s->sx_env, sx_sasl_init, "xmpp", _c2s_sx_sasl_callback, (void *) c2s);
828  if(c2s->sx_sasl == NULL) {
829  log_write(c2s->log, LOG_ERR, "failed to initialise SASL context, aborting");
830  exit(1);
831  }
832 
833  /* get bind up */
834  sx_env_plugin(c2s->sx_env, bind_init, c2s);
835 
836  c2s->mio = mio_new(c2s->io_max_fds);
837  if(c2s->mio == NULL) {
838  log_write(c2s->log, LOG_ERR, "failed to create MIO, aborting");
839  exit(1);
840  }
841 
842  /* hosts mapping */
843  c2s->hosts = xhash_new(1021);
844  _c2s_hosts_expand(c2s);
845  c2s->sm_avail = xhash_new(1021);
846 
847  c2s->retry_left = c2s->retry_init;
848  _c2s_router_connect(c2s);
849 
850  mio_timeout = ((c2s->io_check_interval != 0 && c2s->io_check_interval < 5) ?
851  c2s->io_check_interval : 5);
852 
853  while(!c2s_shutdown) {
854  mio_run(c2s->mio, mio_timeout);
855 
856  if(c2s_logrotate) {
858 
859  log_write(c2s->log, LOG_NOTICE, "reopening log ...");
860  log_free(c2s->log);
861  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
862  log_write(c2s->log, LOG_NOTICE, "log started");
863 
864  c2s_logrotate = 0;
865  }
866 
867  if(c2s_sighup) {
868  log_write(c2s->log, LOG_NOTICE, "reloading some configuration items ...");
869  config_t conf;
870  conf = config_new();
871  if (conf && config_load(conf, config_file) == 0) {
873  c2s->stream_redirects = xhash_new(11);
874 
875  char *req_domain, *to_address, *to_port;
876  config_elem_t elem;
877  int i;
879 
880  elem = config_get(conf, "stream_redirect.redirect");
881  if(elem != NULL)
882  {
883  for(i = 0; i < elem->nvalues; i++)
884  {
886  if(!sr) {
887  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting");
888  exit(1);
889  }
890  req_domain = j_attr((const char **) elem->attrs[i], "requested_domain");
891  to_address = j_attr((const char **) elem->attrs[i], "to_address");
892  to_port = j_attr((const char **) elem->attrs[i], "to_port");
893 
894  if(req_domain == NULL || to_address == NULL || to_port == NULL) {
895  log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping");
896  continue;
897  }
898 
899  // Note that to_address should be RFC 3986 compliant
900  sr->to_address = to_address;
901  sr->to_port = to_port;
902 
903  xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr);
904  }
905  }
906  config_free(conf);
907  } else {
908  log_write(c2s->log, LOG_WARNING, "couldn't reload config (%s)", config_file);
909  if (conf) config_free(conf);
910  }
911  c2s_sighup = 0;
912  }
913 
914  if(c2s_lost_router) {
915  if(c2s->retry_left < 0) {
916  log_write(c2s->log, LOG_NOTICE, "attempting reconnect");
917  sleep(c2s->retry_sleep);
918  c2s_lost_router = 0;
919  if (c2s->router) sx_free(c2s->router);
920  _c2s_router_connect(c2s);
921  }
922 
923  else if(c2s->retry_left == 0) {
924  c2s_shutdown = 1;
925  }
926 
927  else {
928  log_write(c2s->log, LOG_NOTICE, "attempting reconnect (%d left)", c2s->retry_left);
929  c2s->retry_left--;
930  sleep(c2s->retry_sleep);
931  c2s_lost_router = 0;
932  if (c2s->router) sx_free(c2s->router);
933  _c2s_router_connect(c2s);
934  }
935  }
936 
937  /* cleanup dead sess (before sx_t as sess->result uses sx_t nad cache) */
938  while(jqueue_size(c2s->dead_sess) > 0) {
939  sess = (sess_t) jqueue_pull(c2s->dead_sess);
940 
941  /* free sess data */
942  if(sess->ip != NULL) free((void*)sess->ip);
943  if(sess->smcomp != NULL) free((void*)sess->smcomp);
944  if(sess->result != NULL) nad_free(sess->result);
945  if(sess->resources != NULL)
946  for(res = sess->resources; res != NULL;) {
947  bres_t tmp = res->next;
948  jid_free(res->jid);
949  free(res);
950  res = tmp;
951  }
952  if(sess->rate != NULL) rate_free(sess->rate);
953  if(sess->stanza_rate != NULL) rate_free(sess->stanza_rate);
954 
955  free(sess);
956  }
957 
958  /* cleanup dead sx_ts */
959  while(jqueue_size(c2s->dead) > 0)
960  sx_free((sx_t) jqueue_pull(c2s->dead));
961 
962  /* time checks */
963  if(c2s->io_check_interval > 0 && time(NULL) >= c2s->next_check) {
964  log_debug(ZONE, "running time checks");
965 
966  _c2s_time_checks(c2s);
967 
968  c2s->next_check = time(NULL) + c2s->io_check_interval;
969  log_debug(ZONE, "next time check at %d", c2s->next_check);
970  }
971 
972  if(time(NULL) > check_time + 60) {
973 #ifdef POOL_DEBUG
974  pool_stat(1);
975 #endif
976  if(c2s->packet_stats != NULL) {
977  int fd = open(c2s->packet_stats, O_TRUNC | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
978  if (fd >= 0) {
979  char buf[100];
980  int len = snprintf(buf, 100, "%lld\n", c2s->packet_count);
981  if (write(fd, buf, len) != len) {
982  close(fd);
983  fd = -1;
984  } else close(fd);
985  }
986  if (fd < 0) {
987  log_write(c2s->log, LOG_ERR, "failed to write packet statistics to: %s", c2s->packet_stats);
988  c2s_shutdown = 1;
989  }
990  }
991 
992  check_time = time(NULL);
993  }
994  }
995 
996  log_write(c2s->log, LOG_NOTICE, "shutting down");
997 
998  if(xhash_iter_first(c2s->sessions))
999  do {
1000  xhv.sess_val = &sess;
1001  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
1002 
1003  if(sess->active && sess->s)
1004  sx_close(sess->s);
1005 
1006  } while(xhash_iter_next(c2s->sessions));
1007 
1008  /* cleanup dead sess */
1009  while(jqueue_size(c2s->dead_sess) > 0) {
1010  sess = (sess_t) jqueue_pull(c2s->dead_sess);
1011 
1012  /* free sess data */
1013  if(sess->ip != NULL) free((void*)sess->ip);
1014  if(sess->result != NULL) nad_free(sess->result);
1015  if(sess->resources != NULL)
1016  for(res = sess->resources; res != NULL;) {
1017  bres_t tmp = res->next;
1018  jid_free(res->jid);
1019  free(res);
1020  res = tmp;
1021  }
1022 
1023  free(sess);
1024  }
1025 
1026  while(jqueue_size(c2s->dead) > 0)
1027  sx_free((sx_t) jqueue_pull(c2s->dead));
1028 
1029  if (c2s->fd != NULL) mio_close(c2s->mio, c2s->fd);
1030  sx_free(c2s->router);
1031 
1032  sx_env_free(c2s->sx_env);
1033 
1034  mio_free(c2s->mio);
1035 
1036  xhash_free(c2s->sessions);
1037 
1038  xhash_walk(c2s->ar_modules, _c2s_ar_free, NULL);
1039  xhash_free(c2s->ar_modules);
1040 
1041  xhash_free(c2s->conn_rates);
1042 
1044 
1045  xhash_free(c2s->sm_avail);
1046 
1047  xhash_free(c2s->hosts);
1048 
1049  jqueue_free(c2s->dead);
1050 
1051  jqueue_free(c2s->dead_sess);
1052 
1053  access_free(c2s->access);
1054 
1055  log_free(c2s->log);
1056 
1057  config_free(c2s->config);
1058 
1059  free(c2s);
1060 
1061 #ifdef POOL_DEBUG
1062  pool_stat(1);
1063 #endif
1064 
1065 #ifdef HAVE_WINSOCK2_H
1066  WSACleanup();
1067 #endif
1068 
1069  return 0;
1070 }
int(* check_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
check the given password against the stored password, 0 if equal, !0 if not equal (password auth) ...
Definition: c2s.h:351
int address_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: address.c:42
bres_t resources
Definition: c2s.h:103
int io_check_interval
time checks
Definition: c2s.h:258
struct sess_st * sess_t
Definition: c2s.h:55
jid_t jid_reset(jid_t jid, const char *id, int len)
build a jid from an id
Definition: jid.c:113
#define sx_sasl_cb_CHECK_MECH
Definition: plugins.h:115
static void _c2s_signal_hup(int signum)
Definition: main.c:36
struct stream_redirect_st * stream_redirect_t
const char ** values
Definition: util.h:209
const char * log_facility
Definition: c2s.h:200
config_t config
config
Definition: c2s.h:193
_sx_state_t state
Definition: sx.h:315
int access_deny(access_t access, const char *ip, const char *mask)
Definition: access.c:183
int config_load_with_id(config_t c, const char *file, const char *id)
turn an xml file into a config hash
Definition: config.c:80
mio_fd_t fd
Definition: c2s.h:77
struct host_st * host_t
Definition: c2s.h:52
static int _c2s_sx_sasl_callback(int cb, void *arg, void **res, sx_t s, void *cbarg)
Definition: main.c:418
const char * http_forward
http forwarding URL
Definition: c2s.h:238
void xhash_free(xht h)
Definition: xhash.c:241
xht ar_modules
loaded auth/reg modules
Definition: c2s.h:269
static void _c2s_pidfile(c2s_t c2s)
store the process id
Definition: main.c:53
int ar_register_enable
registration
Definition: c2s.h:151
int sx_ack_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: ack.c:107
const char * req_to
Definition: sx.h:281
void config_free(config_t c)
cleanup
Definition: config.c:410
access_t access
access controls
Definition: c2s.h:296
int(* get_password)(authreg_t ar, sess_t sess, const char *username, const char *realm, char password[257])
return this users cleartext password in the array (digest auth, password auth)
Definition: c2s.h:348
mio_t mio_new(int maxfd)
create/free the mio subsytem
Definition: mio.c:38
access_t access_new(int order)
Definition: access.c:25
#define sx_sasl_ret_FAIL
Definition: plugins.h:119
#define mio_run(m, timeout)
give some cpu time to mio to check it's sockets, 0 is non-blocking
Definition: mio.h:164
void jid_static(jid_t jid, jid_static_buf *buf)
Make jid to use static buffer (jid data won't be allocated dynamically, but given buffer will be alwa...
Definition: jid.c:102
const char * router_ciphers
Definition: c2s.h:169
int jqueue_size(jqueue_t q)
Definition: jqueue.c:126
xht conn_rates
Definition: c2s.h:280
int(* user_exists)(authreg_t ar, sess_t sess, const char *username, const char *realm)
returns 1 if the user exists, 0 if not
Definition: c2s.h:345
const char * host_ciphers
list of TLS ciphers
Definition: c2s.h:144
int compression
enable Stream Compression
Definition: c2s.h:255
void log_write(log_t log, int level, const char *msgfmt,...)
Definition: log.c:104
int retry_left
Definition: c2s.h:211
int conn_rate_seconds
Definition: c2s.h:277
static void _c2s_time_checks(c2s_t c2s)
Definition: main.c:612
#define AR_MECH_TRAD_DIGEST
Definition: c2s.h:121
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
Definition: sx.c:23
config_t config_new(void)
new config structure
Definition: config.c:25
#define MIO_STRERROR(e)
Definition: mio.h:170
const char * log_ident
Definition: c2s.h:201
int tag
Definition: sx.h:257
#define mio_free(m)
Definition: mio.h:137
int sx_ssl_server_addcert(sx_plugin_t p, const char *name, const char *pemfile, const char *cachain, int mode, const char *password, const char *ciphers)
args: name, pemfile, cachain, mode
Definition: ssl.c:953
list of resources bound to session
Definition: c2s.h:59
int io_max_fds
max file descriptors
Definition: c2s.h:252
static char * config_file
Definition: main.c:34
char * host_private_key_password
private key password
Definition: c2s.h:135
int io_check_keepalive
Definition: c2s.h:260
nad_t result
Definition: c2s.h:108
int ar_mechanisms
allowed mechanisms
Definition: c2s.h:272
holder for the config hash and nad
Definition: util.h:200
time_t next_check
Definition: c2s.h:262
static void _c2s_config_expand(c2s_t c2s)
pull values out of the config file
Definition: main.c:80
void sx_raw_write(sx_t s, const char *buf, int len)
app version
Definition: io.c:469
const char * id
our id (hostname) with the router
Definition: c2s.h:159
int j_atoi(const char *a, int def)
Definition: str.c:87
char * resource
Definition: jid.h:46
int host_verify_mode
verify-mode
Definition: c2s.h:138
int bind_init(sx_env_t env, sx_plugin_t p, va_list args)
plugin initialiser
Definition: bind.c:69
void nad_free(nad_t nad)
free that nad
Definition: nad.c:178
int stanza_size_limit
maximum stanza size
Definition: c2s.h:293
void log_free(log_t log)
Definition: log.c:174
int xhash_iter_next(xht h)
Definition: xhash.c:320
void jid_random_part(jid_t jid, jid_part_t part)
create random resource
Definition: jid.c:492
static void _c2s_signal(int signum)
Definition: main.c:30
sx_env_t sx_env_new(void)
Definition: env.c:23
#define mio_connect(m, port, hostip, srcip, app, arg)
for creating a new socket connected to this ip:port (returns new fd or <0, use mio_read/write first) ...
Definition: mio.h:144
#define AR_MECH_TRAD_CRAMMD5
Definition: c2s.h:122
sx_t router
router's conn
Definition: c2s.h:183
jid_t jid
full bound jid
Definition: c2s.h:61
time_t last_activity
Definition: c2s.h:97
const char * authnid
Definition: plugins.h:126
authreg_t ar
Definition: c2s.h:266
#define AR_MECH_TRAD_PLAIN
Definition: c2s.h:120
void rate_free(rate_t rt)
Definition: rate.c:36
const char * router_pemfile
Definition: c2s.h:166
sx_t s
Definition: c2s.h:86
#define sx_sasl_ret_OK
Definition: plugins.h:118
char * config_get_attr(config_t c, const char *key, int num, const char *attr)
get an attr for this value
Definition: config.c:314
const char * ip
Definition: c2s.h:83
void jqueue_free(jqueue_t q)
Definition: jqueue.c:38
const char * router_cachain
Definition: c2s.h:167
static void _c2s_signal_usr2(int signum)
Definition: main.c:47
const char * router_ip
how to connect to the router
Definition: c2s.h:162
static void _c2s_signal_usr1(int signum)
Definition: main.c:42
const char * local_ip
ip to listen on
Definition: c2s.h:214
void access_free(access_t access)
Definition: access.c:34
Definition: log.h:42
#define MIO_ERROR
all MIO related routines should use those for error reporting
Definition: mio.h:168
int(* user_authz_allowed)(authreg_t ar, sess_t sess, const char *username, const char *realm, const char *requested_user)
returns 1 if the user is permitted to authorize as the requested_user, 0 if not.
Definition: c2s.h:369
const char * router_private_key_password
Definition: c2s.h:168
int router_port
Definition: c2s.h:163
int sx_can_read(sx_t s)
we can read
Definition: io.c:196
#define sx_sasl_cb_CHECK_AUTHZID
Definition: plugins.h:113
sx_plugin_t sx_ssl
Definition: c2s.h:179
mio_t mio
mio context
Definition: c2s.h:172
sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init,...)
load a plugin into the environment
Definition: env.c:48
holds the state for a single stream
Definition: sx.h:252
int retry_sleep
Definition: c2s.h:210
const char * ar_register_instructions
Definition: c2s.h:152
int stanza_rate_wait
Definition: c2s.h:290
int port
Definition: c2s.h:84
const char * to_address
Definition: c2s.h:409
char jid_static_buf[3 *1025]
JID static buffer.
Definition: jid.h:77
void ** val
Definition: c2s.h:401
time_t bad
Definition: util.h:267
const char * smcomp
Definition: c2s.h:81
void * pmalloco(pool_t p, int size)
easy safety utility (for creating blank mem for structs, etc)
Definition: pool.c:183
void sx_client_init(sx_t s, unsigned int flags, const char *ns, const char *to, const char *from, const char *version)
Definition: client.c:111
struct c2s_st * c2s_t
Definition: c2s.h:53
Definition: jid.h:71
int io_check_idle
Definition: c2s.h:259
const char * router_pass
Definition: c2s.h:165
void set_debug_log_from_config(config_t c)
Definition: log.c:267
void jid_free(jid_t jid)
free a jid
Definition: jid.c:286
const char * realm
our realm (SASL)
Definition: c2s.h:126
void pool_stat(int full)
Definition: pool.c:285
void xhash_put(xht h, const char *key, void *val)
Definition: xhash.c:163
int ar_register_password
Definition: c2s.h:154
sess_t * sess_val
Definition: c2s.h:403
authreg_t ar
Definition: c2s.h:148
struct sx_sasl_creds_st * sx_sasl_creds_t
char * domain
Definition: jid.h:45
host_t host
host this session belongs to
Definition: c2s.h:89
int local_verify_mode
verify-mode
Definition: c2s.h:232
Definition: jid.h:42
int byte_rate_seconds
Definition: c2s.h:284
int local_port
unencrypted port
Definition: c2s.h:217
Definition: c2s.h:124
JABBERD2_API int sx_websocket_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: websocket.c:573
#define stream_err_HOST_GONE
Definition: sx.h:128
xht hosts
hosts mapping
Definition: c2s.h:311
int xhash_iter_get(xht h, const char **key, int *keylen, void **val)
Definition: xhash.c:374
void sx_free(sx_t s)
Definition: sx.c:70
const char * host_pemfile
starttls pemfile
Definition: c2s.h:129
int conn_rate_total
connection rates
Definition: c2s.h:276
int c2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
Definition: c2s.c:679
void sx_close(sx_t s)
Definition: io.c:498
const char * authzid
Definition: plugins.h:128
struct authreg_st * authreg_t
Definition: c2s.h:56
JABBER_MAIN("jabberd2c2s","Jabber 2 C2S","Jabber Open Source Server: Client to Server","jabberd2router\0")
Definition: main.c:654
int byte_rate_wait
Definition: c2s.h:285
#define log_debug(...)
Definition: log.h:65
jsighandler_t * jabber_signal(int signo, jsighandler_t *func)
Definition: jsignal.c:33
sx_env_t sx_env
sx environment
Definition: c2s.h:178
int retry_init
connect retry
Definition: c2s.h:208
static int _c2s_router_connect(c2s_t c2s)
Definition: main.c:401
int rate_check(rate_t rt)
Definition: rate.c:78
const char * realm
Definition: plugins.h:127
int stanza_rate_seconds
Definition: c2s.h:289
xht sm_avail
availability of sms that we are servicing
Definition: c2s.h:315
Definition: c2s.h:157
host_t vhost
Definition: c2s.h:312
const char * ar_module_name
Definition: c2s.h:147
void sx_error(sx_t s, int err, const char *text)
Definition: error.c:94
xht stream_redirects
stream redirection (see-other-host) on session connect
Definition: c2s.h:249
int conn_rate_wait
Definition: c2s.h:278
JABBERD2_API int sx_sasl_init(sx_env_t env, sx_plugin_t p, va_list args)
init function
Definition: sasl.c:855
log_type_t log_type
log data
Definition: c2s.h:199
config_elem_t config_get(config_t c, const char *key)
get the config element for this key
Definition: config.c:271
int retry_lost
Definition: c2s.h:209
jqueue_t dead_sess
list of sess on the way out
Definition: c2s.h:302
#define sx_sasl_cb_GET_REALM
Definition: plugins.h:110
There is one instance of this struct per user who is logged in to this c2s instance.
Definition: c2s.h:74
int ssf
Definition: sx.h:339
void * jqueue_pull(jqueue_t q)
Definition: jqueue.c:96
mio_fd_t fd
Definition: c2s.h:184
int xhash_iter_first(xht h)
iteration
Definition: xhash.c:311
const char * to_port
Definition: c2s.h:410
void xhash_walk(xht h, xhash_walker w, void *arg)
Definition: xhash.c:268
int fd
Definition: mio.h:102
jqueue_t jqueue_new(void)
Definition: jqueue.c:25
long long int packet_count
packet counter
Definition: c2s.h:204
void set_debug_flag(int v)
Definition: log.c:264
int sx_ssl_init(sx_env_t env, sx_plugin_t p, va_list args)
args: name, pemfile, cachain, mode
Definition: ssl.c:904
int websocket
websocket support
Definition: c2s.h:241
static void _c2s_ar_free(const char *module, int modulelen, void *val, void *arg)
Definition: main.c:649
int config_load(config_t c, const char *file)
turn an xml file into a config hash
Definition: config.c:74
xht sessions
sessions
Definition: c2s.h:175
int access_allow(access_t access, const char *ip, const char *mask)
Definition: access.c:163
const char * local_ciphers
list of TLS ciphers
Definition: c2s.h:235
const char *** attrs
Definition: util.h:211
rate_t rate
Definition: c2s.h:91
int sx_compress_init(sx_env_t env, sx_plugin_t p, va_list args)
args: none
Definition: compress.c:328
static sig_atomic_t c2s_shutdown
Definition: main.c:25
pool_t xhash_pool(xht h)
get our pool
Definition: xhash.c:305
const char * packet_stats
Definition: c2s.h:205
static sig_atomic_t c2s_logrotate
Definition: main.c:27
const char * ar_module_name
default auth/reg module
Definition: c2s.h:265
char * pstrdup(pool_t p, const char *src)
XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is wit...
Definition: pool.c:191
rate_t stanza_rate
Definition: c2s.h:94
Definition: log.h:43
int local_ssl_port
encrypted port
Definition: c2s.h:220
Definition: log.h:44
void * xhash_get(xht h, const char *key)
Definition: xhash.c:184
#define mio_close(m, fd)
request that mio close this fd
Definition: mio.h:155
char * j_attr(const char **atts, const char *attr)
Definition: str.c:95
sx_plugin_t sx_sasl
Definition: c2s.h:180
void authreg_free(authreg_t ar)
shutdown the authreg system
Definition: authreg.c:129
log_t log_new(log_type_t type, const char *ident, const char *facility)
Definition: log.c:69
#define ZONE
Definition: mio_impl.h:76
int want_read
Definition: sx.h:305
session packet handling
Definition: c2s.h:399
const char * config_get_one(config_t c, const char *key, int num)
get config value n for this key
Definition: config.c:277
xht xhash_new(int prime)
Definition: xhash.c:96
const char * ar_register_oob
Definition: c2s.h:153
#define sx_sasl_cb_GEN_AUTHZID
Definition: plugins.h:114
jqueue_t dead
list of sx_t on the way out
Definition: c2s.h:299
const char * pass
Definition: plugins.h:129
log_t log
logging
Definition: c2s.h:196
const char * pbx_pipe
PBX integration named pipe.
Definition: c2s.h:244
void sx_env_free(sx_env_t env)
Definition: env.c:31
a single element
Definition: util.h:207
const char * router_user
Definition: c2s.h:164
int host_require_starttls
require starttls
Definition: c2s.h:141
authreg_t authreg_init(c2s_t c2s, const char *name)
get a handle for the named module
Definition: authreg.c:40
const char * local_private_key_password
private key password
Definition: c2s.h:229
sig_atomic_t c2s_lost_router
Definition: main.c:26
int ar_ssl_mechanisms
Definition: c2s.h:273
#define sx_sasl_cb_CHECK_PASS
Definition: plugins.h:112
int active
Definition: c2s.h:105
static sig_atomic_t c2s_sighup
Definition: main.c:28
int nvalues
Definition: util.h:210
char * node
Definition: jid.h:44
int c2s_router_mio_callback(mio_t m, mio_action_t a, mio_fd_t fd, void *data, void *arg)
Definition: c2s.c:1344
int stanza_rate_total
stanza rates
Definition: c2s.h:288
const char * local_pemfile
encrypted port pemfile
Definition: c2s.h:223
const char * local_cachain
encrypted port cachain file
Definition: c2s.h:226
static void _c2s_hosts_expand(c2s_t c2s)
Definition: main.c:295
#define sx_sasl_cb_GET_PASS
Definition: plugins.h:111
bres_t next
Definition: c2s.h:67
const char * host_cachain
certificate chain
Definition: c2s.h:132
int byte_rate_total
byte rates (karma)
Definition: c2s.h:283