serverconfig.c
- Author: Johnny Mnemonic <johnny@themnemonic.org>
+ Author: Giovanni Giacobbi <giovanni@giacobbi.net>
- Copyright (C) 1997 - 2002 Johnny Mnemonic
+ Copyright (C) 1997 - 2005 Pekka Riikonen
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.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "serverincludes.h"
#include "server_internal.h"
+#include <dirent.h>
#if 0
#define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
__type__ *findtmp, *tmp = (__type__ *) config->tmp; \
int got_errno = 0
+/* allocate the tmp field for fetching data */
+#define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
+ if (!tmp) { \
+ config->tmp = silc_calloc(1, sizeof(*findtmp)); \
+ tmp = (__type__ *) config->tmp; \
+ }
+
/* append the tmp field to the specified list */
#define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
if (!__list__) { \
(params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
- SET_PARAM_DEFAULT(connections_max_per_host,
+ SET_PARAM_DEFAULT(connections_max_per_host,
SILC_SERVER_MAX_CONNECTIONS_SINGLE);
SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
+ SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
+ SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
+ SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
+ SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
+ SET_PARAM_DEFAULT(chlimit, SILC_SERVER_CH_JOIN_LIMIT);
#undef SET_PARAM_DEFAULT
}
/* Find connection parameters by the parameter block name. */
static SilcServerConfigConnParams *
-my_find_param(SilcServerConfig config, const char *name, SilcUInt32 line)
+my_find_param(SilcServerConfig config, const char *name)
{
SilcServerConfigConnParams *param;
return param;
}
- SILC_SERVER_LOG_ERROR(("\nError while parsing config file at line %lu: "
- "Cannot find Param \"%s\".\n", line, name));
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Cannot find Params \"%s\".", name));
return NULL;
}
/* parse an authdata according to its auth method */
-static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p,
- SilcUInt32 line, void **auth_data,
- SilcUInt32 *auth_data_len)
+static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p,
+ void **auth_data, SilcUInt32 *auth_data_len)
{
if (auth_meth == SILC_AUTH_PASSWORD) {
/* p is a plain text password */
- if (auth_data)
- *auth_data = (void *) strdup(p);
- if (auth_data_len)
- *auth_data_len = (SilcUInt32) strlen(p);
+ if (auth_data && auth_data_len) {
+ if (!silc_utf8_valid(p, strlen(p))) {
+ *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
+ SILC_STRING_LOCALE);
+ *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
+ silc_utf8_encode(p, strlen(p), SILC_STRING_LOCALE, *auth_data,
+ *auth_data_len);
+ } else {
+ *auth_data = (void *) strdup(p);
+ *auth_data_len = (SilcUInt32) strlen(p);
+ }
+ }
} else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
/* p is a public key file name */
SilcPublicKey public_key;
+ SilcPublicKey cached_key;
if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
- SILC_SERVER_LOG_ERROR(("\nError while parsing config file at line %lu: "
- "Could not load public key file!\n", line));
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Could not load public key file!"));
return FALSE;
}
+ if (*auth_data &&
+ silc_hash_table_find_ext(*auth_data, public_key, (void *)&cached_key,
+ NULL, silc_hash_public_key, NULL,
+ silc_hash_public_key_compare, NULL)) {
+ silc_pkcs_public_key_free(public_key);
+ SILC_SERVER_LOG_WARNING(("Warning: public key file \"%s\" already "
+ "configured, ignoring this key", p));
+ return TRUE; /* non fatal error */
+ }
+
/* The auth_data is a pointer to the hash table of public keys. */
if (auth_data) {
if (*auth_data == NULL)
NULL, NULL,
my_free_public_key, NULL,
TRUE);
+ SILC_LOG_DEBUG(("Adding public key '%s' to authentication cache",
+ public_key->identifier));
silc_hash_table_add(*auth_data, public_key, public_key);
}
- } else {
- SILC_SERVER_LOG_ERROR(("\nError while parsing config file at line %lu: "
- "Unknown authentication method.\n", line));
+ } else
+ abort();
+
+ return TRUE;
+}
+
+static bool my_parse_publickeydir(const char *dirname, void **auth_data)
+{
+ int total = 0;
+ struct dirent *get_file;
+ DIR *dp;
+
+ if (!(dp = opendir(dirname))) {
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Could not open directory \"%s\"", dirname));
return FALSE;
}
+
+ /* errors are not considered fatal */
+ while ((get_file = readdir(dp))) {
+ const char *filename = get_file->d_name;
+ char buf[1024];
+ int dirname_len = strlen(dirname), filename_len = strlen(filename);
+ struct stat check_file;
+
+ /* Ignore "." and "..", and take files only with ".pub" suffix. */
+ if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
+ (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
+ continue;
+
+ memset(buf, 0, sizeof(buf));
+ snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
+ (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
+
+ if (stat(buf, &check_file) < 0) {
+ SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
+ strerror(errno)));
+ } else if (S_ISREG(check_file.st_mode)) {
+ my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL);
+ total++;
+ }
+ }
+
+ SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
return TRUE;
}
}
else if (!strcmp(name, "version_protocol")) {
CONFIG_IS_DOUBLE(config->param.version_protocol);
- config->param.version_protocol =
+ config->param.version_protocol =
(*(char *)val ? strdup((char *) val) : NULL);
}
else if (!strcmp(name, "version_software")) {
CONFIG_IS_DOUBLE(config->param.version_software);
- config->param.version_software =
+ config->param.version_software =
(*(char *)val ? strdup((char *) val) : NULL);
}
else if (!strcmp(name, "version_software_vendor")) {
CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
- config->param.version_software_vendor =
+ config->param.version_software_vendor =
(*(char *)val ? strdup((char *) val) : NULL);
}
+ else if (!strcmp(name, "detach_disabled")) {
+ config->detach_disabled = *(bool *)val;
+ }
+ else if (!strcmp(name, "detach_timeout")) {
+ config->detach_timeout = (SilcUInt32) *(int *)val;
+ }
+ else if (!strcmp(name, "qos")) {
+ config->param.qos = *(bool *)val;
+ }
+ else if (!strcmp(name, "qos_rate_limit")) {
+ config->param.qos_rate_limit = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "qos_bytes_limit")) {
+ config->param.qos_bytes_limit = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "qos_limit_sec")) {
+ config->param.qos_limit_sec = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "qos_limit_usec")) {
+ config->param.qos_limit_usec = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "channel_join_limit")) {
+ config->param.chlimit = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "debug_string")) {
+ CONFIG_IS_DOUBLE(config->debug_string);
+ config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
+ }
else
return SILC_CONFIG_EINTERNAL;
type, name, context));
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
if (!tmp->name) {
got_errno = SILC_CONFIG_EMISSFIELDS;
goto got_err;
}
- /* the temporary struct is ok, append it to the list */
+
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigCipher *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
/* Identify and save this value */
if (!strcmp(name, "name")) {
type, name, context));
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
got_errno = SILC_CONFIG_EMISSFIELDS;
goto got_err;
}
- /* the temporary struct in tmp is ok */
+
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
-
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigHash *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
/* Identify and save this value */
if (!strcmp(name, "name")) {
type, name, context));
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
got_errno = SILC_CONFIG_EMISSFIELDS;
goto got_err;
}
- /* the temporary struct is ok, append it to the list */
+
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigHmac *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
/* Identify and save this value */
if (!strcmp(name, "name")) {
SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
type, name, context));
if (type == SILC_CONFIG_ARG_BLOCK) {
- /* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ /* Check the temporary struct's fields */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
if (!tmp->name) {
got_errno = SILC_CONFIG_EMISSFIELDS;
goto got_err;
}
- /* the temporary struct is ok, append it to the list */
+
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigPkcs *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
/* Identify and save this value */
if (!strcmp(name, "name")) {
SILC_CONFIG_CALLBACK(fetch_serverinfo)
{
- SilcServerConfig config = (SilcServerConfig) context;
+ SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
SilcServerConfigServerInfo *server_info = config->server_info;
- int got_errno = 0;
- /* if there isn't the struct alloc it */
+ SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
+ type, name, context));
+
+ /* If there isn't the main struct alloc it */
if (!server_info)
config->server_info = server_info = (SilcServerConfigServerInfo *)
silc_calloc(1, sizeof(*server_info));
if (type == SILC_CONFIG_ARG_BLOCK) {
- /* check for mandatory inputs */
+ if (!strcmp(name, "primary")) {
+ if (server_info->primary) {
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Double primary specification."));
+ got_errno = SILC_CONFIG_EPRINTLINE;
+ goto got_err;
+ }
+ CONFIG_IS_DOUBLE(server_info->primary);
+
+ /* now check the temporary struct, don't accept empty block and
+ make sure all fields are there */
+ if (!tmp || !tmp->server_ip || !tmp->port) {
+ got_errno = SILC_CONFIG_EMISSFIELDS;
+ goto got_err;
+ }
+ server_info->primary = tmp;
+ config->tmp = NULL;
+ return SILC_CONFIG_OK;
+ } else if (!strcmp(name, "secondary")) {
+ if (!tmp)
+ return SILC_CONFIG_OK;
+ if (!tmp || !tmp->server_ip || !tmp->port) {
+ got_errno = SILC_CONFIG_EMISSFIELDS;
+ goto got_err;
+ }
+ SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
+ config->tmp = NULL;
+ return SILC_CONFIG_OK;
+ } else if (!server_info->public_key || !server_info->private_key) {
+ got_errno = SILC_CONFIG_EMISSFIELDS;
+ goto got_err;
+ }
return SILC_CONFIG_OK;
}
if (!strcmp(name, "hostname")) {
server_info->server_name = strdup((char *) val);
}
else if (!strcmp(name, "ip")) {
- CONFIG_IS_DOUBLE(server_info->server_ip);
- server_info->server_ip = strdup((char *) val);
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
+ CONFIG_IS_DOUBLE(tmp->server_ip);
+ tmp->server_ip = strdup((char *) val);
}
else if (!strcmp(name, "port")) {
int port = *(int *)val;
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
if ((port <= 0) || (port > 65535)) {
- SILC_SERVER_LOG_ERROR(("Error: line %lu: Invalid port number!\n", line));
- return SILC_CONFIG_ESILENT;
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Invalid port number!"));
+ got_errno = SILC_CONFIG_EPRINTLINE;
+ goto got_err;
}
- server_info->port = (SilcUInt16) port;
+ tmp->port = (SilcUInt16) port;
}
else if (!strcmp(name, "servertype")) {
CONFIG_IS_DOUBLE(server_info->server_type);
}
else if (!strcmp(name, "publickey")) {
char *file_tmp = (char *) val;
+ CONFIG_IS_DOUBLE(server_info->public_key);
- /* try to load specified file, if fail stop config parsing */
+ /* Try to load specified file, if fail stop config parsing */
if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
SILC_PKCS_FILE_PEM))
if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
SILC_PKCS_FILE_BIN)) {
- SILC_SERVER_LOG_ERROR(("Error: Could not load public key file.\n"));
- SILC_SERVER_LOG_ERROR((" line %lu: file \"%s\"\n", line, file_tmp));
- return SILC_CONFIG_ESILENT;
+ SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
+ return SILC_CONFIG_EPRINTLINE;
}
}
else if (!strcmp(name, "privatekey")) {
+ struct stat st;
char *file_tmp = (char *) val;
+ CONFIG_IS_DOUBLE(server_info->private_key);
+
+ /* Check the private key file permissions. */
+ if ((stat(file_tmp, &st)) != -1) {
+ if ((st.st_mode & 0777) != 0600) {
+ SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
+ "file \"%s\". The permissions must be "
+ "0600.", file_tmp));
+ return SILC_CONFIG_ESILENT;
+ }
+ }
- /* try to load specified file, if fail stop config parsing */
+ /* Try to load specified file, if fail stop config parsing */
if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
- SILC_PKCS_FILE_BIN))
+ "", 0, SILC_PKCS_FILE_BIN))
if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
- SILC_PKCS_FILE_PEM)) {
- SILC_SERVER_LOG_ERROR(("Error: Could not load private key file.\n"));
- SILC_SERVER_LOG_ERROR((" line %lu: file \"%s\"\n", line, file_tmp));
- return SILC_CONFIG_ESILENT;
+ "", 0, SILC_PKCS_FILE_PEM)) {
+ SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
+ return SILC_CONFIG_EPRINTLINE;
}
}
else
return SILC_CONFIG_OK;
got_err:
+ /* Here we need to check if tmp exists because this function handles
+ * misc data (multiple fields and single-only fields) */
+ if (tmp) {
+ silc_free(tmp->server_ip);
+ silc_free(tmp);
+ config->tmp = NULL;
+ }
return got_errno;
}
SILC_CONFIG_CALLBACK(fetch_logging)
{
- SilcServerConfig config = (SilcServerConfig) context;
- SilcServerConfigLogging *tmp =
- (SilcServerConfigLogging *) config->tmp;
- int got_errno;
+ SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
- if (!strcmp(name, "quicklogs")) {
+ if (!strcmp(name, "timestamp")) {
+ config->logging_timestamp = *(bool *)val;
+ }
+ else if (!strcmp(name, "quicklogs")) {
config->logging_quick = *(bool *)val;
}
else if (!strcmp(name, "flushdelay")) {
int flushdelay = *(int *)val;
if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
- SILC_SERVER_LOG_ERROR(("Error: line %lu: Invalid flushdelay value, use "
- "quicklogs if you want real-time logging.\n", line));
- return SILC_CONFIG_ESILENT;
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Invalid flushdelay value, use quicklogs if you "
+ "want real-time logging."));
+ return SILC_CONFIG_EPRINTLINE;
}
config->logging_flushdelay = (long) flushdelay;
}
+
+ /* The following istances happens only in Logging's sub-blocks, a match
+ for the sub-block name means that you should store the filename/maxsize
+ temporary struct to the proper logging channel.
+ If we get a match for "file" or "maxsize" this means that we are inside
+ a sub-sub-block and it is safe to alloc a new tmp. */
#define FETCH_LOGGING_CHAN(__chan__, __member__) \
else if (!strcmp(name, __chan__)) { \
if (!tmp) return SILC_CONFIG_OK; \
FETCH_LOGGING_CHAN("fatals", logging_fatals)
#undef FETCH_LOGGING_CHAN
else if (!strcmp(name, "file")) {
- if (!tmp) { /* FIXME: what the fuck is this? */
- config->tmp = silc_calloc(1, sizeof(*tmp));
- tmp = (SilcServerConfigLogging *) config->tmp;
- }
- if (tmp->file) {
- got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
+ CONFIG_IS_DOUBLE(tmp->file);
tmp->file = strdup((char *) val);
}
else if (!strcmp(name, "size")) {
{
SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
- SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
+ SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
type, name, context));
-
if (type == SILC_CONFIG_ARG_BLOCK) {
- if (!tmp)
+ /* check the temporary struct's fields */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
-
if (!tmp->name) {
got_errno = SILC_CONFIG_EMISSFIELDS;
goto got_err;
}
-
/* Set defaults */
my_set_param_defaults(tmp, &config->param);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
-
- /* if there isn't a temporary struct alloc one */
if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigConnParams *) config->tmp;
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
+ tmp->reconnect_keep_trying = TRUE;
}
if (!strcmp(name, "name")) {
}
else if (!strcmp(name, "version_software_vendor")) {
CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
- tmp->version_software_vendor =
+ tmp->version_software_vendor =
(*(char *)val ? strdup((char *) val) : NULL);
}
+ else if (!strcmp(name, "anonymous")) {
+ tmp->anonymous = *(bool *)val;
+ }
+ else if (!strcmp(name, "qos")) {
+ tmp->qos = *(bool *)val;
+ }
+ else if (!strcmp(name, "qos_rate_limit")) {
+ tmp->qos_rate_limit = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "qos_bytes_limit")) {
+ tmp->qos_bytes_limit = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "qos_limit_sec")) {
+ tmp->qos_limit_sec = *(SilcUInt32 *)val;
+ }
+ else if (!strcmp(name, "qos_limit_usec")) {
+ tmp->qos_limit_usec = *(SilcUInt32 *)val;
+ }
else
return SILC_CONFIG_EINTERNAL;
SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
type, name, context));
- /* alloc tmp before block checking (empty sub-blocks are welcome here) */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigClient *) config->tmp;
- }
+ /* Alloc before block checking, because empty sub-blocks are welcome here */
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
if (type == SILC_CONFIG_ARG_BLOCK) {
- /* closing the block */
+ /* empty sub-blocks are welcome */
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
else if (!strcmp(name, "passphrase")) {
CONFIG_IS_DOUBLE(tmp->passphrase);
- if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
- (void **)&tmp->passphrase,
+ if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
+ (void *)&tmp->passphrase,
&tmp->passphrase_len)) {
- got_errno = SILC_CONFIG_ESILENT;
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
else if (!strcmp(name, "publickey")) {
- if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
- (void **)&tmp->publickeys, NULL)) {
- got_errno = SILC_CONFIG_ESILENT;
+ if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
+ (void *)&tmp->publickeys, NULL)) {
+ got_errno = SILC_CONFIG_EPRINTLINE;
+ goto got_err;
+ }
+ }
+ else if (!strcmp(name, "publickeydir")) {
+ if (!my_parse_publickeydir((char *) val, (void *)&tmp->publickeys)) {
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
else if (!strcmp(name, "params")) {
CONFIG_IS_DOUBLE(tmp->param);
- tmp->param = my_find_param(config, (char *) val, line);
- if (!tmp->param) { /* error already output */
- got_errno = SILC_CONFIG_ESILENT;
+ tmp->param = my_find_param(config, (char *) val);
+ if (!tmp->param) { /* error message already output */
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
type, name, context));
-
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
-
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigAdmin *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
/* Identify and save this value */
if (!strcmp(name, "host")) {
}
else if (!strcmp(name, "passphrase")) {
CONFIG_IS_DOUBLE(tmp->passphrase);
- if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
- (void **)&tmp->passphrase,
+ if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
+ (void *)&tmp->passphrase,
&tmp->passphrase_len)) {
- got_errno = SILC_CONFIG_ESILENT;
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
else if (!strcmp(name, "publickey")) {
- CONFIG_IS_DOUBLE(tmp->publickeys);
- if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
- (void **)&tmp->publickeys, NULL)) {
- got_errno = SILC_CONFIG_ESILENT;
+ if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
+ (void *)&tmp->publickeys, NULL)) {
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
type, name, context));
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
if (!tmp->reason) {
got_errno = SILC_CONFIG_EMISSFIELDS;
goto got_err;
}
+
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigDeny *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
/* Identify and save this value */
if (!strcmp(name, "host")) {
SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
type, name, context));
-
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check the temporary struct's fields */
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
+ if (!tmp->host) {
+ got_errno = SILC_CONFIG_EMISSFIELDS;
+ goto got_err;
+ }
/* the temporary struct is ok, append it to the list */
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
-
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigServer *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
/* Identify and save this value */
if (!strcmp(name, "host")) {
}
else if (!strcmp(name, "passphrase")) {
CONFIG_IS_DOUBLE(tmp->passphrase);
- if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
- (void **)&tmp->passphrase,
+ if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
+ (void *)&tmp->passphrase,
&tmp->passphrase_len)) {
- got_errno = SILC_CONFIG_ESILENT;
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
else if (!strcmp(name, "publickey")) {
CONFIG_IS_DOUBLE(tmp->publickeys);
- if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
- (void **)&tmp->publickeys, NULL)) {
- got_errno = SILC_CONFIG_ESILENT;
+ if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
+ (void *)&tmp->publickeys, NULL)) {
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
- else if (!strcmp(name, "versionid")) {
- CONFIG_IS_DOUBLE(tmp->version);
- tmp->version = strdup((char *) val);
- }
else if (!strcmp(name, "params")) {
CONFIG_IS_DOUBLE(tmp->param);
- tmp->param = my_find_param(config, (char *) val, line);
- if (!tmp->param) { /* error already output */
- got_errno = SILC_CONFIG_ESILENT;
+ tmp->param = my_find_param(config, (char *) val);
+ if (!tmp->param) { /* error message already output */
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
got_err:
silc_free(tmp->host);
- silc_free(tmp->version);
CONFIG_FREE_AUTH(tmp);
silc_free(tmp);
config->tmp = NULL;
SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
type, name, context));
-
if (type == SILC_CONFIG_ARG_BLOCK) {
- if (!tmp) /* empty sub-block? */
+ if (!tmp) /* discard empty sub-blocks */
return SILC_CONFIG_OK;
+ if (!tmp->host) {
+ got_errno = SILC_CONFIG_EMISSFIELDS;
+ goto got_err;
+ }
- /* the temporary struct is ok, append it to the list */
SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
config->tmp = NULL;
return SILC_CONFIG_OK;
}
-
- /* if there isn't a temporary struct alloc one */
- if (!tmp) {
- config->tmp = silc_calloc(1, sizeof(*findtmp));
- tmp = (SilcServerConfigRouter *) config->tmp;
- }
+ SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
/* Identify and save this value */
if (!strcmp(name, "host")) {
else if (!strcmp(name, "port")) {
int port = *(int *)val;
if ((port <= 0) || (port > 65535)) {
- SILC_SERVER_LOG_ERROR(("Error: line %lu: Invalid port number!\n", line));
- return SILC_CONFIG_ESILENT;
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Invalid port number!"));
+ got_errno = SILC_CONFIG_EPRINTLINE;
+ goto got_err;
}
tmp->port = (SilcUInt16) port;
}
else if (!strcmp(name, "passphrase")) {
CONFIG_IS_DOUBLE(tmp->passphrase);
- if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
- (void **)&tmp->passphrase,
+ if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
+ (void *)&tmp->passphrase,
&tmp->passphrase_len)) {
- got_errno = SILC_CONFIG_ESILENT;
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
else if (!strcmp(name, "publickey")) {
CONFIG_IS_DOUBLE(tmp->publickeys);
- if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
- (void **)&tmp->publickeys, NULL)) {
- got_errno = SILC_CONFIG_ESILENT;
+ if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
+ (void *)&tmp->publickeys, NULL)) {
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
- else if (!strcmp(name, "versionid")) {
- CONFIG_IS_DOUBLE(tmp->version);
- tmp->version = strdup((char *) val);
- }
else if (!strcmp(name, "params")) {
CONFIG_IS_DOUBLE(tmp->param);
- tmp->param = my_find_param(config, (char *) val, line);
- if (!tmp->param) { /* error already output */
- got_errno = SILC_CONFIG_ESILENT;
+ tmp->param = my_find_param(config, (char *) val);
+ if (!tmp->param) { /* error message already output */
+ got_errno = SILC_CONFIG_EPRINTLINE;
goto got_err;
}
}
CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
strdup("*"));
+ tmp->backup_router = TRUE;
}
else if (!strcmp(name, "backupport")) {
int port = *(int *)val;
if ((port <= 0) || (port > 65535)) {
- SILC_SERVER_LOG_ERROR(("Error: line %lu: Invalid port number!\n", line));
- return SILC_CONFIG_ESILENT;
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
+ "Invalid port number!"));
+ got_errno = SILC_CONFIG_EPRINTLINE;
+ goto got_err;
}
tmp->backup_replace_port = (SilcUInt16) port;
}
got_err:
silc_free(tmp->host);
- silc_free(tmp->version);
silc_free(tmp->backup_replace_ip);
CONFIG_FREE_AUTH(tmp);
silc_free(tmp);
{ "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
{ "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
{ "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
- { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
- { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
- { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
+ { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
+ { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
+ { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
+ { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
+ { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
+ { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
+ { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
+ { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
+ { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
+ { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
+ { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
+ { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
{ 0, 0, 0, 0 }
};
{ 0, 0, 0, 0 }
};
-static const SilcConfigTable table_serverinfo[] = {
- { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
+static const SilcConfigTable table_serverinfo_c[] = {
{ "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
{ "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
+ { 0, 0, 0, 0 }
+};
+
+static const SilcConfigTable table_serverinfo[] = {
+ { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
+ { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
+ { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
{ "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
{ "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
{ "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
};
static const SilcConfigTable table_logging[] = {
+ { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
{ "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
{ "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
{ "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
{ "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
{ "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
{ "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
+ { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
+ { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
+ { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
+ { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
+ { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
+ { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
{ 0, 0, 0, 0 }
};
{ "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
{ "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
{ "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
+ { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
{ "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
{ 0, 0, 0, 0 }
};
{ "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
{ "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
{ "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
- { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
{ "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
{ "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
{ 0, 0, 0, 0 }
{ "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
{ "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
{ "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
- { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
{ "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
{ "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
{ "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
};
static const SilcConfigTable table_main[] = {
- { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
{ "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
{ "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
{ "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
{ "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
+ { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
{ "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
{ "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
{ "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
SILC_SERVER_CONNAUTH_TIMEOUT);
}
+/* Check for correctness of the configuration */
+
+static bool silc_server_config_check(SilcServerConfig config)
+{
+ bool ret = TRUE;
+ SilcServerConfigServer *s;
+ SilcServerConfigRouter *r;
+ bool b = FALSE;
+
+ /* ServerConfig is mandatory */
+ if (!config->server_info) {
+ SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
+ ret = FALSE;
+ }
+
+ /* RouterConnection sanity checks */
+
+ if (config->routers && config->routers->backup_router == TRUE &&
+ !config->servers) {
+ SILC_SERVER_LOG_ERROR((
+ "\nError: First RouterConnection block must be primary router "
+ "connection. You have marked it incorrectly as backup router."));
+ ret = FALSE;
+ }
+#if 0
+ if (config->routers && config->routers->initiator == FALSE &&
+ config->routers->backup_router == FALSE) {
+ SILC_SERVER_LOG_ERROR((
+ "\nError: First RouterConnection block must be primary router "
+ "connection and it must be marked as Initiator."));
+ ret = FALSE;
+ }
+#endif
+ if (config->routers && config->routers->backup_router == TRUE &&
+ !config->servers && !config->routers->next) {
+ SILC_SERVER_LOG_ERROR((
+ "\nError: You have configured backup router but not primary router. "
+ "If backup router is configured also primary router must be "
+ "configured."));
+ ret = FALSE;
+ }
+
+ /* Backup router sanity checks */
+
+ for (r = config->routers; r; r = r->next) {
+ if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
+ SILC_SERVER_LOG_ERROR((
+ "\nError: Backup router connection incorrectly configured to use "
+ "primary and backup router as same host `%s'. They must not be "
+ "same host.", r->host));
+ ret = FALSE;
+ }
+
+ if (r->initiator == FALSE && r->port != 0) {
+ SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
+ "specified. Ignoring Port value."));
+ r->port = 0;
+ }
+ }
+
+ /* ServerConnection sanity checks */
+
+ for (s = config->servers; s; s = s->next) {
+ if (s->backup_router) {
+ b = TRUE;
+ break;
+ }
+ }
+ if (b) {
+ for (s = config->servers; s; s = s->next) {
+ if (!s->backup_router) {
+ SILC_SERVER_LOG_ERROR((
+ "\nError: Your server is backup router but not all ServerConnection "
+ "blocks were marked as backup connections. They all must be "
+ "marked as backup connections."));
+ ret = FALSE;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
/* Allocates a new configuration object, opens configuration file and
- * parses it. The parsed data is returned to the newly allocated
- * configuration object. */
+ parses it. The parsed data is returned to the newly allocated
+ configuration object. The SilcServerConfig must be freed by calling
+ the silc_server_config_destroy function. */
-SilcServerConfig silc_server_config_alloc(SilcServer server,
- const char *filename)
+SilcServerConfig silc_server_config_alloc(const char *filename)
{
SilcServerConfig config_new;
SilcConfigEntity ent;
if (!config_new)
return NULL;
+ /* general config defaults */
+ config_new->refcount = 1;
+ config_new->logging_timestamp = TRUE;
+ config_new->param.reconnect_keep_trying = TRUE;
+
/* obtain a config file object */
file = silc_config_open(filename);
if (!file) {
- SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'\n",
+ SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
filename));
return NULL;
}
if (ret != SILC_CONFIG_ESILENT) {
char *linebuf, *filename = silc_config_get_filename(file);
SilcUInt32 line = silc_config_get_line(file);
- SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.\n",
- silc_config_strerror(ret)));
+ if (ret != SILC_CONFIG_EPRINTLINE)
+ SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
+ silc_config_strerror(ret)));
linebuf = silc_config_read_line(file, line);
- SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
- line, linebuf));
- silc_free(linebuf);
+ if (linebuf) {
+ SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
+ line, linebuf));
+ silc_free(linebuf);
+ }
}
silc_server_config_destroy(config_new);
+ silc_config_close(file);
return NULL;
}
/* close (destroy) the file object */
silc_config_close(file);
- /* If config_new is incomplete, abort the object and return NULL */
- if (!config_new->server_info) {
- SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block "
- "`server_info'\n"));
+ /* Check the configuration */
+ if (!silc_server_config_check(config_new)) {
silc_server_config_destroy(config_new);
return NULL;
}
- /* XXX are there any other mandatory sections in the config file? */
-
/* Set default to configuration parameters */
silc_server_config_set_defaults(config_new);
- silc_server_config_ref(&server->config_ref, config_new, config_new);
return config_new;
}
config->refcount++;
ref->config = config;
ref->ref_ptr = ref_ptr;
- SILC_LOG_DEBUG(("Referencing config [%p] refcnt %hu->%hu", config,
+ SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
config->refcount - 1, config->refcount));
}
}
void silc_server_config_unref(SilcServerConfigRef *ref)
{
- SilcServerConfig config = ref->config;
- if (ref->ref_ptr) {
- config->refcount--;
- SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %hu->%hu", config,
- config->refcount + 1, config->refcount));
- if (!config->refcount)
- silc_server_config_destroy(config);
- }
+ if (ref->ref_ptr)
+ silc_server_config_destroy(ref->config);
}
/* Destroy a config object with all his children lists */
{
void *tmp;
- if (config->refcount > 0) {
- config->refcount--;
- SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %hu->%hu", config,
- config->refcount + 1, config->refcount));
- if (config->refcount > 0)
- return;
- }
+ config->refcount--;
+ SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
+ config->refcount + 1, config->refcount));
+ if (config->refcount > 0)
+ return;
SILC_LOG_DEBUG(("Freeing config context"));
+ /* Destroy general config stuff */
silc_free(config->module_path);
+ silc_free(config->debug_string);
+ silc_free(config->param.version_protocol);
+ silc_free(config->param.version_software);
+ silc_free(config->param.version_software_vendor);
/* Destroy Logging channels */
if (config->logging_info)
silc_free(config->logging_errors->file);
if (config->logging_fatals)
silc_free(config->logging_fatals->file);
+ silc_free(config->logging_info);
+ silc_free(config->logging_warnings);
+ silc_free(config->logging_errors);
+ silc_free(config->logging_fatals);
/* Destroy the ServerInfo struct */
if (config->server_info) {
register SilcServerConfigServerInfo *si = config->server_info;
silc_free(si->server_name);
- silc_free(si->server_ip);
+ if (si->primary) {
+ silc_free(si->primary->server_ip);
+ silc_free(si->primary);
+ }
+ SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
+ si->secondary)
+ silc_free(di->server_ip);
+ silc_free(di);
+ }
silc_free(si->server_type);
silc_free(si->location);
silc_free(si->admin);
silc_free(si->group);
silc_free(si->motd_file);
silc_free(si->pid_file);
+ silc_pkcs_public_key_free(si->public_key);
+ silc_pkcs_private_key_free(si->private_key);
+ silc_free(si);
}
/* Now let's destroy the lists */
silc_free(di->name);
silc_free(di);
}
- SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient,
- config->clients)
+ SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
+ config->conn_params)
+ silc_free(di->name);
+ silc_free(di->version_protocol);
+ silc_free(di->version_software);
+ silc_free(di->version_software_vendor);
+ silc_free(di);
+ }
+ SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
silc_free(di->host);
CONFIG_FREE_AUTH(di);
silc_free(di);
SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
config->servers)
silc_free(di->host);
- silc_free(di->version);
CONFIG_FREE_AUTH(di);
silc_free(di);
}
SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
config->routers)
silc_free(di->host);
- silc_free(di->version);
silc_free(di->backup_replace_ip);
CONFIG_FREE_AUTH(di);
silc_free(di);
SILC_CIPHER_SIM_SET_KEY));
SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
cipher_obj.set_key_with_string =
- silc_sim_getsym(sim,
+ silc_sim_getsym(sim,
silc_sim_symname(alg_name,
SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
SILC_LOG_DEBUG(("set_key_with_string=%p",
silc_free(alg_name);
} else {
SILC_LOG_ERROR(("Error configuring ciphers"));
+ silc_sim_free(sim);
silc_server_stop(server);
exit(1);
}
silc_dlist_add(server->sim, sim);
} else {
SILC_LOG_ERROR(("Error configuring hash functions"));
+ silc_sim_free(sim);
silc_server_stop(server);
exit(1);
}
SILC_LOG_DEBUG(("Setting configured log file names and options"));
- silc_log_quick = config->logging_quick;
- silc_log_flushdelay = (config->logging_flushdelay ?
- config->logging_flushdelay :
- SILC_SERVER_LOG_FLUSH_DELAY);
+ silc_log_timestamp(config->logging_timestamp);
+ silc_log_quick(config->logging_quick);
+ silc_log_flushdelay(config->logging_flushdelay ?
+ config->logging_flushdelay :
+ SILC_SERVER_LOG_FLUSH_DELAY);
if ((this = config->logging_fatals))
silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
nickname. */
SilcServerConfigAdmin *
-silc_server_config_find_admin(SilcServer server, char *host, char *user,
+silc_server_config_find_admin(SilcServer server, char *host, char *user,
char *nick)
{
SilcServerConfig config = server->config;
return serv;
}
+/* Find backup router connection by host (name or ip) */
+
+SilcServerConfigRouter *
+silc_server_config_find_backup_conn(SilcServer server, char *host)
+{
+ SilcServerConfig config = server->config;
+ SilcServerConfigRouter *serv = NULL;
+
+ if (!host)
+ return NULL;
+
+ if (!config->routers)
+ return NULL;
+
+ for (serv = config->routers; serv; serv = serv->next) {
+ if (!serv->backup_router)
+ continue;
+ if (!silc_string_compare(serv->host, host))
+ continue;
+ break;
+ }
+
+ return serv;
+}
+
/* Returns TRUE if configuration for a router connection that we are
initiating exists. */
return NULL;
}
+
+/* If we have backup router configured that is going to replace us this
+ function returns it. */
+
+SilcServerConfigRouter *
+silc_server_config_get_backup_router(SilcServer server)
+{
+ SilcServerConfig config = server->config;
+ SilcServerConfigRouter *serv = NULL;
+ int i;
+
+ if (server->server_type != SILC_ROUTER)
+ return NULL;
+
+ serv = config->routers;
+ for (i = 0; serv; i++) {
+ if (serv->initiator == FALSE && serv->backup_router == TRUE &&
+ serv->backup_local == TRUE &&
+ !strcmp(server->config->server_info->primary->server_ip,
+ serv->backup_replace_ip) &&
+ server->config->server_info->primary->port ==
+ serv->backup_replace_port)
+ return serv;
+ serv = serv->next;
+ }
+
+ return NULL;
+}