X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fserverconfig.c;h=30d76af3516cae4c81cbb60a718e938cc66fadf3;hb=805fddcf6431e784f9f77114782a90c9d12f9cbe;hp=8ff643c1e0f4fc126349a05cdba23d956d3ec844;hpb=413da0f8686910f5e627393157566ae729ca99c4;p=silc.git diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 8ff643c1..30d76af3 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -4,12 +4,11 @@ Author: Giovanni Giacobbi - Copyright (C) 1997 - 2002 Pekka Riikonen + Copyright (C) 1997 - 2007 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 @@ -68,14 +67,7 @@ /* Free the authentication fields in the specified struct * Expands to two instructions */ #define CONFIG_FREE_AUTH(__section__) \ - silc_free(__section__->passphrase); \ - if (__section__->publickeys) \ - silc_hash_table_free(__section__->publickeys); - -static void my_free_public_key(void *key, void *context, void *user_data) -{ - silc_pkcs_public_key_free(context); -} + silc_free(__section__->passphrase); /* Set default values to those parameters that have not been defined */ static void @@ -97,6 +89,7 @@ my_set_param_defaults(SilcServerConfigConnParams *params, 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 } @@ -118,18 +111,34 @@ my_find_param(SilcServerConfig config, const char *name) return NULL; } +/* SKR find callbcak */ + +static void my_find_callback(SilcSKR skr, SilcSKRFind find, + SilcSKRStatus status, SilcDList keys, + void *context) +{ + SilcSKRStatus *s = context; + + *s = status; + if (keys) + silc_dlist_uninit(keys); + + silc_skr_find_free(find); +} + /* parse an authdata according to its auth method */ -static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p, - void **auth_data, SilcUInt32 *auth_data_len) +static SilcBool my_parse_authdata(SilcAuthMethod auth_meth, const char *p, + void **auth_data, SilcUInt32 *auth_data_len, + SilcSKRKeyUsage usage, void *key_context) { if (auth_meth == SILC_AUTH_PASSWORD) { /* p is a plain text password */ 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_LANGUAGE); + SILC_STRING_LOCALE); *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char)); - silc_utf8_encode(p, strlen(p), SILC_STRING_LANGUAGE, *auth_data, + silc_utf8_encode(p, strlen(p), SILC_STRING_LOCALE, *auth_data, *auth_data_len); } else { *auth_data = (void *) strdup(p); @@ -139,41 +148,43 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p, } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) { /* p is a public key file name */ SilcPublicKey public_key; - SilcPublicKey cached_key; + SilcSKR skr = *auth_data; + SilcSKRFind find; + SilcSKRStatus status = SILC_SKR_NOT_FOUND; - 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(("Error while parsing config file: " - "Could not load public key file!")); - return FALSE; - } + if (!silc_pkcs_load_public_key(p, &public_key)) { + 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)) { + find = silc_skr_find_alloc(); + silc_skr_find_set_public_key(find, public_key); + silc_skr_find_set_usage(find, usage); + if (!key_context) + silc_skr_find_set_context(find, SILC_32_TO_PTR(usage)); + silc_skr_find(skr, NULL, find, my_find_callback, &status); + if (status == SILC_SKR_OK) { + /* Already added, ignore error */ 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 */ + return TRUE; } - /* The auth_data is a pointer to the hash table of public keys. */ - if (auth_data) { - if (*auth_data == NULL) - *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL, - NULL, NULL, - my_free_public_key, NULL, - TRUE); - silc_hash_table_add(*auth_data, public_key, public_key); + /* Add the public key to repository */ + status = silc_skr_add_public_key(skr, public_key, usage, + key_context ? key_context : + (void *)usage, NULL); + if (status != SILC_SKR_OK) { + SILC_SERVER_LOG_ERROR(("Error while adding public key \"%s\"", p)); + return FALSE; } - } else - abort(); + } return TRUE; } -static bool my_parse_publickeydir(const char *dirname, void **auth_data) +static int my_parse_publickeydir(const char *dirname, void **auth_data, + SilcSKRKeyUsage usage) { int total = 0; struct dirent *get_file; @@ -182,7 +193,7 @@ static bool my_parse_publickeydir(const char *dirname, void **auth_data) if (!(dp = opendir(dirname))) { SILC_SERVER_LOG_ERROR(("Error while parsing config file: " "Could not open directory \"%s\"", dirname)); - return FALSE; + return -1; } /* errors are not considered fatal */ @@ -205,13 +216,14 @@ static bool my_parse_publickeydir(const char *dirname, void **auth_data) 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++; + if (my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL, + usage, NULL)) + total++; } } SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname)); - return TRUE; + return total; } /* Callbacks */ @@ -221,15 +233,11 @@ SILC_CONFIG_CALLBACK(fetch_generic) SilcServerConfig config = (SilcServerConfig) context; int got_errno = 0; - if (!strcmp(name, "module_path")) { - CONFIG_IS_DOUBLE(config->module_path); - config->module_path = (*(char *)val ? strdup((char *) val) : NULL); - } - else if (!strcmp(name, "prefer_passphrase_auth")) { - config->prefer_passphrase_auth = *(bool *)val; + if (!strcmp(name, "prefer_passphrase_auth")) { + config->prefer_passphrase_auth = *(SilcBool *)val; } else if (!strcmp(name, "require_reverse_lookup")) { - config->require_reverse_lookup = *(bool *)val; + config->require_reverse_lookup = *(SilcBool *)val; } else if (!strcmp(name, "connections_max")) { config->param.connections_max = (SilcUInt32) *(int *)val; @@ -250,13 +258,13 @@ SILC_CONFIG_CALLBACK(fetch_generic) config->param.reconnect_interval_max = (SilcUInt32) *(int *)val; } else if (!strcmp(name, "reconnect_keep_trying")) { - config->param.reconnect_keep_trying = *(bool *)val; + config->param.reconnect_keep_trying = *(SilcBool *)val; } else if (!strcmp(name, "key_exchange_rekey")) { config->param.key_exchange_rekey = (SilcUInt32) *(int *)val; } else if (!strcmp(name, "key_exchange_pfs")) { - config->param.key_exchange_pfs = *(bool *)val; + config->param.key_exchange_pfs = *(SilcBool *)val; } else if (!strcmp(name, "channel_rekey_secs")) { config->channel_rekey_secs = (SilcUInt32) *(int *)val; @@ -283,13 +291,13 @@ SILC_CONFIG_CALLBACK(fetch_generic) (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "detach_disabled")) { - config->detach_disabled = *(bool *)val; + config->detach_disabled = *(SilcBool *)val; } else if (!strcmp(name, "detach_timeout")) { config->detach_timeout = (SilcUInt32) *(int *)val; } else if (!strcmp(name, "qos")) { - config->param.qos = *(bool *)val; + config->param.qos = *(SilcBool *)val; } else if (!strcmp(name, "qos_rate_limit")) { config->param.qos_rate_limit = *(SilcUInt32 *)val; @@ -303,10 +311,36 @@ SILC_CONFIG_CALLBACK(fetch_generic) 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 if (!strcmp(name, "http_server")) { + config->httpd = *(SilcBool *)val; + } + else if (!strcmp(name, "http_server_ip")) { + CONFIG_IS_DOUBLE(config->httpd_ip); + config->httpd_ip = (*(char *)val ? strdup((char *) val) : NULL); + } + else if (!strcmp(name, "http_server_port")) { + int port = *(int *)val; + if ((port <= 0) || (port > 65535)) { + SILC_SERVER_LOG_ERROR(("Error while parsing config file: " + "Invalid port number!")); + got_errno = SILC_CONFIG_EPRINTLINE; + goto got_err; + } + config->httpd_port = (SilcUInt16)port; + } + else if (!strcmp(name, "dynamic_server")) { + config->dynamic_server = *(SilcBool *)val; + } + else if (!strcmp(name, "local_channels")) { + config->local_channels = *(SilcBool *)val; + } else return SILC_CONFIG_EINTERNAL; @@ -342,10 +376,6 @@ SILC_CONFIG_CALLBACK(fetch_cipher) CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } - else if (!strcmp(name, "module")) { - CONFIG_IS_DOUBLE(tmp->module); - tmp->module = (*(char *)val ? strdup((char *) val) : NULL); - } else if (!strcmp(name, "keylength")) { tmp->key_length = *(SilcUInt32 *)val; } @@ -358,7 +388,6 @@ SILC_CONFIG_CALLBACK(fetch_cipher) got_err: silc_free(tmp->name); - silc_free(tmp->module); silc_free(tmp); config->tmp = NULL; return got_errno; @@ -390,10 +419,6 @@ SILC_CONFIG_CALLBACK(fetch_hash) CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } - else if (!strcmp(name, "module")) { - CONFIG_IS_DOUBLE(tmp->module); - tmp->module = (*(char *)val ? strdup((char *) val) : NULL); - } else if (!strcmp(name, "blocklength")) { tmp->block_length = *(int *)val; } @@ -406,7 +431,6 @@ SILC_CONFIG_CALLBACK(fetch_hash) got_err: silc_free(tmp->name); - silc_free(tmp->module); silc_free(tmp); config->tmp = NULL; return got_errno; @@ -551,6 +575,11 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) CONFIG_IS_DOUBLE(tmp->server_ip); tmp->server_ip = strdup((char *) val); } + else if (!strcmp(name, "public_ip")) { + SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface); + CONFIG_IS_DOUBLE(tmp->public_ip); + tmp->public_ip = strdup((char *) val); + } else if (!strcmp(name, "port")) { int port = *(int *)val; SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface); @@ -599,13 +628,10 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) CONFIG_IS_DOUBLE(server_info->public_key); /* 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.")); - return SILC_CONFIG_EPRINTLINE; - } + if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key)) { + SILC_SERVER_LOG_ERROR(("Error: Could not load public key file.")); + return SILC_CONFIG_EPRINTLINE; + } } else if (!strcmp(name, "privatekey")) { struct stat st; @@ -614,22 +640,21 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) /* Check the private key file permissions. */ if ((stat(file_tmp, &st)) != -1) { - if ((st.st_mode & 0777) != 0600) { + if (((st.st_mode & 0777) != 0600) && + ((st.st_mode & 0777) != 0640)) { SILC_SERVER_LOG_ERROR(("Wrong permissions in private key " "file \"%s\". The permissions must be " - "0600.", file_tmp)); + "0600 or 0640.", file_tmp)); return SILC_CONFIG_ESILENT; } } /* Try to load specified file, if fail stop config parsing */ - if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key, - "", 0, SILC_PKCS_FILE_BIN)) - if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key, - "", 0, SILC_PKCS_FILE_PEM)) { - SILC_SERVER_LOG_ERROR(("Error: Could not load private key file.")); - return SILC_CONFIG_EPRINTLINE; - } + if (!silc_pkcs_load_private_key(file_tmp, "", 0, + &server_info->private_key)) { + SILC_SERVER_LOG_ERROR(("Error: Could not load private key file.")); + return SILC_CONFIG_EPRINTLINE; + } } else return SILC_CONFIG_EINTERNAL; @@ -651,10 +676,10 @@ SILC_CONFIG_CALLBACK(fetch_logging) SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging); if (!strcmp(name, "timestamp")) { - config->logging_timestamp = *(bool *)val; + config->logging_timestamp = *(SilcBool *)val; } else if (!strcmp(name, "quicklogs")) { - config->logging_quick = *(bool *)val; + config->logging_quick = *(SilcBool *)val; } else if (!strcmp(name, "flushdelay")) { int flushdelay = *(int *)val; @@ -730,7 +755,10 @@ SILC_CONFIG_CALLBACK(fetch_connparam) config->tmp = NULL; return SILC_CONFIG_OK; } - SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams); + if (!tmp) { + SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams); + tmp->reconnect_keep_trying = TRUE; + } if (!strcmp(name, "name")) { CONFIG_IS_DOUBLE(tmp->name); @@ -755,13 +783,13 @@ SILC_CONFIG_CALLBACK(fetch_connparam) tmp->reconnect_interval_max = *(SilcUInt32 *)val; } else if (!strcmp(name, "reconnect_keep_trying")) { - tmp->reconnect_keep_trying = *(bool *)val; + tmp->reconnect_keep_trying = *(SilcBool *)val; } else if (!strcmp(name, "key_exchange_rekey")) { tmp->key_exchange_rekey = *(SilcUInt32 *)val; } else if (!strcmp(name, "key_exchange_pfs")) { - tmp->key_exchange_pfs = *(bool *)val; + tmp->key_exchange_pfs = *(SilcBool *)val; } else if (!strcmp(name, "version_protocol")) { CONFIG_IS_DOUBLE(tmp->version_protocol); @@ -777,10 +805,10 @@ SILC_CONFIG_CALLBACK(fetch_connparam) (*(char *)val ? strdup((char *) val) : NULL); } else if (!strcmp(name, "anonymous")) { - tmp->anonymous = *(bool *)val; + tmp->anonymous = *(SilcBool *)val; } else if (!strcmp(name, "qos")) { - tmp->qos = *(bool *)val; + tmp->qos = *(SilcBool *)val; } else if (!strcmp(name, "qos_rate_limit")) { tmp->qos_rate_limit = *(SilcUInt32 *)val; @@ -831,24 +859,31 @@ SILC_CONFIG_CALLBACK(fetch_client) else if (!strcmp(name, "passphrase")) { CONFIG_IS_DOUBLE(tmp->passphrase); if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, - (void **)&tmp->passphrase, - &tmp->passphrase_len)) { + (void *)&tmp->passphrase, + &tmp->passphrase_len, 0, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } } else if (!strcmp(name, "publickey")) { if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, - (void **)&tmp->publickeys, NULL)) { + (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_AUTH | + SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "publickeydir")) { - if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) { + if (my_parse_publickeydir((char *) val, + (void *)&config->server->repository, + SILC_SKR_USAGE_AUTH | + SILC_SKR_USAGE_KEY_AGREEMENT) < 0) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); @@ -903,24 +938,20 @@ SILC_CONFIG_CALLBACK(fetch_admin) else if (!strcmp(name, "passphrase")) { CONFIG_IS_DOUBLE(tmp->passphrase); if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, - (void **)&tmp->passphrase, - &tmp->passphrase_len)) { + (void *)&tmp->passphrase, + &tmp->passphrase_len, 0, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } } else if (!strcmp(name, "publickey")) { 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)) { + (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_SERVICE_AUTHORIZATION, tmp)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else return SILC_CONFIG_EINTERNAL; @@ -1008,8 +1039,8 @@ SILC_CONFIG_CALLBACK(fetch_server) else if (!strcmp(name, "passphrase")) { CONFIG_IS_DOUBLE(tmp->passphrase); if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, - (void **)&tmp->passphrase, - &tmp->passphrase_len)) { + (void *)&tmp->passphrase, + &tmp->passphrase_len, 0, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } @@ -1017,10 +1048,13 @@ SILC_CONFIG_CALLBACK(fetch_server) else if (!strcmp(name, "publickey")) { CONFIG_IS_DOUBLE(tmp->publickeys); if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, - (void **)&tmp->publickeys, NULL)) { + (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_AUTH | + SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); @@ -1031,7 +1065,7 @@ SILC_CONFIG_CALLBACK(fetch_server) } } else if (!strcmp(name, "backup")) { - tmp->backup_router = *(bool *)val; + tmp->backup_router = *(SilcBool *)val; } else return SILC_CONFIG_EINTERNAL; @@ -1084,8 +1118,8 @@ SILC_CONFIG_CALLBACK(fetch_router) else if (!strcmp(name, "passphrase")) { CONFIG_IS_DOUBLE(tmp->passphrase); if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, - (void **)&tmp->passphrase, - &tmp->passphrase_len)) { + (void *)&tmp->passphrase, + &tmp->passphrase_len, 0, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } @@ -1093,10 +1127,13 @@ SILC_CONFIG_CALLBACK(fetch_router) else if (!strcmp(name, "publickey")) { CONFIG_IS_DOUBLE(tmp->publickeys); if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, - (void **)&tmp->publickeys, NULL)) { + (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_AUTH | + SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); @@ -1107,7 +1144,7 @@ SILC_CONFIG_CALLBACK(fetch_router) } } else if (!strcmp(name, "initiator")) { - tmp->initiator = *(bool *)val; + tmp->initiator = *(SilcBool *)val; } else if (!strcmp(name, "backuphost")) { CONFIG_IS_DOUBLE(tmp->backup_replace_ip); @@ -1126,7 +1163,10 @@ SILC_CONFIG_CALLBACK(fetch_router) tmp->backup_replace_port = (SilcUInt16) port; } else if (!strcmp(name, "backuplocal")) { - tmp->backup_local = *(bool *)val; + tmp->backup_local = *(SilcBool *)val; + } + else if (!strcmp(name, "dynamic_connection")) { + tmp->dynamic_connection = *(SilcBool *)val; } else return SILC_CONFIG_EINTERNAL; @@ -1144,7 +1184,6 @@ SILC_CONFIG_CALLBACK(fetch_router) /* known config options tables */ static const SilcConfigTable table_general[] = { - { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, @@ -1169,13 +1208,18 @@ static const SilcConfigTable table_general[] = { { "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 }, + { "http_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "http_server_ip", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, + { "http_server_port", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "dynamic_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "local_channels", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { 0, 0, 0, 0 } }; static const SilcConfigTable table_cipher[] = { { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL }, - { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL }, { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL }, { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL }, { 0, 0, 0, 0 } @@ -1183,7 +1227,6 @@ static const SilcConfigTable table_cipher[] = { static const SilcConfigTable table_hash[] = { { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL }, - { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL }, { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL }, { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL }, { 0, 0, 0, 0 } @@ -1203,6 +1246,7 @@ static const SilcConfigTable table_pkcs[] = { static const SilcConfigTable table_serverinfo_c[] = { { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL}, + { "public_ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL}, { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL}, { 0, 0, 0, 0 } }; @@ -1258,11 +1302,11 @@ static const SilcConfigTable table_connparam[] = { { "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_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 }, + { "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 } }; @@ -1281,7 +1325,6 @@ static const SilcConfigTable table_admin[] = { { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL }, { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, - { "publickeydir", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL }, { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { 0, 0, 0, 0 } @@ -1312,6 +1355,7 @@ static const SilcConfigTable table_routerconn[] = { { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL }, { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL }, { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL }, + { "dynamic_connection", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL }, { 0, 0, 0, 0 } }; @@ -1351,12 +1395,12 @@ static void silc_server_config_set_defaults(SilcServerConfig config) /* Check for correctness of the configuration */ -static bool silc_server_config_check(SilcServerConfig config) +static SilcBool silc_server_config_check(SilcServerConfig config) { - bool ret = TRUE; + SilcBool ret = TRUE; SilcServerConfigServer *s; SilcServerConfigRouter *r; - bool b = FALSE; + SilcBool b = FALSE; /* ServerConfig is mandatory */ if (!config->server_info) { @@ -1364,6 +1408,24 @@ static bool silc_server_config_check(SilcServerConfig config) ret = FALSE; } + if (!config->server_info->public_key || + !config->server_info->private_key) { + SILC_SERVER_LOG_ERROR(("\nError: Server keypair is missing")); + ret = FALSE; + } + + if (!config->server_info->primary) { + SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `Primary' " + "in `ServerInfo'")); + ret = FALSE; + } + + if (!config->server_info->primary->server_ip) { + SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory field `Ip' " + "in `Primary' in `ServerInfo'")); + ret = FALSE; + } + /* RouterConnection sanity checks */ if (config->routers && config->routers->backup_router == TRUE && @@ -1373,13 +1435,6 @@ static bool silc_server_config_check(SilcServerConfig config) "connection. You have marked it incorrectly as backup router.")); ret = FALSE; } - 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; - } if (config->routers && config->routers->backup_router == TRUE && !config->servers && !config->routers->next) { SILC_SERVER_LOG_ERROR(( @@ -1399,10 +1454,16 @@ static bool silc_server_config_check(SilcServerConfig config) "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; @@ -1430,7 +1491,8 @@ static bool silc_server_config_check(SilcServerConfig config) configuration object. The SilcServerConfig must be freed by calling the silc_server_config_destroy function. */ -SilcServerConfig silc_server_config_alloc(const char *filename) +SilcServerConfig silc_server_config_alloc(const char *filename, + SilcServer server) { SilcServerConfig config_new; SilcConfigEntity ent; @@ -1446,6 +1508,8 @@ SilcServerConfig silc_server_config_alloc(const char *filename) /* general config defaults */ config_new->refcount = 1; config_new->logging_timestamp = TRUE; + config_new->param.reconnect_keep_trying = TRUE; + config_new->server = server; /* obtain a config file object */ file = silc_config_open(filename); @@ -1541,11 +1605,11 @@ void silc_server_config_destroy(SilcServerConfig config) 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); + silc_free(config->httpd_ip); /* Destroy Logging channels */ if (config->logging_info) @@ -1582,8 +1646,10 @@ void silc_server_config_destroy(SilcServerConfig config) 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); + if (si->public_key) + silc_pkcs_public_key_free(si->public_key); + if (si->private_key) + silc_pkcs_private_key_free(si->private_key); silc_free(si); } @@ -1592,12 +1658,10 @@ void silc_server_config_destroy(SilcServerConfig config) SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher, config->cipher) silc_free(di->name); - silc_free(di->module); silc_free(di); } SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash) silc_free(di->name); - silc_free(di->module); silc_free(di); } SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac) @@ -1655,7 +1719,7 @@ void silc_server_config_destroy(SilcServerConfig config) /* Registers configured ciphers. These can then be allocated by the server when needed. */ -bool silc_server_config_register_ciphers(SilcServer server) +SilcBool silc_server_config_register_ciphers(SilcServer server) { SilcServerConfig config = server->config; SilcServerConfigCipher *cipher = config->cipher; @@ -1681,70 +1745,6 @@ bool silc_server_config_register_ciphers(SilcServer server) silc_server_stop(server); exit(1); } - } else { -#ifdef SILC_SIM - /* Load (try at least) the crypto SIM module */ - char buf[1023], *alg_name; - SilcCipherObject cipher_obj; - SilcSim sim; - - memset(&cipher_obj, 0, sizeof(cipher_obj)); - cipher_obj.name = cipher->name; - cipher_obj.block_len = cipher->block_length; - cipher_obj.key_len = cipher->key_length * 8; - - /* build the libname */ - snprintf(buf, sizeof(buf), "%s/%s", config->module_path, - cipher->module); - sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0); - - alg_name = strdup(cipher->name); - if (strchr(alg_name, '-')) - *strchr(alg_name, '-') = '\0'; - - if (silc_sim_load(sim)) { - cipher_obj.set_key = - silc_sim_getsym(sim, silc_sim_symname(alg_name, - 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_symname(alg_name, - SILC_CIPHER_SIM_SET_KEY_WITH_STRING)); - SILC_LOG_DEBUG(("set_key_with_string=%p", - cipher_obj.set_key_with_string)); - cipher_obj.encrypt = - silc_sim_getsym(sim, silc_sim_symname(alg_name, - SILC_CIPHER_SIM_ENCRYPT_CBC)); - SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt)); - cipher_obj.decrypt = - silc_sim_getsym(sim, silc_sim_symname(alg_name, - SILC_CIPHER_SIM_DECRYPT_CBC)); - SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt)); - cipher_obj.context_len = - silc_sim_getsym(sim, silc_sim_symname(alg_name, - SILC_CIPHER_SIM_CONTEXT_LEN)); - SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len)); - - /* Put the SIM to the list of all SIM's in server */ - silc_dlist_add(server->sim, sim); - - silc_free(alg_name); - } else { - SILC_LOG_ERROR(("Error configuring ciphers")); - silc_sim_free(sim); - silc_server_stop(server); - exit(1); - } - - /* Register the cipher */ - silc_cipher_register(&cipher_obj); -#else - SILC_LOG_ERROR(("Dynamic module support not compiled, " - "can't load modules!")); - silc_server_stop(server); - exit(1); -#endif } cipher = cipher->next; } /* while */ @@ -1755,7 +1755,7 @@ bool silc_server_config_register_ciphers(SilcServer server) /* Registers configured hash functions. These can then be allocated by the server when needed. */ -bool silc_server_config_register_hashfuncs(SilcServer server) +SilcBool silc_server_config_register_hashfuncs(SilcServer server) { SilcServerConfig config = server->config; SilcServerConfigHash *hash = config->hash; @@ -1781,54 +1781,6 @@ bool silc_server_config_register_hashfuncs(SilcServer server) silc_server_stop(server); exit(1); } - } else { -#ifdef SILC_SIM - /* Load (try at least) the hash SIM module */ - SilcHashObject hash_obj; - SilcSim sim; - - memset(&hash_obj, 0, sizeof(hash_obj)); - hash_obj.name = hash->name; - hash_obj.block_len = hash->block_length; - hash_obj.hash_len = hash->digest_length; - - sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0); - - if ((silc_sim_load(sim))) { - hash_obj.init = - silc_sim_getsym(sim, silc_sim_symname(hash->name, - SILC_HASH_SIM_INIT)); - SILC_LOG_DEBUG(("init=%p", hash_obj.init)); - hash_obj.update = - silc_sim_getsym(sim, silc_sim_symname(hash->name, - SILC_HASH_SIM_UPDATE)); - SILC_LOG_DEBUG(("update=%p", hash_obj.update)); - hash_obj.final = - silc_sim_getsym(sim, silc_sim_symname(hash->name, - SILC_HASH_SIM_FINAL)); - SILC_LOG_DEBUG(("final=%p", hash_obj.final)); - hash_obj.context_len = - silc_sim_getsym(sim, silc_sim_symname(hash->name, - SILC_HASH_SIM_CONTEXT_LEN)); - SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len)); - - /* Put the SIM to the table of all SIM's in server */ - silc_dlist_add(server->sim, sim); - } else { - SILC_LOG_ERROR(("Error configuring hash functions")); - silc_sim_free(sim); - silc_server_stop(server); - exit(1); - } - - /* Register the hash function */ - silc_hash_register(&hash_obj); -#else - SILC_LOG_ERROR(("Dynamic module support not compiled, " - "can't load modules!")); - silc_server_stop(server); - exit(1); -#endif } hash = hash->next; } /* while */ @@ -1839,7 +1791,7 @@ bool silc_server_config_register_hashfuncs(SilcServer server) /* Registers configure HMACs. These can then be allocated by the server when needed. */ -bool silc_server_config_register_hmacs(SilcServer server) +SilcBool silc_server_config_register_hmacs(SilcServer server) { SilcServerConfig config = server->config; SilcServerConfigHmac *hmac = config->hmac; @@ -1871,32 +1823,9 @@ bool silc_server_config_register_hmacs(SilcServer server) /* Registers configured PKCS's. */ -bool silc_server_config_register_pkcs(SilcServer server) +SilcBool silc_server_config_register_pkcs(SilcServer server) { - SilcServerConfig config = server->config; - SilcServerConfigPkcs *pkcs = config->pkcs; - - SILC_LOG_DEBUG(("Registering configured PKCS")); - - if (!pkcs) - return FALSE; - - while (pkcs) { - int i; - for (i = 0; silc_default_pkcs[i].name; i++) - if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) { - silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]); - break; - } - if (!silc_pkcs_is_supported(pkcs->name)) { - SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name)); - silc_server_stop(server); - exit(1); - } - pkcs = pkcs->next; - } /* while */ - - return TRUE; + return FALSE; } /* Sets log files where log messages are saved by the server logger. */ @@ -1908,11 +1837,11 @@ void silc_server_config_setlogfiles(SilcServer server) SILC_LOG_DEBUG(("Setting configured log file names and options")); - 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); + 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, @@ -2083,12 +2012,12 @@ silc_server_config_find_backup_conn(SilcServer server, char *host) /* Returns TRUE if configuration for a router connection that we are initiating exists. */ -bool silc_server_config_is_primary_route(SilcServer server) +SilcBool silc_server_config_is_primary_route(SilcServer server) { SilcServerConfig config = server->config; SilcServerConfigRouter *serv = NULL; int i; - bool found = FALSE; + SilcBool found = FALSE; serv = config->routers; for (i = 0; serv; i++) {