📄 main.c
字号:
/* * jabberd - Jabber Open Source Server * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, * Ryan Eatmon, Robert Norris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA */#include "c2s.h"static sig_atomic_t c2s_shutdown = 0;sig_atomic_t c2s_lost_router = 0;static sig_atomic_t c2s_logrotate = 0;static void _c2s_signal(int signum){ c2s_shutdown = 1; c2s_lost_router = 0;}static void _c2s_signal_hup(int signum){ c2s_logrotate = 1;}/** store the process id */static void _c2s_pidfile(c2s_t c2s) { char *pidfile; FILE *f; pid_t pid; pidfile = config_get_one(c2s->config, "pidfile", 0); if(pidfile == NULL) return; pid = getpid(); if((f = fopen(pidfile, "w+")) == NULL) { log_write(c2s->log, LOG_ERR, "couldn't open %s for writing: %s", pidfile, strerror(errno)); return; } if(fprintf(f, "%d", pid) < 0) { log_write(c2s->log, LOG_ERR, "couldn't write to %s: %s", pidfile, strerror(errno)); return; } fclose(f); log_write(c2s->log, LOG_INFO, "process id is %d, written to %s", pid, pidfile);}/** pull values out of the config file */static void _c2s_config_expand(c2s_t c2s){ char *str, *ip, *mask; config_elem_t elem; int i; 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 = "jabberd"; c2s->router_pass = config_get_one(c2s->config, "router.pass", 0); if(c2s->router_pass == NULL) c2s->router_pass = "secret"; c2s->router_pemfile = config_get_one(c2s->config, "router.pemfile", 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->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); if(config_get(c2s->config, "local.require-starttls") != NULL) c2s->local_require_starttls = 1; c2s->local_cachain = config_get_one(c2s->config, "local.cachain", 0); c2s->local_ssl_port = j_atoi(config_get_one(c2s->config, "local.ssl-port", 0), 0); c2s->io_max_fds = j_atoi(config_get_one(c2s->config, "io.max_fds", 0), 1024); 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->ar_module_name = config_get_one(c2s->config, "authreg.module", 0); c2s->ar_register_enable = (config_get(c2s->config, "authreg.register.enable") != NULL); if(c2s->ar_register_enable) { c2s->ar_register_instructions = config_get_one(c2s->config, "authreg.register.instructions", 0); if(c2s->ar_register_instructions == NULL) c2s->ar_register_instructions = "Enter a username and password to register with this server."; } else c2s->ar_register_password = (config_get(c2s->config, "authreg.register.password") != NULL); 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.zerok") != NULL) c2s->ar_mechanisms |= AR_MECH_TRAD_ZEROK; if(config_get(c2s->config, "authreg.mechanisms.sasl.anonymous") != NULL) c2s->ar_mechanisms |= AR_MECH_SASL_ANONYMOUS; if(config_get(c2s->config, "authreg.mechanisms.sasl.plain") != NULL) c2s->ar_mechanisms |= AR_MECH_SASL_PLAIN; if(config_get(c2s->config, "authreg.mechanisms.sasl.digest-md5") != NULL) c2s->ar_mechanisms |= AR_MECH_SASL_DIGESTMD5; 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.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); } } 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 int _c2s_router_connect(c2s_t c2s) { log_write(c2s->log, LOG_NOTICE, "attempting connection to router at %s, port=%d", c2s->router_ip, c2s->router_port); c2s->fd = mio_connect(c2s->mio, c2s->router_port, c2s->router_ip, c2s_router_mio_callback, (void *) c2s); if(c2s->fd < 0) { if(errno == ECONNREFUSED) c2s_lost_router = 1; log_write(c2s->log, LOG_NOTICE, "connection attempt to router failed: %s (%d)", strerror(errno), errno); return 1; } c2s->router = sx_new(c2s->sx_env, c2s->fd, c2s_router_sx_callback, (void *) c2s); sx_client_init(c2s->router, 0, NULL, NULL, NULL, "1.0"); return 0;}static int _c2s_sx_sasl_callback(int cb, void *arg, void **res, scod_t sd, void *cbarg) { c2s_t c2s = (c2s_t) cbarg; sx_t s; char *realm, *my_realm, pass[257]; scod_cb_creds_t creds; struct jid_st jid; int i, r; switch(cb) { case sx_sasl_cb_GET_REALM: s = (sx_t) arg; realm = (char *) res; if(s->req_to == NULL) /* this shouldn't happen */ my_realm = ""; else { my_realm = xhash_get(c2s->realms, s->req_to); if(my_realm == NULL) my_realm = s->req_to; } strncpy(realm, my_realm, 256); log_debug(ZONE, "sx sasl callback: get realm: realm is '%s'", realm); break; case sx_sasl_cb_GET_PASS: creds = (scod_cb_creds_t) arg; log_debug(ZONE, "sx sasl callback: get pass (authnid=%s, realm=%s)", creds->authnid, creds->realm); if(*res == NULL) return 1; if((c2s->ar->get_password)(c2s->ar, creds->authnid, (creds->realm != NULL) ? creds->realm : "", pass) != 0) return 1; strncpy(* (char **) res, pass, 256); (* (char **) res)[256] = '\0'; return 0; case sx_sasl_cb_CHECK_PASS: creds = (scod_cb_creds_t) arg; log_debug(ZONE, "sx sasl callback: check pass (authnid=%s, realm=%s)", creds->authnid, creds->realm); if(c2s->ar->check_password != NULL) return (c2s->ar->check_password)(c2s->ar, creds->authnid, (creds->realm != NULL) ? creds->realm : "", creds->pass); if((c2s->ar->get_password)(c2s->ar, creds->authnid, (creds->realm != NULL) ? creds->realm : "", pass) != 0) return 1; return strcmp(creds->pass, pass); case sx_sasl_cb_CHECK_AUTHZID: creds = (scod_cb_creds_t) arg; s = (sx_t) sd->app_private; /* no authzid, we should build one */ if(creds->authzid[0] == '\0') snprintf(creds->authzid, 3072, "%s@%s", creds->authnid, s->req_to); /* authzid must be a valid jid */ jid.pc = c2s->pc; if(jid_reset(&jid, creds->authzid, 0) == NULL) return 1; /* and have domain == stream to addr */ if(strcmp(jid.domain, s->req_to) != 0) return 1; /* and have no resource */ if(jid.resource[0] != '\0') return 1; return 0; case sx_sasl_cb_GEN_AUTHZID: s = (sx_t) sd->app_private; jid.pc = c2s->pc; jid_reset(&jid, s->req_to, 0); for(i = 0; i < 256; i++) { r = (int) (36.0 * rand() / RAND_MAX); jid.node[i] = (r >= 0 && r <= 0) ? (r + 48) : (r + 87);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -