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