static void _s2s_hosts_expand(s2s_t s2s) { char *realm; config_elem_t elem; char id[1024]; int i; elem = config_get(s2s->config, "local.id"); if (elem) for(i = 0; i < elem->nvalues; i++) { host_t host = (host_t) pmalloco(xhash_pool(s2s->hosts), sizeof(struct host_st)); if(!host) { log_write(s2s->log, LOG_ERR, "cannot allocate memory for new host, aborting"); exit(1); } realm = j_attr((const char **) elem->attrs[i], "realm"); /* stringprep ids (domain names) so that they are in canonical form */ strncpy(id, elem->values[i], 1024); id[1023] = '\0'; if (stringprep_nameprep(id, 1024) != 0) { log_write(s2s->log, LOG_ERR, "cannot stringprep id %s, aborting", id); exit(1); } host->realm = (realm != NULL) ? realm : pstrdup(xhash_pool(s2s->hosts), id); host->host_pemfile = j_attr((const char **) elem->attrs[i], "pemfile"); host->host_cachain = j_attr((const char **) elem->attrs[i], "cachain"); host->host_verify_mode = j_atoi(j_attr((const char **) elem->attrs[i], "verify-mode"), 0); #ifdef HAVE_SSL if(host->host_pemfile != NULL) { if(s2s->sx_ssl == NULL) { s2s->sx_ssl = sx_env_plugin(s2s->sx_env, sx_ssl_init, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode); if(s2s->sx_ssl == NULL) { log_write(s2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm); host->host_pemfile = NULL; } } else { if(sx_ssl_server_addcert(s2s->sx_ssl, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode) != 0) { log_write(s2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm); host->host_pemfile = NULL; } } } #endif /* insert into vHosts xhash */ xhash_put(s2s->hosts, pstrdup(xhash_pool(s2s->hosts), id), host); log_write(s2s->log, LOG_NOTICE, "[%s] configured; realm=%s", id, host->realm); } }
storage_t storage_new(config_t config, log_t log) { storage_t st; int i; config_elem_t elem; char *type; st_ret_t ret; st = (storage_t) calloc(1, sizeof(struct storage_st)); st->config = config; st->log = log; st->drivers = xhash_new(101); st->types = xhash_new(101); /* register types declared in the config file */ elem = config_get(st->config, "storage.driver"); if(elem != NULL) { for(i = 0; i < elem->nvalues; i++) { type = j_attr((const char **) elem->attrs[i], "type"); ret = storage_add_type(st, elem->values[i], type); /* Initialisation of storage type failed */ if (ret != st_SUCCESS) { free(st); return NULL; } } } return st; }
/** get an attr for this value */ char *config_get_attr(config_t c, const char *key, int num, const char *attr) { config_elem_t elem = (config_elem_t)xhash_get(c->hash, key); if(num >= elem->nvalues || elem->attrs == NULL || elem->attrs[num] == NULL) return NULL; return j_attr((const char **) elem->attrs[num], attr); }
/** pull values out of the config file */ static void _c2s_config_expand(c2s_t c2s) { const char *str, *ip, *mask; char *req_domain, *to_address, *to_port; config_elem_t elem; int i; stream_redirect_t sr; set_debug_log_from_config(c2s->config); c2s->id = config_get_one(c2s->config, "id", 0); if(c2s->id == NULL) c2s->id = "c2s"; c2s->router_ip = config_get_one(c2s->config, "router.ip", 0); if(c2s->router_ip == NULL) c2s->router_ip = "127.0.0.1"; c2s->router_port = j_atoi(config_get_one(c2s->config, "router.port", 0), 5347); c2s->router_user = config_get_one(c2s->config, "router.user", 0); if(c2s->router_user == NULL) c2s->router_user = "******"; c2s->router_pass = config_get_one(c2s->config, "router.pass", 0); if(c2s->router_pass == NULL) c2s->router_pass = "******"; c2s->router_pemfile = config_get_one(c2s->config, "router.pemfile", 0); c2s->router_cachain = config_get_one(c2s->config, "router.cachain", 0); c2s->router_private_key_password = config_get_one(c2s->config, "router.private_key_password", 0); c2s->retry_init = j_atoi(config_get_one(c2s->config, "router.retry.init", 0), 3); c2s->retry_lost = j_atoi(config_get_one(c2s->config, "router.retry.lost", 0), 3); if((c2s->retry_sleep = j_atoi(config_get_one(c2s->config, "router.retry.sleep", 0), 2)) < 1) c2s->retry_sleep = 1; c2s->log_type = log_STDOUT; if(config_get(c2s->config, "log") != NULL) { if((str = config_get_attr(c2s->config, "log", 0, "type")) != NULL) { if(strcmp(str, "file") == 0) c2s->log_type = log_FILE; else if(strcmp(str, "syslog") == 0) c2s->log_type = log_SYSLOG; } } if(c2s->log_type == log_SYSLOG) { c2s->log_facility = config_get_one(c2s->config, "log.facility", 0); c2s->log_ident = config_get_one(c2s->config, "log.ident", 0); if(c2s->log_ident == NULL) c2s->log_ident = "jabberd/c2s"; } else if(c2s->log_type == log_FILE) c2s->log_ident = config_get_one(c2s->config, "log.file", 0); c2s->packet_stats = config_get_one(c2s->config, "stats.packet", 0); c2s->local_ip = config_get_one(c2s->config, "local.ip", 0); if(c2s->local_ip == NULL) c2s->local_ip = "0.0.0.0"; c2s->local_port = j_atoi(config_get_one(c2s->config, "local.port", 0), 0); c2s->local_pemfile = config_get_one(c2s->config, "local.pemfile", 0); c2s->local_cachain = config_get_one(c2s->config, "local.cachain", 0); c2s->local_private_key_password = config_get_one(c2s->config, "local.private_key_password", 0); c2s->local_verify_mode = j_atoi(config_get_one(c2s->config, "local.verify-mode", 0), 0); c2s->local_ssl_port = j_atoi(config_get_one(c2s->config, "local.ssl-port", 0), 0); c2s->http_forward = config_get_one(c2s->config, "local.httpforward", 0); c2s->io_max_fds = j_atoi(config_get_one(c2s->config, "io.max_fds", 0), 1024); c2s->compression = (config_get(c2s->config, "io.compression") != NULL); c2s->io_check_interval = j_atoi(config_get_one(c2s->config, "io.check.interval", 0), 0); c2s->io_check_idle = j_atoi(config_get_one(c2s->config, "io.check.idle", 0), 0); c2s->io_check_keepalive = j_atoi(config_get_one(c2s->config, "io.check.keepalive", 0), 0); c2s->pbx_pipe = config_get_one(c2s->config, "pbx.pipe", 0); elem = config_get(c2s->config, "stream_redirect.redirect"); if(elem != NULL) { for(i = 0; i < elem->nvalues; i++) { sr = (stream_redirect_t) pmalloco(xhash_pool(c2s->stream_redirects), sizeof(struct stream_redirect_st)); if(!sr) { log_write(c2s->log, LOG_ERR, "cannot allocate memory for new stream redirection record, aborting"); exit(1); } req_domain = j_attr((const char **) elem->attrs[i], "requested_domain"); to_address = j_attr((const char **) elem->attrs[i], "to_address"); to_port = j_attr((const char **) elem->attrs[i], "to_port"); if(req_domain == NULL || to_address == NULL || to_port == NULL) { log_write(c2s->log, LOG_ERR, "Error reading a stream_redirect.redirect element from file, skipping"); continue; } // Note that to_address should be RFC 3986 compliant sr->to_address = to_address; sr->to_port = to_port; xhash_put(c2s->stream_redirects, pstrdup(xhash_pool(c2s->stream_redirects), req_domain), sr); } } c2s->ar_module_name = config_get_one(c2s->config, "authreg.module", 0); if(config_get(c2s->config, "authreg.mechanisms.traditional.plain") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_PLAIN; if(config_get(c2s->config, "authreg.mechanisms.traditional.digest") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_DIGEST; if(config_get(c2s->config, "authreg.mechanisms.traditional.cram-md5") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_CRAMMD5; if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.plain") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_PLAIN; if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.digest") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_DIGEST; if(config_get(c2s->config, "authreg.ssl-mechanisms.traditional.cram-md5") != NULL) c2s->ar_ssl_mechanisms |= AR_MECH_TRAD_CRAMMD5; elem = config_get(c2s->config, "io.limits.bytes"); if(elem != NULL) { c2s->byte_rate_total = j_atoi(elem->values[0], 0); if(c2s->byte_rate_total != 0) { c2s->byte_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 1); c2s->byte_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5); } } elem = config_get(c2s->config, "io.limits.stanzas"); if(elem != NULL) { c2s->stanza_rate_total = j_atoi(elem->values[0], 0); if(c2s->stanza_rate_total != 0) { c2s->stanza_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 1); c2s->stanza_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5); } } elem = config_get(c2s->config, "io.limits.connects"); if(elem != NULL) { c2s->conn_rate_total = j_atoi(elem->values[0], 0); if(c2s->conn_rate_total != 0) { c2s->conn_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5); c2s->conn_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5); } } c2s->stanza_size_limit = j_atoi(config_get_one(c2s->config, "io.limits.stanzasize", 0), 0); /* tweak timed checks with rate times */ if(c2s->io_check_interval == 0) { if(c2s->byte_rate_total != 0) c2s->io_check_interval = c2s->byte_rate_wait; if(c2s->stanza_rate_total != 0 && c2s->io_check_interval > c2s->stanza_rate_wait) c2s->io_check_interval = c2s->stanza_rate_wait; } str = config_get_one(c2s->config, "io.access.order", 0); if(str == NULL || strcmp(str, "deny,allow") != 0) c2s->access = access_new(0); else c2s->access = access_new(1); elem = config_get(c2s->config, "io.access.allow"); if(elem != NULL) { for(i = 0; i < elem->nvalues; i++) { ip = j_attr((const char **) elem->attrs[i], "ip"); mask = j_attr((const char **) elem->attrs[i], "mask"); if(ip == NULL) continue; if(mask == NULL) mask = "255.255.255.255"; access_allow(c2s->access, ip, mask); } } elem = config_get(c2s->config, "io.access.deny"); if(elem != NULL) { for(i = 0; i < elem->nvalues; i++) { ip = j_attr((const char **) elem->attrs[i], "ip"); mask = j_attr((const char **) elem->attrs[i], "mask"); if(ip == NULL) continue; if(mask == NULL) mask = "255.255.255.255"; access_deny(c2s->access, ip, mask); } } }
static void _c2s_hosts_expand(c2s_t c2s) { char *realm; config_elem_t elem; char id[1024]; int i; elem = config_get(c2s->config, "local.id"); if(!elem) { log_write(c2s->log, LOG_NOTICE, "no local.id configured - skipping local domains configuration"); return; } for(i = 0; i < elem->nvalues; i++) { host_t host = (host_t) pmalloco(xhash_pool(c2s->hosts), sizeof(struct host_st)); if(!host) { log_write(c2s->log, LOG_ERR, "cannot allocate memory for new host, aborting"); exit(1); } realm = j_attr((const char **) elem->attrs[i], "realm"); /* stringprep ids (domain names) so that they are in canonical form */ strncpy(id, elem->values[i], 1024); id[1023] = '\0'; if (stringprep_nameprep(id, 1024) != 0) { log_write(c2s->log, LOG_ERR, "cannot stringprep id %s, aborting", id); exit(1); } host->realm = (realm != NULL) ? realm : pstrdup(xhash_pool(c2s->hosts), id); host->host_pemfile = j_attr((const char **) elem->attrs[i], "pemfile"); host->host_cachain = j_attr((const char **) elem->attrs[i], "cachain"); host->host_verify_mode = j_atoi(j_attr((const char **) elem->attrs[i], "verify-mode"), 0); host->host_private_key_password = j_attr((const char **) elem->attrs[i], "private-key-password"); #ifdef HAVE_SSL if(host->host_pemfile != NULL) { if(c2s->sx_ssl == NULL) { c2s->sx_ssl = sx_env_plugin(c2s->sx_env, sx_ssl_init, host->realm, host->host_pemfile, host->host_cachain, host->host_verify_mode, host->host_private_key_password); if(c2s->sx_ssl == NULL) { log_write(c2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm); host->host_pemfile = NULL; } } else { 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) != 0) { log_write(c2s->log, LOG_ERR, "failed to load %s SSL pemfile", host->realm); host->host_pemfile = NULL; } } } #endif host->host_require_starttls = (j_attr((const char **) elem->attrs[i], "require-starttls") != NULL); host->ar_register_enable = (j_attr((const char **) elem->attrs[i], "register-enable") != NULL); host->ar_register_oob = j_attr((const char **) elem->attrs[i], "register-oob"); if(host->ar_register_enable || host->ar_register_oob) { host->ar_register_instructions = j_attr((const char **) elem->attrs[i], "instructions"); if(host->ar_register_instructions == NULL) { if(host->ar_register_oob) host->ar_register_instructions = "Only web based registration is possible with this server."; else host->ar_register_instructions = "Enter a username and password to register with this server."; } } else host->ar_register_password = (j_attr((const char **) elem->attrs[i], "password-change") != NULL); /* check for empty <id/> CDATA - XXX this "1" is VERY config.c dependant !!! */ if(! strcmp(id, "1")) { /* remove the realm even if set */ host->realm = NULL; /* skip if vHost already configured */ if(! c2s->vhost) c2s->vhost = host; /* add meaningful log "id" */ strcpy(id, "default vHost"); } else { /* insert into vHosts xhash */ xhash_put(c2s->hosts, pstrdup(xhash_pool(c2s->hosts), id), host); } log_write(c2s->log, LOG_NOTICE, "[%s] configured; realm=%s, registration %s, using PEM:%s", id, (host->realm != NULL ? host->realm : "no realm set"), (host->ar_register_enable ? "enabled" : "disabled"), (host->host_pemfile ? host->host_pemfile : "Default")); } }
/** pull values out of the config file */ static void _sm_config_expand(sm_t sm) { char *str; config_elem_t elem; set_debug_log_from_config(sm->config); sm->id = config_get_one(sm->config, "id", 0); if(sm->id == NULL) sm->id = "sm"; sm->router_ip = config_get_one(sm->config, "router.ip", 0); if(sm->router_ip == NULL) sm->router_ip = "127.0.0.1"; sm->router_port = j_atoi(config_get_one(sm->config, "router.port", 0), 5347); sm->router_user = config_get_one(sm->config, "router.user", 0); if(sm->router_user == NULL) sm->router_user = "******"; sm->router_pass = config_get_one(sm->config, "router.pass", 0); if(sm->router_pass == NULL) sm->router_pass = "******"; sm->router_pemfile = config_get_one(sm->config, "router.pemfile", 0); sm->router_private_key_password = config_get_one(sm->config, "router.private_key_password", 0); sm->retry_init = j_atoi(config_get_one(sm->config, "router.retry.init", 0), 3); sm->retry_lost = j_atoi(config_get_one(sm->config, "router.retry.lost", 0), 3); if((sm->retry_sleep = j_atoi(config_get_one(sm->config, "router.retry.sleep", 0), 2)) < 1) sm->retry_sleep = 1; sm->log_type = log_STDOUT; if(config_get(sm->config, "log") != NULL) { if((str = config_get_attr(sm->config, "log", 0, "type")) != NULL) { if(strcmp(str, "file") == 0) sm->log_type = log_FILE; else if(strcmp(str, "syslog") == 0) sm->log_type = log_SYSLOG; } } if(sm->log_type == log_SYSLOG) { sm->log_facility = config_get_one(sm->config, "log.facility", 0); sm->log_ident = config_get_one(sm->config, "log.ident", 0); if(sm->log_ident == NULL) sm->log_ident = "jabberd/sm"; } else if(sm->log_type == log_FILE) sm->log_ident = config_get_one(sm->config, "log.file", 0); elem = config_get(sm->config, "storage.limits.queries"); if(elem != NULL) { sm->query_rate_total = j_atoi(elem->values[0], 0); if(sm->query_rate_total != 0) { sm->query_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5); sm->query_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 60); } } }
/** pull values out of the config file */ static void _router_config_expand(router_t r) { const char *str; char *ip, *mask, *name, *target; config_elem_t elem; int i; alias_t alias; r->id = config_get_one(r->config, "id", 0); if(r->id == NULL) r->id = "router"; set_debug_log_from_config(r->config); r->log_type = log_STDOUT; if(config_get(r->config, "log") != NULL) { if((str = config_get_attr(r->config, "log", 0, "type")) != NULL) { if(strcmp(str, "file") == 0) r->log_type = log_FILE; else if(strcmp(str, "syslog") == 0) r->log_type = log_SYSLOG; } } if(r->log_type == log_SYSLOG) { r->log_facility = config_get_one(r->config, "log.facility", 0); r->log_ident = config_get_one(r->config, "log.ident", 0); if(r->log_ident == NULL) r->log_ident = "jabberd/router"; } else if(r->log_type == log_FILE) r->log_ident = config_get_one(r->config, "log.file", 0); r->local_ip = config_get_one(r->config, "local.ip", 0); if(r->local_ip == NULL) r->local_ip = "0.0.0.0"; r->local_port = j_atoi(config_get_one(r->config, "local.port", 0), 5347); r->local_secret = config_get_one(r->config, "local.secret", 0); r->local_pemfile = config_get_one(r->config, "local.pemfile", 0); r->io_max_fds = j_atoi(config_get_one(r->config, "io.max_fds", 0), 1024); elem = config_get(r->config, "io.limits.bytes"); if(elem != NULL) { r->byte_rate_total = j_atoi(elem->values[0], 0); if(r->byte_rate_total != 0) { r->byte_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5); r->byte_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5); } } elem = config_get(r->config, "io.limits.connects"); if(elem != NULL) { r->conn_rate_total = j_atoi(elem->values[0], 0); if(r->conn_rate_total != 0) { r->conn_rate_seconds = j_atoi(j_attr((const char **) elem->attrs[0], "seconds"), 5); r->conn_rate_wait = j_atoi(j_attr((const char **) elem->attrs[0], "throttle"), 5); } } str = config_get_one(r->config, "io.access.order", 0); if(str == NULL || strcmp(str, "deny,allow") != 0) r->access = access_new(0); else r->access = access_new(1); elem = config_get(r->config, "io.access.allow"); if(elem != NULL) { for(i = 0; i < elem->nvalues; i++) { ip = j_attr((const char **) elem->attrs[i], "ip"); mask = j_attr((const char **) elem->attrs[i], "mask"); if(ip == NULL) continue; if(mask == NULL) mask = "255.255.255.255"; access_allow(r->access, ip, mask); } } elem = config_get(r->config, "io.access.deny"); if(elem != NULL) { for(i = 0; i < elem->nvalues; i++) { ip = j_attr((const char **) elem->attrs[i], "ip"); mask = j_attr((const char **) elem->attrs[i], "mask"); if(ip == NULL) continue; if(mask == NULL) mask = "255.255.255.255"; access_deny(r->access, ip, mask); } } /* aliases */ elem = config_get(r->config, "aliases.alias"); if(elem != NULL) for(i = 0; i < elem->nvalues; i++) { name = j_attr((const char **) elem->attrs[i], "name"); target = j_attr((const char **) elem->attrs[i], "target"); if(name == NULL || target == NULL) continue; alias = (alias_t) calloc(1, sizeof(struct alias_st)); alias->name = name; alias->target = target; alias->next = r->aliases; r->aliases = alias; } /* message logging to flat file */ r->message_logging_enabled = j_atoi(config_get_one(r->config, "message_logging.enabled", 0), 0); r->message_logging_file = config_get_one(r->config, "message_logging.file", 0); r->check_interval = j_atoi(config_get_one(r->config, "check.interval", 0), 60); r->check_keepalive = j_atoi(config_get_one(r->config, "check.keepalive", 0), 0); }