/** store the process id */ static void _s2s_pidfile(s2s_t s2s) { char *pidfile; FILE *f; pid_t pid; pidfile = config_get_one(s2s->config, "pidfile", 0); if(pidfile == NULL) return; pid = getpid(); if((f = fopen(pidfile, "w+")) == NULL) { log_write(s2s->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno)); return; } if(fprintf(f, "%d", pid) < 0) { log_write(s2s->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno)); fclose(f); return; } fclose(f); log_write(s2s->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile); }
/** get config value n for this key, returns default_value if not found */ const char *config_get_one_default(config_t c, const char *key, int num, const char *default_value) { const char *rv = config_get_one(c, key, num); if (!rv) rv = default_value; return rv; };
void ICACHE_FLASH_ATTR config_get(serverConnData *conn, uint8_t argc, char *argv[]){ bool err = false; if (argc == 0) config_get_all(conn); else if (argc != 1) err=true; else { config_get_one(conn, argv[1]); } if (err) espbuffsentstring(conn, MSG_ERROR); else espbuffsentstring(conn, MSG_OK); }
st_ret_t storage_add_type(storage_t st, const char *driver, const char *type) { st_driver_t drv; st_driver_init_fn init_fn = NULL; char mod_fullpath[PATH_MAX]; const char *modules_path; st_ret_t ret; void *handle; /* startup, see if we've already registered this type */ if(type == NULL) { log_debug(ZONE, "adding arbitrary types to driver '%s'", driver); /* see if we already have one */ if(st->default_drv != NULL) { log_debug(ZONE, "we already have a default handler, ignoring this one"); return st_FAILED; } } else { log_debug(ZONE, "adding type '%s' to driver '%s'", type, driver); /* see if we already have one */ if(xhash_get(st->types, type) != NULL) { log_debug(ZONE, "we already have a handler for type '%s', ignoring this one", type); return st_FAILED; } } /* set modules path */ modules_path = config_get_one(st->config, "storage.path", 0); /* get the driver */ drv = xhash_get(st->drivers, driver); if(drv == NULL) { log_debug(ZONE, "driver not loaded, trying to init"); log_write(st->log, LOG_INFO, "loading '%s' storage module", driver); #ifndef _WIN32 if (modules_path != NULL) snprintf(mod_fullpath, PATH_MAX, "%s/storage_%s.so", modules_path, driver); else snprintf(mod_fullpath, PATH_MAX, "%s/storage_%s.so", LIBRARY_DIR, driver); handle = dlopen(mod_fullpath, RTLD_LAZY); if (handle != NULL) init_fn = dlsym(handle, "st_init"); #else if (modules_path != NULL) snprintf(mod_fullpath, PATH_MAX, "%s\\storage_%s.dll", modules_path, driver); else snprintf(mod_fullpath, PATH_MAX, "storage_%s.dll", driver); handle = (void*) LoadLibrary(mod_fullpath); if (handle != NULL) init_fn = (st_driver_init_fn)GetProcAddress((HMODULE) handle, "st_init"); #endif if (handle != NULL && init_fn != NULL) { log_debug(ZONE, "preloaded module '%s' (not initialized yet)", driver); } else { #ifndef _WIN32 log_write(st->log, LOG_ERR, "failed loading storage module '%s' (%s)", driver, dlerror()); if (handle != NULL) dlclose(handle); #else log_write(st->log, LOG_ERR, "failed loading storage module '%s' (errcode: %x)", driver, GetLastError()); if (handle != NULL) FreeLibrary((HMODULE) handle); #endif return st_FAILED; } /* make a new driver structure */ drv = (st_driver_t) calloc(1, sizeof(struct st_driver_st)); drv->handle = handle; drv->st = st; log_debug(ZONE, "calling driver initializer"); /* init */ if((init_fn)(drv) == st_FAILED) { log_write(st->log, LOG_NOTICE, "initialisation of storage driver '%s' failed", driver); free(drv); return st_FAILED; } /* add it to the drivers hash so we can find it later */ drv->name = pstrdup(xhash_pool(st->drivers), driver); xhash_put(st->drivers, drv->name, (void *) drv); log_write(st->log, LOG_NOTICE, "initialised storage driver '%s'", driver); } /* if its a default, set it up as such */ if(type == NULL) { st->default_drv = drv; return st_SUCCESS; } /* its a real type, so let the driver know */ if(type != NULL && (ret = (drv->add_type)(drv, type)) != st_SUCCESS) { log_debug(ZONE, "driver '%s' can't handle '%s' data", driver, type); return ret; } /* register the type */ xhash_put(st->types, pstrdup(xhash_pool(st->types), type), (void *) drv); return st_SUCCESS; }
/** pull values out of the config file */ static void _s2s_config_expand(s2s_t s2s) { char *str, secret[41]; config_elem_t elem; int i, r; set_debug_log_from_config(s2s->config); s2s->id = config_get_one(s2s->config, "id", 0); if(s2s->id == NULL) s2s->id = "s2s"; s2s->router_ip = config_get_one(s2s->config, "router.ip", 0); if(s2s->router_ip == NULL) s2s->router_ip = "127.0.0.1"; s2s->router_port = j_atoi(config_get_one(s2s->config, "router.port", 0), 5347); s2s->router_user = config_get_one(s2s->config, "router.user", 0); if(s2s->router_user == NULL) s2s->router_user = "******"; s2s->router_pass = config_get_one(s2s->config, "router.pass", 0); if(s2s->router_pass == NULL) s2s->router_pass = "******"; s2s->router_pemfile = config_get_one(s2s->config, "router.pemfile", 0); s2s->retry_init = j_atoi(config_get_one(s2s->config, "router.retry.init", 0), 3); s2s->retry_lost = j_atoi(config_get_one(s2s->config, "router.retry.lost", 0), 3); if((s2s->retry_sleep = j_atoi(config_get_one(s2s->config, "router.retry.sleep", 0), 2)) < 1) s2s->retry_sleep = 1; s2s->router_default = config_count(s2s->config, "router.non-default") ? 0 : 1; s2s->log_type = log_STDOUT; if(config_get(s2s->config, "log") != NULL) { if((str = config_get_attr(s2s->config, "log", 0, "type")) != NULL) { if(strcmp(str, "file") == 0) s2s->log_type = log_FILE; else if(strcmp(str, "syslog") == 0) s2s->log_type = log_SYSLOG; } } if(s2s->log_type == log_SYSLOG) { s2s->log_facility = config_get_one(s2s->config, "log.facility", 0); s2s->log_ident = config_get_one(s2s->config, "log.ident", 0); if(s2s->log_ident == NULL) s2s->log_ident = "jabberd/s2s"; } else if(s2s->log_type == log_FILE) s2s->log_ident = config_get_one(s2s->config, "log.file", 0); s2s->packet_stats = config_get_one(s2s->config, "stats.packet", 0); if(s2s->local_ip == NULL) s2s->local_ip = "0.0.0.0"; /* * If no origin IP is specified, use local IP as the originating one: * it makes most sense, at least for SSL'ized connections. * APPLE: make origin an array of addresses so that both IPv4 and IPv6 can be specified. */ s2s->local_ip = config_get_one(s2s->config, "local.ip", 0); if((elem = config_get(s2s->config, "local.origins.ip")) != NULL) { s2s->origin_ips = elem->values; s2s->origin_nips = elem->nvalues; } if (s2s->origin_nips == 0) { s2s->origin_ips = (char **)malloc(sizeof(s2s->origin_ips)); s2s->origin_ips[0] = strdup(s2s->local_ip); s2s->origin_nips = 1; } s2s->local_port = j_atoi(config_get_one(s2s->config, "local.port", 0), 0); if(config_get(s2s->config, "local.secret") != NULL) s2s->local_secret = strdup(config_get_one(s2s->config, "local.secret", 0)); else { for(i = 0; i < 40; i++) { r = (int) (36.0 * rand() / RAND_MAX); secret[i] = (r >= 0 && r <= 9) ? (r + 48) : (r + 87); } secret[40] = '\0'; s2s->local_secret = strdup(secret); } if(s2s->local_secret == NULL) s2s->local_secret = "secret"; s2s->local_pemfile = config_get_one(s2s->config, "local.pemfile", 0); s2s->local_cachain = config_get_one(s2s->config, "local.cachain", 0); s2s->local_verify_mode = j_atoi(config_get_one(s2s->config, "local.verify-mode", 0), 0); s2s->io_max_fds = j_atoi(config_get_one(s2s->config, "io.max_fds", 0), 1024); s2s->compression = (config_get(s2s->config, "io.compression") != NULL); s2s->stanza_size_limit = j_atoi(config_get_one(s2s->config, "io.limits.stanzasize", 0), 0); s2s->require_tls = j_atoi(config_get_one(s2s->config, "security.require_tls", 0), 0); s2s->enable_whitelist = j_atoi(config_get_one(s2s->config, "security.enable_whitelist", 0), 0); if((elem = config_get(s2s->config, "security.whitelist_domain")) != NULL) { _s2s_populate_whitelist_domains(s2s, elem->values, elem->nvalues); } s2s->check_interval = j_atoi(config_get_one(s2s->config, "check.interval", 0), 60); s2s->check_queue = j_atoi(config_get_one(s2s->config, "check.queue", 0), 60); s2s->check_keepalive = j_atoi(config_get_one(s2s->config, "check.keepalive", 0), 0); s2s->check_idle = j_atoi(config_get_one(s2s->config, "check.idle", 0), 86400); s2s->check_dnscache = j_atoi(config_get_one(s2s->config, "check.dnscache", 0), 300); s2s->retry_limit = j_atoi(config_get_one(s2s->config, "check.retry", 0), 300); if((elem = config_get(s2s->config, "lookup.srv")) != NULL) { s2s->lookup_srv = elem->values; s2s->lookup_nsrv = elem->nvalues; } s2s->resolve_aaaa = config_count(s2s->config, "lookup.resolve-ipv6") ? 1 : 0; s2s->dns_cache_enabled = config_count(s2s->config, "lookup.no-cache") ? 0 : 1; s2s->dns_bad_timeout = j_atoi(config_get_one(s2s->config, "lookup.bad-host-timeout", 0), 3600); s2s->dns_min_ttl = j_atoi(config_get_one(s2s->config, "lookup.min-ttl", 0), 30); if (s2s->dns_min_ttl < 5) s2s->dns_min_ttl = 5; s2s->dns_max_ttl = j_atoi(config_get_one(s2s->config, "lookup.max-ttl", 0), 86400); s2s->etc_hosts_ttl = j_atoi(config_get_one(s2s->config, "lookup.etc-hosts-ttl", 0), 86400); s2s->out_reuse = config_count(s2s->config, "out-conn-reuse") ? 1 : 0; }
/** pull values out of the config file */ static void _sm_config_expand(sm_t sm) { char *str; sm->id = config_get_one(sm->config, "id", 0); if(sm->id == NULL) sm->id = "localhost"; 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->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); }
/** 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); } } }
/** get a handle for the named module */ authreg_t authreg_init(c2s_t c2s, char *name) { char mod_fullpath[PATH_MAX], *modules_path; ar_module_init_fn init_fn = NULL; authreg_t ar; void *handle; /* load authreg module */ modules_path = config_get_one(c2s->config, "authreg.path", 0); if (modules_path != NULL) log_write(c2s->log, LOG_NOTICE, "modules search path: %s", modules_path); else log_write(c2s->log, LOG_NOTICE, "modules search path undefined, using default: "LIBRARY_DIR); log_write(c2s->log, LOG_INFO, "loading '%s' authreg module", name); #ifndef _WIN32 if (modules_path != NULL) snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", modules_path, name); else snprintf(mod_fullpath, PATH_MAX, "%s/authreg_%s.so", LIBRARY_DIR, name); handle = dlopen(mod_fullpath, RTLD_LAZY); if (handle != NULL) init_fn = dlsym(handle, "ar_init"); #else if (modules_path != NULL) snprintf(mod_fullpath, PATH_MAX, "%s\\authreg_%s.dll", modules_path, name); else snprintf(mod_fullpath, PATH_MAX, "authreg_%s.dll", name); handle = (void*) LoadLibrary(mod_fullpath); if (handle != NULL) init_fn = (ar_module_init_fn)GetProcAddress((HMODULE) handle, "ar_init"); #endif if (handle != NULL && init_fn != NULL) { log_debug(ZONE, "preloaded module '%s' (not initialized yet)", name); } else { #ifndef _WIN32 log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (%s)", name, dlerror()); if (handle != NULL) dlclose(handle); #else log_write(c2s->log, LOG_ERR, "failed loading authreg module '%s' (errcode: %x)", name, GetLastError()); if (handle != NULL) FreeLibrary((HMODULE) handle); #endif return NULL; } /* make a new one */ ar = (authreg_t) calloc(1, sizeof(struct authreg_st)); ar->c2s = c2s; /* call the initialiser */ if((init_fn)(ar) != 0) { log_write(c2s->log, LOG_ERR, "failed to initialize auth module '%s'", name); authreg_free(ar); return NULL; } /* we need user_exists(), at the very least */ if(ar->user_exists == NULL) { log_write(c2s->log, LOG_ERR, "auth module '%s' has no check for user existence", name); authreg_free(ar); return NULL; } /* its good */ log_write(c2s->log, LOG_NOTICE, "initialized auth module '%s'", name); return ar; }
int filter_load(router_t r) { char *filterfile; FILE *f; long size; char *buf; nad_t nad; int i, nfilters, filter, from, to, what, redirect, error, log; acl_t list_tail, acl; log_debug(ZONE, "loading filter"); if(r->filter != NULL) filter_unload(r); filterfile = config_get_one(r->config, "aci.filter", 0); if(filterfile == NULL) filterfile = CONFIG_DIR "/router-filter.xml"; f = fopen(filterfile, "rb"); if(f == NULL) { log_write(r->log, LOG_NOTICE, "couldn't open filter file %s: %s", filterfile, strerror(errno)); r->filter_load = time(NULL); return 0; } fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); buf = (char *) malloc(sizeof(char) * size); if (fread(buf, 1, size, f) != size || ferror(f)) { log_write(r->log, LOG_ERR, "couldn't read from filter file: %s", strerror(errno)); free(buf); fclose(f); return 1; } fclose(f); nad = nad_parse(buf, size); if(nad == NULL) { log_write(r->log, LOG_ERR, "couldn't parse filter file"); free(buf); return 1; } free(buf); list_tail = NULL; log_debug(ZONE, "building filter list"); nfilters = 0; filter = nad_find_elem(nad, 0, -1, "rule", 1); while(filter >= 0) { from = nad_find_attr(nad, filter, -1, "from", NULL); to = nad_find_attr(nad, filter, -1, "to", NULL); what = nad_find_attr(nad, filter, -1, "what", NULL); redirect = nad_find_attr(nad, filter, -1, "redirect", NULL); error = nad_find_attr(nad, filter, -1, "error", NULL); log = nad_find_attr(nad, filter, -1, "log", NULL); acl = (acl_t) calloc(1, sizeof(struct acl_s)); if(from >= 0) { if (NAD_AVAL_L(nad, from) == 0 ) acl->from = NULL; else { acl->from = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, from) + 1)); sprintf(acl->from, "%.*s", NAD_AVAL_L(nad, from), NAD_AVAL(nad, from)); } } if(to >= 0) { if (NAD_AVAL_L(nad, to) == 0 ) acl->to = NULL; else { acl->to = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, to) + 1)); sprintf(acl->to, "%.*s", NAD_AVAL_L(nad, to), NAD_AVAL(nad, to)); } } if(what >= 0) { if (NAD_AVAL_L(nad, what) == 0 || strncmp(NAD_AVAL(nad, what), "*", NAD_AVAL_L(nad, what)) == 0) acl->what = NULL; else { acl->what = (char *) malloc(sizeof(char) * (NAD_AVAL_L(nad, what) + 1)); sprintf(acl->what, "%.*s", NAD_AVAL_L(nad, what), NAD_AVAL(nad, what)); } } if(redirect >= 0) { if (NAD_AVAL_L(nad, redirect) == 0) acl->redirect = NULL; else { acl->redirect_len = NAD_AVAL_L(nad, redirect); acl->redirect = (char *) malloc(sizeof(char) * (acl->redirect_len + 1)); sprintf(acl->redirect, "%.*s", acl->redirect_len, NAD_AVAL(nad, redirect)); acl->error = stanza_err_REDIRECT; } } if(error >= 0) { acl->error = stanza_err_NOT_ALLOWED; for(i=0; _stanza_errors[i].code != NULL; i++) { if(_stanza_errors[i].name != NULL && strncmp(_stanza_errors[i].name, NAD_AVAL(nad, error), NAD_AVAL_L(nad, error)) == 0) { acl->error = stanza_err_BAD_REQUEST + i; break; } } } if(log >= 0) { acl->log = ! strncasecmp(NAD_AVAL(nad, log), "YES", NAD_AVAL_L(nad, log)); acl->log |= ! strncasecmp(NAD_AVAL(nad, log), "ON", NAD_AVAL_L(nad, log)); } if(list_tail != NULL) { list_tail->next = acl; list_tail = acl; } /* record the head of the list */ if(r->filter == NULL) { r->filter = acl; list_tail = acl; } log_debug(ZONE, "added %s rule: from=%s, to=%s, what=%s, redirect=%s, error=%d, log=%s", (acl->error?"deny":"allow"), acl->from, acl->to, acl->what, acl->redirect, acl->error, (acl->log?"yes":"no")); nfilters++; filter = nad_find_elem(nad, filter, -1, "rule", 0); } nad_free(nad); log_write(r->log, LOG_NOTICE, "loaded filters (%d rules)", nfilters); r->filter_load = time(NULL); return 0; }
/** 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); }
static char *_config_expandx(config_t c, const char *value, int l) { const char *var_value; #ifdef CONFIGEXPAND_GUARDED static char guard[] = "deadbeaf"; #endif // fprintf(stderr, "config_expand: Expanding '%s'\n", value); char *s = strndup(value, l); char *var_start, *var_end; while ((var_start = strstr(s, "${")) != 0) { // fprintf(stderr, "config_expand: processing '%s'\n", s); var_end = strstr(var_start + 2, "}"); if (var_end) { char *tail = var_end + 1; char *var = var_start + 2; *var_end = 0; // fprintf(stderr, "config_expand: Var '%s', tail is '%s'\n", var, tail); var_value = config_get_one(c, var, 0); if (var_value) { int len = (var_start - s) + strlen(tail) + strlen(var_value) + 1; #ifdef CONFIGEXPAND_GUARDED len += sizeof(guard); #endif char *expanded_str = (char *)calloc(len, 1); #ifdef CONFIGEXPAND_GUARDED char *p_guard = expanded_str + len - sizeof(guard); strncpy(p_guard, guard, sizeof(guard)); #endif char *p = expanded_str; strncpy(expanded_str, s, var_start - s); p += var_start - s; strcpy(p, var_value); p += strlen(var_value); strcpy(p, tail); free(s); s = expanded_str; } else { fprintf(stderr, "config_expand: Have no '%s' defined\n", var); free(s); s = 0; break; } } else { fprintf(stderr, "config_expand: } missmatch\n"); free(s); s = 0; break; } } if (s) { char *retval = pstrdup(xhash_pool(c->hash), s); free(s); return retval; } else { return 0; } }
int user_table_load(router_t r) { const char *userfile; FILE *f; long size; char *buf; nad_t nad; int nusers, user, name, secret; log_debug(ZONE, "loading user table"); if(r->users != NULL) xhash_free(r->users); r->users = xhash_new(51); userfile = config_get_one(r->config, "local.users", 0); if(userfile == NULL) userfile = CONFIG_DIR "/router-users.xml"; f = fopen(userfile, "rb"); if(f == NULL) { log_write(r->log, LOG_ERR, "couldn't open user table file %s: %s", userfile, strerror(errno)); return 1; } fseek(f, 0, SEEK_END); size = ftell(f); if(size < 0) { log_write(r->log, LOG_ERR, "couldn't seek user table file %s: %s", userfile, strerror(errno)); fclose(f); return 1; } if(size == 0) { log_write(r->log, LOG_ERR, "empty user table file %s", userfile); fclose(f); return 1; } fseek(f, 0, SEEK_SET); buf = (char *) malloc(sizeof(char) * size); if (fread(buf, 1, size, f) != size || ferror(f)) { log_write(r->log, LOG_ERR, "couldn't read from user table file: %s", strerror(errno)); free(buf); fclose(f); return 1; } fclose(f); nad = nad_parse(buf, size); if(nad == NULL) { log_write(r->log, LOG_ERR, "couldn't parse user table"); free(buf); return 1; } free(buf); nusers = 0; user = nad_find_elem(nad, 0, -1, "user", 1); while(user >= 0) { name = nad_find_elem(nad, user, -1, "name", 1); secret = nad_find_elem(nad, user, -1, "secret", 1); if(name < 0 || secret < 0 || NAD_CDATA_L(nad, name) <= 0 || NAD_CDATA_L(nad, secret) <= 0) { log_write(r->log, LOG_ERR, "malformed user entry in user table file, skipping"); continue; } log_debug(ZONE, "remembering user '%.*s'", NAD_CDATA_L(nad, name), NAD_CDATA(nad, name)); xhash_put(r->users, pstrdupx(xhash_pool(r->users), NAD_CDATA(nad, name), NAD_CDATA_L(nad, name)), pstrdupx(xhash_pool(r->users), NAD_CDATA(nad, secret), NAD_CDATA_L(nad, secret))); nusers++; user = nad_find_elem(nad, user, -1, "user", 0); } nad_free(nad); log_write(r->log, LOG_NOTICE, "loaded user table (%d users)", nusers); r->users_load = time(NULL); return 0; }