result mt_ns_usr_I(mpacket mp, void *arg) { session s = (session) arg; char *cmd = mt_packet_data(mp,0); if (j_strcmp(cmd,"USR") == 0) { char tp[500]; char *authdata = mt_packet_data(mp,4); mt_ssl_auth(s, authdata, tp); if(strcmp(tp, "") == 0) { mt_session_kill(s,TERROR_EXTERNAL); return r_ERR; } mt_stream_register(s->st,&mt_ns_usr_P,(void *) s); mt_cmd_usr_P(s->st,tp); } else if (j_strcmp(cmd,"XFR") == 0) mt_ns_xfr(mp,s); else if (j_atoi(cmd,0) == 911) mt_session_kill(s,(terror) {406,"Invalid Username"});/* 911 at this point means the username doesn't exit */ else if (j_atoi(cmd,0) != 0) mt_session_kill(s,TERROR_EXTERNAL); else return r_ERR; return r_DONE; }
result mt_ns_usr_P(mpacket mp, void *arg) { session s = (session) arg; char *cmd = mt_packet_data(mp,0); if (j_strcmp(cmd,"USR") == 0) /* auth was successful */ { log_debug(ZONE,"Auth successful for '%s' ",s->user); if (s->type == stype_register) { jpacket jp = mt_jpbuf_de(s->buff); s->type = stype_normal; jp->aux1 = (void *) s; mtq_send(s->q,jp->p,&mt_reg_success,(void *) jp); } else mt_user_sync(s); } else if (j_atoi(cmd,0) == 911) mt_session_kill(s,TERROR_AUTH); else if (j_atoi(cmd,0) != 0) { mt_ns_close(s); mt_ns_reconnect(s); /* some other wierd error, try again */ } else return r_ERR; return r_DONE; }
void mt_ns_rng(mpacket mp, session s) { sbchat sc; char *user = mt_packet_data(mp,5); char *sid, *chal, *host, *port; sc = xhash_get(s->chats,user); /* is there already is a SB session? */ if (sc != NULL) { if (sc->state == sb_START) { log_debug(ZONE,"SB Session with '%s' already started",user); return; } log_debug(ZONE,"Replacing SB session"); mt_chat_end(sc); } sid = mt_packet_data(mp,1); host = mt_packet_data(mp,2); chal = mt_packet_data(mp,4); port = strchr(host,':'); if (port != NULL) { *port = '\0'; port++; } mt_chat_join(s,user,host,j_atoi(port,1863),chal,sid); }
/** 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); }
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); } }
void mt_ns_xfr(mpacket mp, session s) { if (j_strcmp(mt_packet_data(mp,2),"NS") == 0) { char *host = mt_packet_data(mp,3); char *port = strchr(host,':'); if (port != NULL) { *port = '\0'; ++port; } mt_ns_close(s); mt_ns_connect(s,host,j_atoi(port,1863)); } else { log_debug(ZONE,"Session[%s], NS XFR Error, %s",jid_full(s->id),mt_packet_data(mp,2)); } }
result mt_ns_ver(mpacket mp, void *arg) { session s = (session) arg; char *cmd = mt_packet_data(mp,0); if (j_strcmp(cmd,"VER") == 0) { mt_stream_register(s->st,&mt_ns_cvr,(void *) s); mt_cmd_cvr(s->st, s->user); } else if (j_atoi(cmd,0) != 0) { /* The server is probably down */ log_debug(ZONE,"Session[%s], Error code %s, retrying",jid_full(s->id),cmd); mt_ns_close(s); mt_ns_reconnect(s); } else return r_ERR; return r_DONE; }
void jcr_queue_deliver(void *a) { extern jcr_instance jcr; GIOStatus rc = G_IO_STATUS_NORMAL; GString *buffer; gsize bytes; int left, len, pkts; dpacket d; GTimeVal timeout; int buf_size = j_atoi(xmlnode_get_data(xmlnode_get_tag(jcr->config,"send-buffer")), 8192); log_warn(JDBG, "packet delivery thread starting."); buffer = g_string_new(NULL); while(TRUE) { g_string_set_size(buffer, 0); pkts = 0; g_get_current_time(&timeout); g_time_val_add(&timeout, (5 * G_USEC_PER_SEC)); d = (dpacket)g_async_queue_timed_pop(jcr->dqueue, &timeout); if (d == NULL) { if (jcr->stream_state == _STREAM_CONNECTED) continue; else break; } g_string_append(buffer, xmlnode2str(d->x)); xmlnode_free(d->x); d = NULL; left = len = buffer->len; pkts++; while ((g_async_queue_length(jcr->dqueue) > 0) && (buffer->len < buf_size)) { d = (dpacket)g_async_queue_pop(jcr->dqueue); g_string_append(buffer, xmlnode2str(d->x)); xmlnode_free(d->x); d = NULL; left = len = buffer->len; pkts++; } // log_debug(JDBG, "%d '%s'", len, buf); while ((left > 0) && (rc == G_IO_STATUS_NORMAL)) { rc = g_io_channel_write_chars(jcr->gio, (buffer->str+(len - left)), left, &bytes, NULL); left = left - bytes; if (rc != G_IO_STATUS_NORMAL) { log_warn(JDBG, "Send packet failed, dropping packet"); } log_debug(JDBG, "wrote %d packets of %d bytes", pkts, bytes); // fprintf(stderr, "wrote %d packets of %d bytes\n", pkts, bytes); if (left==0){ //queue is empty, flushing the socket g_io_channel_flush(jcr->gio, NULL); } } } log_warn(JDBG, "packet delivery thread exiting."); log_warn(JDBG, " Last DvryQ Buffer='%.*s'", buffer->len, buffer->str); g_string_free(buffer, TRUE); }
/** Start up transport. Read configuration, register callbacks. */ void icqtrans(instance i, xmlnode x) { iti ti; pool p = i->p; xmlnode config; xmlnode cur; int check; log_debug(ZONE,"ICQ Transport, initializing for section '%s'",i->id); /* create new transport instance */ ti = pmalloco(p,sizeof(_iti)); ti->i = i; ti->xc = xdb_cache(i); config = xdb_get(ti->xc,jid_new(xmlnode_pool(x),"config@-internal"),"jabber:config:icqtrans"); if (config == NULL) { log_error(i->id,"Configuration not found!"); return; } ti->registration_instructions = pstrdup(p,xmlnode_get_tag_data(config,"instructions")); if (ti->registration_instructions == NULL) { log_debug(i->id,"Registration instructions not found"); } ti->search_instructions = pstrdup(p,xmlnode_get_tag_data(config,"search")); if (ti->search_instructions == NULL) { log_debug(i->id,"Search instructions not found"); } ti->charset = pstrdup(p,xmlnode_get_tag_data(config,"charset")); if (ti->charset == NULL) { log_debug(i->id,"Charset not specified, set default to %s ",DEFAULT_CHARSET); ti->charset = pstrdup(p,DEFAULT_CHARSET); } _ucs2utf = iconv_open("UTF-8","UCS-2BE"); _win2utf = iconv_open("UTF-8",ti->charset); if (_win2utf==(iconv_t)-1) { ti->charset = pstrdup(p,DEFAULT_CHARSET); _win2utf = iconv_open("UTF-8",ti->charset); if (_win2utf==(iconv_t)-1) { log_error(i->id,"Charset error!"); return; } } _utf2win = iconv_open(ti->charset,"UTF-8"); if (_utf2win ==(iconv_t)-1) { ti->charset = pstrdup(p,DEFAULT_CHARSET); _utf2win = iconv_open(ti->charset,"UTF-8"); if (_utf2win ==(iconv_t)-1) { log_error(i->id,"Charset error!"); return; } } log_notice("config","charset %s",ti->charset); ti->msg_chat = xmlnode_get_tag(config,"chat") ? 1 : 0; if (ti->msg_chat) { log_notice("config","chat messages enabled"); } ti->web_aware = xmlnode_get_tag(config,"web") ? 1 : 0; if (ti->web_aware) { log_notice("config","web presence enabled"); } ti->own_roster = xmlnode_get_tag(config,"own_roster") ? 1 : 0; if (ti->own_roster) { log_notice("config","JIT will use own roster"); } ti->no_jabber_roster = xmlnode_get_tag(config,"no_jabber_roster") ? 1 : 0; if (ti->no_jabber_roster) { log_notice("config","JIT willn't get users from jabber roster"); } ti->no_x_data = xmlnode_get_tag(config,"no_xdata") ? 1 : 0; if (ti->no_x_data) { log_notice("config","JIT will not use xdata"); } cur = xmlnode_get_tag(config,"sms"); if (cur) { ti->sms_id = pstrdup(p,xmlnode_get_tag_data(cur,"host")); if (ti->sms_id) { ti->sms_show = jit_show2status(xmlnode_get_tag_data(cur,"show")); if (ti->sms_show==ICQ_STATUS_NOT_IN_LIST) { ti->sms_show = ICQ_STATUS_ONLINE; } log_notice("config","sms host %s show: %d",ti->sms_id,ti->sms_show); ti->sms_status = pstrdup(p,xmlnode_get_tag_data(cur,"status")); if (ti->sms_status) { log_debug(ZONE,"sms st %s ",ti->sms_status); } ti->sms_name = pstrdup(p,xmlnode_get_tag_data(cur,"name")); if (ti->sms_name) { log_debug(ZONE,"sms name %s",ti->sms_name); } } } ti->count_file = pstrdup(p,xmlnode_get_tag_data(config,"user_count_file")); if (ti->count_file == NULL) { ti->count_file = "icqcount"; } log_notice("config","Using %s as count log file",ti->count_file); for (cur = xmlnode_get_firstchild(xmlnode_get_tag(config,"server")); cur != NULL; cur = xmlnode_get_nextsibling(cur)) { char * port; char * host; if (xmlnode_get_type(cur) != NTYPE_TAG) continue; if ((port = xmlnode_get_attrib(cur,"port")) == NULL) continue; if ((host = xmlnode_get_data(cur)) == NULL) continue; ti->auth_hosts[ti->auth_hosts_count] = pstrdup(p,host); ti->auth_ports[ti->auth_hosts_count] = j_atoi(port,5190); log_debug(ZONE,"Host %s port %d at pos %d", ti->auth_hosts[ti->auth_hosts_count], ti->auth_ports[ti->auth_hosts_count], ti->auth_hosts_count); ti->auth_hosts_count++; if (ti->auth_hosts_count >= MAX_AUTH_HOSTS) break; } if (ti->auth_hosts_count == 0) { log_alert("err","No hosts to auth icq client !. Using default"); ti->auth_hosts[ti->auth_hosts_count] = pstrdup(p,"205.188.179.233"); ti->auth_ports[ti->auth_hosts_count] = 5190; ti->auth_hosts_count++; } /* add queue for unknown packets */ ti->q = mtq_new(i->p); ti->sessions = wpxhash_new(j_atoi(xmlnode_get_tag_data(config,"prime"),509)); ti->sessions_alt = wpxhash_new(j_atoi(xmlnode_get_tag_data(config,"prime"),509)); SEM_INIT(ti->sessions_sem); ti->vcard = xmlnode_new_tag_pool(p,"vCard"); xmlnode_put_attrib(ti->vcard,"xmlns",NS_VCARD); xmlnode_insert_node(ti->vcard,xmlnode_get_firstchild(xmlnode_get_tag(config,"vCard"))); /* default 5 hours */ ti->session_timeout = j_atoi(xmlnode_get_tag_data(config,"session_timeout"),18000); log_notice("config","session_timeout in sec : %d",ti->session_timeout); ti->reconnect = j_atoi(xmlnode_get_tag_data(config,"reconnects"),0); log_notice("config","Number of reconnects for session %d",ti->reconnect); check = j_atoi(xmlnode_get_tag_data(config,"session_check"),10); log_notice("config","JIT will check session every %d sec",check); // ti->admin = xmlnode_dup(xmlnode_get_tag(config,"admin")); ti->start = time(NULL); /* Register callbacks */ register_phandler(i,o_DELIVER,it_receive,(void *) ti); register_shutdown(it_shutdown,(void *) ti); /* Start up heartbeat thread */ register_beat(check,it_sessions_check,(void *) ti); xmlnode_free(config); }
/** 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 _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); } } }
/* session thread */ mreturn mod_presence_out(mapi m, void *arg) { xmlnode pnew, delay, pold; modpres mp = (modpres) arg; session cur = NULL; int oldpri, newpri; char *priority; if (m->packet->type != JPACKET_PRESENCE) return M_IGNORE; if (m->packet->to != NULL || jpacket_subtype(m->packet) == JPACKET__PROBE || jpacket_subtype(m->packet) == JPACKET__ERROR) return M_PASS; log_debug("new presence from %s of %s", jid_full(m->s->id), xmlnode2str(m->packet->x)); /* pre-existing conditions (no, we are not an insurance company) */ oldpri = m->s->priority; /* check that the priority is in the valid range */ priority = xmlnode_get_tag_data(m->packet->x, "priority"); if (priority == NULL) { newpri = 0; } else { newpri = j_atoi(priority, 0); if (newpri < -128 || newpri > 127) { log_notice("mod_presence", "got presence with invalid priority value from %s", jid_full(m->s->id)); xmlnode_free(m->packet->x); return M_HANDLED; } } /* invisible mode is special, don't you wish you were special too? */ if (jpacket_subtype(m->packet) == JPACKET__INVISIBLE) { log_debug("handling invisible mode request"); /* if we get this and we're available, it means go unavail first then reprocess this packet, nifty trick :) */ if (oldpri >= -128) { js_session_from(m->s, jpacket_new(jutil_presnew (JPACKET__UNAVAILABLE, NULL, xmlnode_get_tag_data(m->packet->x,"status") ))); js_session_from(m->s, m->packet); return M_HANDLED; } /* now, pretend we come online :) */ /* (this is the handling of the reinjected invisible presence * or an initial invisible presence) */ mp->invisible = 1; mod_presence_roster(m, NULL); /* send out probes to users we are subscribed to */ m->s->priority = newpri; /* store presence in xdb? */ if (mp->conf->pres_to_xdb > 0) mod_presence_store(m); xmlnode_free(m->packet->x); /* we do not broadcast invisible presences without a to attribute */ return M_HANDLED; } /* our new presence */ pnew = xmlnode_dup(m->packet->x); /* store presence in xdb? */ if (mp->conf->pres_to_xdb > 0) mod_presence_store(m); /* stamp the sessions presence */ delay = xmlnode_insert_tag(pnew, "x"); xmlnode_put_attrib(delay, "xmlns", NS_DELAY); xmlnode_put_attrib(delay, "from", jid_full(m->s->id)); xmlnode_put_attrib(delay, "stamp", jutil_timestamp()); /* our old presence */ pold = m->s->presence; m->s->presence = pnew; m->s->priority = jutil_priority(pnew); log_debug("presence oldp %d newp %d", oldpri, m->s->priority); /* if we're going offline now, let everyone know */ if (m->s->priority < -128) { /* jutil_priority returns -129 in case the "type" attribute is missing */ if (!mp->invisible) /* bcc's don't get told if we were invisible */ _mod_presence_broadcast(m->s, mp->conf->bcc, m->packet->x, NULL); _mod_presence_broadcast(m->s, mp->A, m->packet->x, NULL); _mod_presence_broadcast(m->s, mp->I, m->packet->x, NULL); /* reset vars */ mp->invisible = 0; mp->A->next = NULL; mp->I = NULL; xmlnode_free(m->packet->x); xmlnode_free(pold); return M_HANDLED; } /* available presence updates, intersection of A and T */ if (oldpri >= -128 && !mp->invisible) { _mod_presence_broadcast_trusted(m->s, mp->A, m->packet->x); xmlnode_free(m->packet->x); xmlnode_free(pold); return M_HANDLED; } /* at this point we're coming out of the closet */ mp->invisible = 0; /* make sure we get notified for any presence about ourselves */ /* XXX: the following is the original code: it caused existing presences * to be stamped several times and the presence to be sent out twice. pnew = jutil_presnew(JPACKET__PROBE,jid_full(m->s->uid),NULL); xmlnode_put_attrib(pnew,"from",jid_full(m->s->uid)); js_session_from(m->s, jpacket_new(pnew)); */ /* XXX: I think this should be okay as well: */ /* send us all presences of our other resources */ for (cur = m->user->sessions; cur != NULL; cur = cur->next) { pool pool_for_existing_presence = NULL; xmlnode duplicated_presence = NULL; jpacket packet = NULL; /* skip our own session (and sanity check) */ if (cur == m->s || cur->presence == NULL) { continue; } /* send the presence to us: we need a new pool as js_session_to() will free the packet's pool */ pool_for_existing_presence = pool_new(); duplicated_presence = xmlnode_dup_pool(pool_for_existing_presence, cur->presence); xmlnode_put_attrib(duplicated_presence, "to", jid_full(m->user->id)); packet = jpacket_new(duplicated_presence); js_session_to(m->s, packet); } /* probe s10ns and populate A */ mod_presence_roster(m, mp->A); /* we broadcast this baby! */ _mod_presence_broadcast(m->s, mp->conf->bcc, m->packet->x, NULL); _mod_presence_broadcast(m->s, mp->A, m->packet->x, NULL); xmlnode_free(m->packet->x); xmlnode_free(pold); return M_HANDLED; }
/** 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); }
void dnsrv(instance i, xmlnode x) { xdbcache xc = NULL; xmlnode config = NULL; xmlnode iternode = NULL; dns_resend_list tmplist = NULL; /* Setup a struct to hold dns_io handles */ dns_io di; di = pmalloco(i->p, sizeof(_dns_io)); di->mempool = i->p; /* Load config from xdb */ xc = xdb_cache(i); config = xdb_get(xc, jid_new(xmlnode_pool(x), "config@-internal"), "jabber:config:dnsrv"); /* Build a list of services/resend hosts */ iternode = xmlnode_get_lastchild(config); while (iternode != NULL) { if (j_strcmp("resend", xmlnode_get_name(iternode)) != 0) { iternode = xmlnode_get_prevsibling(iternode); continue; } /* Allocate a new list node */ tmplist = pmalloco(di->mempool, sizeof(_dns_resend_list)); tmplist->service = pstrdup(di->mempool, xmlnode_get_attrib(iternode, "service")); tmplist->host = pstrdup(di->mempool, xmlnode_get_data(iternode)); /* Insert this node into the list */ tmplist->next = di->svclist; di->svclist = tmplist; /* Move to next child */ iternode = xmlnode_get_prevsibling(iternode); } log_debug(ZONE, "dnsrv debug: %s\n", xmlnode2str(config)); /* Setup the hash of dns_packet_list */ di->packet_table = xhash_new(j_atoi(xmlnode_get_attrib(config,"queuemax"),101)); di->packet_timeout = j_atoi(xmlnode_get_attrib(config,"queuetimeout"),60); register_beat(di->packet_timeout, dnsrv_beat_packets, (void *)di); /* Setup the internal hostname cache */ di->cache_table = xhash_new(j_atoi(xmlnode_get_attrib(config,"cachemax"),1999)); di->cache_timeout = j_atoi(xmlnode_get_attrib(config,"cachetimeout"),3600); /* 1 hour dns cache? XXX would be nice to get the right value from dns! */ xmlnode_free(config); /* spawn a thread that get's forked, and wait for it since it sets up the fd's */ pth_join(pth_spawn(PTH_ATTR_DEFAULT,(void*)dnsrv_thread,(void*)di),NULL); if(di->pid < 0) { log_error(i->id,"dnsrv failed to start, unable to fork and/or create pipes"); return; } /* Start IO thread */ pth_spawn(PTH_ATTR_DEFAULT, dnsrv_process_io, di); /* Register an incoming packet handler */ register_phandler(i, o_DELIVER, dnsrv_deliver, (void*)di); /* register a cleanup function */ pool_cleanup(i->p, dnsrv_shutdown, (void*)di); }