jabberd2  2.5.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  /* get host for request */
566  host = xhash_get(c2s->hosts, s->req_to);
567  if(host == NULL) {
568  log_write(c2s->log, LOG_WARNING, "SASL callback for non-existing host: %s", s->req_to);
569  return sx_sasl_ret_FAIL;
570  }
571 
572  /* Determine if our configuration will let us use this mechanism.
573  * We support different mechanisms for both SSL and normal use */
574  if (strcmp(mechbuf, "digest-md5") == 0) {
575  /* digest-md5 requires that our authreg support get_password */
576  if (host->ar->get_password == NULL)
577  return sx_sasl_ret_FAIL;
578  } else if (strcmp(mechbuf, "plain") == 0) {
579  /* plain requires either get_password or check_password */
580  if (host->ar->get_password == NULL && host->ar->check_password == NULL)
581  return sx_sasl_ret_FAIL;
582  }
583 
584  /* Using SSF is potentially dangerous, as SASL can also set the
585  * SSF of the connection. However, SASL shouldn't do so until after
586  * we've finished mechanism establishment
587  */
588  if (s->ssf>0) {
589  r = snprintf(buf, sizeof(buf), "authreg.ssl-mechanisms.sasl.%s",mechbuf);
590  if (r < -1 || r > sizeof(buf))
591  return sx_sasl_ret_FAIL;
592  if(config_get(c2s->config,buf) != NULL)
593  return sx_sasl_ret_OK;
594  }
595 
596  r = snprintf(buf, sizeof(buf), "authreg.mechanisms.sasl.%s",mechbuf);
597  if (r < -1 || r > sizeof(buf))
598  return sx_sasl_ret_FAIL;
599 
600  /* Work out if our configuration will let us use this mechanism */
601  if(config_get(c2s->config,buf) != NULL)
602  return sx_sasl_ret_OK;
603  else
604  return sx_sasl_ret_FAIL;
605  default:
606  break;
607  }
608 
609  return sx_sasl_ret_FAIL;
610 }
611 static void _c2s_time_checks(c2s_t c2s) {
612  sess_t sess;
613  time_t now;
614  union xhashv xhv;
615 
616  now = time(NULL);
617 
618  if(xhash_iter_first(c2s->sessions))
619  do {
620  xhv.sess_val = &sess;
621  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
622 
623  if(!sess->s) continue;
624 
625  if(c2s->io_check_idle > 0 && now > sess->last_activity + c2s->io_check_idle) {
626  log_write(c2s->log, LOG_NOTICE, "[%d] [%s, port=%d] timed out", sess->fd->fd, sess->ip, sess->port);
627 
628  sx_error(sess->s, stream_err_HOST_GONE, "connection timed out");
629  sx_close(sess->s);
630 
631  continue;
632  }
633 
634  if(c2s->io_check_keepalive > 0 && now > sess->last_activity + c2s->io_check_keepalive && sess->s->state >= state_STREAM) {
635  log_debug(ZONE, "sending keepalive for %d", sess->fd->fd);
636 
637  sx_raw_write(sess->s, " ", 1);
638  }
639 
640  if(sess->rate != NULL && sess->rate->bad != 0 && rate_check(sess->rate) != 0) {
641  /* read the pending bytes when rate limit is no longer in effect */
642  log_debug(ZONE, "reading throttled %d", sess->fd->fd);
643  sess->s->want_read = 1;
644  sx_can_read(sess->s);
645  }
646 
647  } while(xhash_iter_next(c2s->sessions));
648 }
649 
650 static void _c2s_ar_free(const char *module, int modulelen, void *val, void *arg) {
651  authreg_t ar = (authreg_t) val;
652  authreg_free(ar);
653 }
654 
655 JABBER_MAIN("jabberd2c2s", "Jabber 2 C2S", "Jabber Open Source Server: Client to Server", "jabberd2router\0")
656 {
657  c2s_t c2s;
658  char *config_file;
659  int optchar;
660  int mio_timeout;
661  sess_t sess;
662  bres_t res;
663  union xhashv xhv;
664  time_t check_time = 0;
665  const char *cli_id = 0;
666 
667 #ifdef HAVE_UMASK
668  umask((mode_t) 0027);
669 #endif
670 
671  srand(time(NULL));
672 
673 #ifdef HAVE_WINSOCK2_H
674 /* get winsock running */
675  {
676  WORD wVersionRequested;
677  WSADATA wsaData;
678  int err;
679 
680  wVersionRequested = MAKEWORD( 2, 2 );
681 
682  err = WSAStartup( wVersionRequested, &wsaData );
683  if ( err != 0 ) {
684  /* !!! tell user that we couldn't find a usable winsock dll */
685  return 0;
686  }
687  }
688 #endif
689 
690  jabber_signal(SIGINT, _c2s_signal);
691  jabber_signal(SIGTERM, _c2s_signal);
692 #ifdef SIGHUP
694 #endif
695 #ifdef SIGPIPE
696  jabber_signal(SIGPIPE, SIG_IGN);
697 #endif
700 
701 
702  c2s = (c2s_t) calloc(1, sizeof(struct c2s_st));
703 
704  /* load our config */
705  c2s->config = config_new();
706 
707  config_file = CONFIG_DIR "/c2s.xml";
708 
709  /* cmdline parsing */
710  while((optchar = getopt(argc, argv, "Dc:hi:?")) >= 0)
711  {
712  switch(optchar)
713  {
714  case 'c':
715  config_file = optarg;
716  break;
717  case 'D':
718 #ifdef DEBUG
719  set_debug_flag(1);
720 #else
721  printf("WARN: Debugging not enabled. Ignoring -D.\n");
722 #endif
723  break;
724  case 'i':
725  cli_id = optarg;
726  break;
727  case 'h': case '?': default:
728  fputs(
729  "c2s - jabberd client-to-server connector (" VERSION ")\n"
730  "Usage: c2s <options>\n"
731  "Options are:\n"
732  " -c <config> config file to use [default: " CONFIG_DIR "/c2s.xml]\n"
733  " -i id Override <id> config element\n"
734 #ifdef DEBUG
735  " -D Show debug output\n"
736 #endif
737  ,
738  stdout);
739  config_free(c2s->config);
740  free(c2s);
741  return 1;
742  }
743  }
744 
745  if(config_load_with_id(c2s->config, config_file, cli_id) != 0)
746  {
747  fputs("c2s: couldn't load config, aborting\n", stderr);
748  config_free(c2s->config);
749  free(c2s);
750  return 2;
751  }
752 
753  c2s->stream_redirects = xhash_new(11);
754 
755  _c2s_config_expand(c2s);
756 
757  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
758 
759  c2s->ar_modules = xhash_new(5);
760  if(c2s->ar_module_name == NULL) {
761  log_write(c2s->log, LOG_NOTICE, "no default authreg module specified in config file");
762  }
763  else if((c2s->ar = authreg_init(c2s, c2s->ar_module_name)) == NULL) {
764  access_free(c2s->access);
765  config_free(c2s->config);
766  log_free(c2s->log);
767  free(c2s);
768  exit(1);
769  }
770 
771  log_write(c2s->log, LOG_NOTICE, "starting up");
772 
773  _c2s_pidfile(c2s);
774 
775  c2s->sessions = xhash_new(1023);
776 
777  c2s->conn_rates = xhash_new(101);
778 
779  c2s->dead = jqueue_new();
780 
781  c2s->dead_sess = jqueue_new();
782 
783  c2s->sx_env = sx_env_new();
784 
785 #ifdef HAVE_SSL
786  /* get the ssl context up and running */
787  if(c2s->local_pemfile != NULL) {
789  if(c2s->sx_ssl == NULL) {
790  log_write(c2s->log, LOG_ERR, "failed to load local SSL pemfile, SSL will not be available to clients");
791  c2s->local_pemfile = NULL;
792  }
793  }
794 
795  /* try and get something online, so at least we can encrypt to the router */
796  if(c2s->sx_ssl == NULL && c2s->router_pemfile != NULL) {
798  if(c2s->sx_ssl == NULL) {
799  log_write(c2s->log, LOG_ERR, "failed to load router SSL pemfile, channel to router will not be SSL encrypted");
800  c2s->router_pemfile = NULL;
801  }
802  }
803 #endif
804 
805 #ifdef USE_WEBSOCKET
806  /* possibly wrap in websocket */
807  if(c2s->websocket) {
809  }
810 #else
811  if(c2s->websocket) {
812  log_write(c2s->log, LOG_ERR, "websocket support not built-in - not enabling");
813  }
814  if(c2s->http_forward) {
815  log_write(c2s->log, LOG_ERR, "httpforward available only with websocket support built-in");
816  }
817 #endif
818 
819 #ifdef HAVE_LIBZ
820  /* get compression up and running */
821  if(c2s->compression) {
823  }
824 #endif
825 
826  /* get stanza ack up */
828 
829  /* and user IP address plugin */
831 
832  /* get sasl online */
833  c2s->sx_sasl = sx_env_plugin(c2s->sx_env, sx_sasl_init, "xmpp", _c2s_sx_sasl_callback, (void *) c2s);
834  if(c2s->sx_sasl == NULL) {
835  log_write(c2s->log, LOG_ERR, "failed to initialise SASL context, aborting");
836  exit(1);
837  }
838 
839  /* get bind up */
840  sx_env_plugin(c2s->sx_env, bind_init, c2s);
841 
842  c2s->mio = mio_new(c2s->io_max_fds);
843  if(c2s->mio == NULL) {
844  log_write(c2s->log, LOG_ERR, "failed to create MIO, aborting");
845  exit(1);
846  }
847 
848  /* hosts mapping */
849  c2s->hosts = xhash_new(1021);
850  _c2s_hosts_expand(c2s);
851  c2s->sm_avail = xhash_new(1021);
852 
853  c2s->retry_left = c2s->retry_init;
854  _c2s_router_connect(c2s);
855 
856  mio_timeout = ((c2s->io_check_interval != 0 && c2s->io_check_interval < 5) ?
857  c2s->io_check_interval : 5);
858 
859  while(!c2s_shutdown) {
860  mio_run(c2s->mio, mio_timeout);
861 
862  if(c2s_logrotate) {
864 
865  log_write(c2s->log, LOG_NOTICE, "reopening log ...");
866  log_free(c2s->log);
867  c2s->log = log_new(c2s->log_type, c2s->log_ident, c2s->log_facility);
868  log_write(c2s->log, LOG_NOTICE, "log started");
869 
870  c2s_logrotate = 0;
871  }
872 
873  if(c2s_sighup) {
874  log_write(c2s->log, LOG_NOTICE, "reloading some configuration items ...");
875  config_t conf;
876  conf = config_new();
877  if (conf && config_load(conf, config_file) == 0) {
879  c2s->stream_redirects = xhash_new(11);
880 
881  char *req_domain, *to_address, *to_port;
882  config_elem_t elem;
883  int i;
885 
886  elem = config_get(conf, "stream_redirect.redirect");
887  if(elem != NULL)
888  {
889  for(i = 0; i < elem->nvalues; i++)
890  {
892  if(!sr) {
893  log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting");
894  exit(1);
895  }
896  req_domain = j_attr((const char **) elem->attrs[i], "requested_domain");
897  to_address = j_attr((const char **) elem->attrs[i], "to_address");
898  to_port = j_attr((const char **) elem->attrs[i], "to_port");
899 
900  if(req_domain == NULL || to_address == NULL || to_port == NULL) {
901  log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping");
902  continue;
903  }
904 
905  // Note that to_address should be RFC 3986 compliant
906  sr->to_address = to_address;
907  sr->to_port = to_port;
908 
909  xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr);
910  }
911  }
912  config_free(conf);
913  } else {
914  log_write(c2s->log, LOG_WARNING, "couldn't reload config (%s)", config_file);
915  if (conf) config_free(conf);
916  }
917  c2s_sighup = 0;
918  }
919 
920  if(c2s_lost_router) {
921  if(c2s->retry_left < 0) {
922  log_write(c2s->log, LOG_NOTICE, "attempting reconnect");
923  sleep(c2s->retry_sleep);
924  c2s_lost_router = 0;
925  if (c2s->router) sx_free(c2s->router);
926  _c2s_router_connect(c2s);
927  }
928 
929  else if(c2s->retry_left == 0) {
930  c2s_shutdown = 1;
931  }
932 
933  else {
934  log_write(c2s->log, LOG_NOTICE, "attempting reconnect (%d left)", c2s->retry_left);
935  c2s->retry_left--;
936  sleep(c2s->retry_sleep);
937  c2s_lost_router = 0;
938  if (c2s->router) sx_free(c2s->router);
939  _c2s_router_connect(c2s);
940  }
941  }
942 
943  /* cleanup dead sess (before sx_t as sess->result uses sx_t nad cache) */
944  while(jqueue_size(c2s->dead_sess) > 0) {
945  sess = (sess_t) jqueue_pull(c2s->dead_sess);
946 
947  /* free sess data */
948  if(sess->ip != NULL) free((void*)sess->ip);
949  if(sess->smcomp != NULL) free((void*)sess->smcomp);
950  if(sess->result != NULL) nad_free(sess->result);
951  if(sess->resources != NULL)
952  for(res = sess->resources; res != NULL;) {
953  bres_t tmp = res->next;
954  jid_free(res->jid);
955  free(res);
956  res = tmp;
957  }
958  if(sess->rate != NULL) rate_free(sess->rate);
959  if(sess->stanza_rate != NULL) rate_free(sess->stanza_rate);
960 
961  free(sess);
962  }
963 
964  /* cleanup dead sx_ts */
965  while(jqueue_size(c2s->dead) > 0)
966  sx_free((sx_t) jqueue_pull(c2s->dead));
967 
968  /* time checks */
969  if(c2s->io_check_interval > 0 && time(NULL) >= c2s->next_check) {
970  log_debug(ZONE, "running time checks");
971 
972  _c2s_time_checks(c2s);
973 
974  c2s->next_check = time(NULL) + c2s->io_check_interval;
975  log_debug(ZONE, "next time check at %d", c2s->next_check);
976  }
977 
978  if(time(NULL) > check_time + 60) {
979 #ifdef POOL_DEBUG
980  pool_stat(1);
981 #endif
982  if(c2s->packet_stats != NULL) {
983  int fd = open(c2s->packet_stats, O_TRUNC | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP);
984  if (fd >= 0) {
985  char buf[100];
986  int len = snprintf(buf, 100, "%lld\n", c2s->packet_count);
987  if (write(fd, buf, len) != len) {
988  close(fd);
989  fd = -1;
990  } else close(fd);
991  }
992  if (fd < 0) {
993  log_write(c2s->log, LOG_ERR, "failed to write packet statistics to: %s", c2s->packet_stats);
994  c2s_shutdown = 1;
995  }
996  }
997 
998  check_time = time(NULL);
999  }
1000  }
1001 
1002  log_write(c2s->log, LOG_NOTICE, "shutting down");
1003 
1004  if(xhash_iter_first(c2s->sessions))
1005  do {
1006  xhv.sess_val = &sess;
1007  xhash_iter_get(c2s->sessions, NULL, NULL, xhv.val);
1008 
1009  if(sess->active && sess->s)
1010  sx_close(sess->s);
1011 
1012  } while(xhash_iter_next(c2s->sessions));
1013 
1014  /* cleanup dead sess */
1015  while(jqueue_size(c2s->dead_sess) > 0) {
1016  sess = (sess_t) jqueue_pull(c2s->dead_sess);
1017 
1018  /* free sess data */
1019  if(sess->ip != NULL) free((void*)sess->ip);
1020  if(sess->result != NULL) nad_free(sess->result);
1021  if(sess->resources != NULL)
1022  for(res = sess->resources; res != NULL;) {
1023  bres_t tmp = res->next;
1024  jid_free(res->jid);
1025  free(res);
1026  res = tmp;
1027  }
1028 
1029  free(sess);
1030  }
1031 
1032  while(jqueue_size(c2s->dead) > 0)
1033  sx_free((sx_t) jqueue_pull(c2s->dead));
1034 
1035  if (c2s->fd != NULL) mio_close(c2s->mio, c2s->fd);
1036  sx_free(c2s->router);
1037 
1038  sx_env_free(c2s->sx_env);
1039 
1040  mio_free(c2s->mio);
1041 
1042  xhash_free(c2s->sessions);
1043 
1044  xhash_walk(c2s->ar_modules, _c2s_ar_free, NULL);
1045  xhash_free(c2s->ar_modules);
1046 
1047  xhash_free(c2s->conn_rates);
1048 
1050 
1051  xhash_free(c2s->sm_avail);
1052 
1053  xhash_free(c2s->hosts);
1054 
1055  jqueue_free(c2s->dead);
1056 
1057  jqueue_free(c2s->dead_sess);
1058 
1059  access_free(c2s->access);
1060 
1061  log_free(c2s->log);
1062 
1063  config_free(c2s->config);
1064 
1065  free(c2s);
1066 
1067 #ifdef POOL_DEBUG
1068  pool_stat(1);
1069 #endif
1070 
1071 #ifdef HAVE_WINSOCK2_H
1072  WSACleanup();
1073 #endif
1074 
1075  return 0;
1076 }
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 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:611
#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:954
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: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
sx_t router
router&#39;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: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:681
void sx_close(sx_t s)
Definition: io.c:512
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:655
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
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:862
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
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:905
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:650
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:1343
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