X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fserverconfig.c;h=ecc35e2fa799ca880a0c7ef696b60362246d1933;hp=d1c0ad37c10c7266136c81b61d9a7bd3c2c86ec1;hb=e5d8d3db6caa344b3d419b884556c21b15e7d123;hpb=f9b6b6d91114fc1249b53ad4a77b3f1e974d8eef diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index d1c0ad37..ecc35e2f 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -26,11 +26,13 @@ SilcServerConfigSection silc_server_config_sections[] = { { "[Cipher]", SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 }, { "[PKCS]", - SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 2 }, + SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 1 }, { "[Hash]", SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 }, { "[hmac]", SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 }, + { "[ServerKeys]", + SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, 2 }, { "[ServerInfo]", SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 }, { "[AdminInfo]", @@ -52,9 +54,7 @@ SilcServerConfigSection silc_server_config_sections[] = { { "[AdminConnection]", SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 }, { "[DenyConnection]", - SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 4 }, - { "[RedirectClient]", - SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT, 2 }, + SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 }, { "[motd]", SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 }, @@ -81,6 +81,8 @@ SilcServerConfig silc_server_config_alloc(char *filename) new->filename = filename; + SILC_LOG_DEBUG(("Loading config data from `%s'", filename)); + /* Open configuration file and parse it */ config_parse = NULL; buffer = NULL; @@ -107,6 +109,7 @@ void silc_server_config_free(SilcServerConfig config) { if (config) { silc_free(config->filename); + silc_free(config->server_keys); silc_free(config->server_info); silc_free(config->admin_info); silc_free(config->listen_port); @@ -117,7 +120,6 @@ void silc_server_config_free(SilcServerConfig config) silc_free(config->servers); silc_free(config->routers); silc_free(config->denied); - silc_free(config->redirect); silc_free(config->motd); silc_free(config); } @@ -132,8 +134,7 @@ void silc_server_config_free(SilcServerConfig config) int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer, SilcServerConfigParse *return_config) { - int i, begin; - unsigned int linenum; + int i, begin, linenum; char line[1024], *cp; SilcServerConfigSection *cptr = NULL; SilcServerConfigParse parse = *return_config, first = NULL; @@ -250,7 +251,7 @@ int silc_server_config_parse_lines(SilcServerConfig config, SilcServerConfigParse parse_config) { int ret, check = FALSE; - unsigned int checkmask; + uint32 checkmask; char *tmp; SilcServerConfigParse pc = parse_config; SilcBuffer line; @@ -267,7 +268,7 @@ int silc_server_config_parse_lines(SilcServerConfig config, /* Get number of tokens in line */ ret = silc_config_check_num_token(line); - if (ret != pc->section->maxfields) { + if (ret < pc->section->maxfields) { /* Bad line */ fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n", config->filename, pc->linenum, ret, @@ -339,18 +340,6 @@ int silc_server_config_parse_lines(SilcServerConfig config, break; } - /* Get key length */ - ret = silc_config_get_token(line, &tmp); - if (ret < 0) - break; - if (ret == 0) { - fprintf(stderr, "%s:%d: PKCS key length not defined\n", - config->filename, pc->linenum); - break; - } - config->pkcs->key_len = atoi(tmp); - silc_free(tmp); - check = TRUE; checkmask |= (1L << pc->section->type); break; @@ -443,6 +432,54 @@ int silc_server_config_parse_lines(SilcServerConfig config, checkmask |= (1L << pc->section->type); break; + case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS: + + if (!config->server_keys) + config->server_keys = silc_calloc(1, sizeof(*config->server_keys)); + + ret = silc_config_get_token(line, &tmp); + if (ret < 0) + break; + if (ret == 0) { + fprintf(stderr, "%s:%d: Public key name not defined\n", + config->filename, pc->linenum); + break; + } + + if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key, + SILC_PKCS_FILE_PEM)) + if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key, + SILC_PKCS_FILE_BIN)) { + fprintf(stderr, "%s:%d: Could not load public key file `%s'\n", + config->filename, pc->linenum, tmp); + break; + } + silc_free(tmp); + + ret = silc_config_get_token(line, &tmp); + if (ret < 0) + break; + if (ret == 0) { + fprintf(stderr, "%s:%d: Private key name not defined\n", + config->filename, pc->linenum); + break; + } + + if (!silc_pkcs_load_private_key(tmp, &config->server_keys->private_key, + SILC_PKCS_FILE_BIN)) + if (!silc_pkcs_load_private_key(tmp, + &config->server_keys->private_key, + SILC_PKCS_FILE_PEM)) { + fprintf(stderr, "%s:%d: Could not load private key file `%s'\n", + config->filename, pc->linenum, tmp); + break; + } + silc_free(tmp); + + check = TRUE; + checkmask |= (1L << pc->section->type); + break; + case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO: if (!config->server_info) @@ -520,13 +557,13 @@ int silc_server_config_parse_lines(SilcServerConfig config, SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port); - /* Get host */ - ret = silc_config_get_token(line, &config->listen_port->host); + /* Get local IP */ + ret = silc_config_get_token(line, &config->listen_port->local_ip); if (ret < 0) break; - /* Get remote IP */ - ret = silc_config_get_token(line, &config->listen_port->remote_ip); + /* Get listener IP */ + ret = silc_config_get_token(line, &config->listen_port->listener_ip); if (ret < 0) break; @@ -711,7 +748,7 @@ int silc_server_config_parse_lines(SilcServerConfig config, ret = silc_config_get_token(line, &tmp); if (ret < 0) break; - if (ret == 0) { + if (ret) { config->clients->port = atoi(tmp); silc_free(tmp); } @@ -811,6 +848,15 @@ int silc_server_config_parse_lines(SilcServerConfig config, silc_free(tmp); } + /* Check whether this connection is backup router connection */ + ret = silc_config_get_token(line, &tmp); + if (ret != -1) { + config->servers->backup_router = atoi(tmp); + if (config->servers->backup_router != 0) + config->servers->backup_router = TRUE; + silc_free(tmp); + } + check = TRUE; checkmask |= (1L << pc->section->type); break; @@ -823,9 +869,6 @@ int silc_server_config_parse_lines(SilcServerConfig config, ret = silc_config_get_token(line, &config->routers->host); if (ret < 0) break; - // if (ret == 0) - ///* Any host */ - // config->routers->host = strdup("*"); /* Get authentication method */ ret = silc_config_get_token(line, &tmp); @@ -908,6 +951,24 @@ int silc_server_config_parse_lines(SilcServerConfig config, silc_free(tmp); } + /* Check whether this connection is backup router connection */ + ret = silc_config_get_token(line, &tmp); + if (ret != -1) { + config->routers->backup_router = atoi(tmp); + if (config->routers->backup_router != 0) + config->routers->backup_router = TRUE; + silc_free(tmp); + } + + /* Check whether this backup is local (in cell) or remote (other cell) */ + ret = silc_config_get_token(line, &tmp); + if (ret != -1) { + config->routers->backup_local = atoi(tmp); + if (config->routers->backup_local != 0) + config->routers->backup_local = TRUE; + silc_free(tmp); + } + check = TRUE; checkmask |= (1L << pc->section->type); break; @@ -992,13 +1053,39 @@ int silc_server_config_parse_lines(SilcServerConfig config, break; case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION: - /* Not implemented yet */ - check = TRUE; - break; - case SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT: - /* Not implemented yet */ + SILC_SERVER_CONFIG_LIST_ALLOC(config->denied); + + /* Get host */ + ret = silc_config_get_token(line, &config->denied->host); + if (ret < 0) + break; + if (ret == 0) { + /* Any host */ + config->denied->host = strdup("*"); + fprintf(stderr, "warning: %s:%d: Denying all connections", + config->filename, pc->linenum); + } + + /* Get port */ + ret = silc_config_get_token(line, &tmp); + if (ret < 0) + break; + if (ret == 0) { + /* Any port */ + config->denied->port = 0; + } else { + config->denied->port = atoi(tmp); + silc_free(tmp); + } + + /* Get comment */ + ret = silc_config_get_token(line, &config->denied->comment); + if (ret < 0) + break; + check = TRUE; + checkmask |= (1L << pc->section->type); break; case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD: @@ -1029,9 +1116,6 @@ int silc_server_config_parse_lines(SilcServerConfig config, } pc = pc->next; - /* XXXX */ - // silc_free(pc->prev); - // pc->prev = NULL; } if (check == FALSE) @@ -1065,6 +1149,8 @@ int silc_server_config_parse_lines(SilcServerConfig config, config->clients = config->clients->prev; while (config->servers && config->servers->prev) config->servers = config->servers->prev; + while (config->admins && config->admins->prev) + config->admins = config->admins->prev; while (config->routers && config->routers->prev) config->routers = config->routers->prev; @@ -1076,7 +1162,7 @@ int silc_server_config_parse_lines(SilcServerConfig config, /* This function checks that the mask sent as argument includes all the sections that are mandatory in SILC server. */ -int silc_server_config_check_sections(unsigned int checkmask) +int silc_server_config_check_sections(uint32 checkmask) { if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) { @@ -1090,7 +1176,8 @@ int silc_server_config_check_sections(unsigned int checkmask) return FALSE; } - if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) { + if (!(checkmask & + (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) { return FALSE; } @@ -1114,7 +1201,7 @@ void silc_server_config_setlogfiles(SilcServerConfig config) { SilcServerConfigSectionLogging *log; char *info, *warning, *error, *fatal; - unsigned int info_size, warning_size, error_size, fatal_size; + uint32 info_size, warning_size, error_size, fatal_size; SILC_LOG_DEBUG(("Setting configured log file names")); @@ -1157,28 +1244,33 @@ void silc_server_config_setlogfiles(SilcServerConfig config) /* Registers configured ciphers. These can then be allocated by the server when needed. */ -void silc_server_config_register_ciphers(SilcServerConfig config) +bool silc_server_config_register_ciphers(SilcServerConfig config) { SilcServerConfigSectionAlg *alg; SilcServer server = (SilcServer)config->server; SILC_LOG_DEBUG(("Registering configured ciphers")); + if (!config->cipher) + return FALSE; + alg = config->cipher; while(alg) { if (!alg->sim_name) { - /* Crypto module is supposed to be built in. Nothing to be done - here except to test that the cipher really is built in. */ - SilcCipher tmp = NULL; - - if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) { - SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name)); + int i; + + for (i = 0; silc_default_ciphers[i].name; i++) + if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) { + silc_cipher_register(&silc_default_ciphers[i]); + break; + } + + if (!silc_cipher_is_supported(alg->alg_name)) { + SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name)); silc_server_stop(server); exit(1); } - silc_cipher_free(tmp); - #ifdef SILC_SIM } else { /* Load (try at least) the crypto SIM module */ @@ -1238,59 +1330,73 @@ void silc_server_config_register_ciphers(SilcServerConfig config) alg = alg->next; } + + return TRUE; } /* Registers configured PKCS's. */ -/* XXX: This really doesn't do anything now since we have statically - registered our PKCS's. This should be implemented when PKCS works - as SIM's. This checks now only that the PKCS user requested is - really out there. */ -void silc_server_config_register_pkcs(SilcServerConfig config) +bool silc_server_config_register_pkcs(SilcServerConfig config) { SilcServerConfigSectionAlg *alg = config->pkcs; SilcServer server = (SilcServer)config->server; - SilcPKCS tmp = NULL; SILC_LOG_DEBUG(("Registering configured PKCS")); - while(alg) { + if (!config->pkcs) + return FALSE; - if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) { - SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name)); + while(alg) { + int i; + + for (i = 0; silc_default_pkcs[i].name; i++) + if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) { + silc_pkcs_register(&silc_default_pkcs[i]); + break; + } + + if (!silc_pkcs_is_supported(alg->alg_name)) { + SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name)); silc_server_stop(server); exit(1); } - silc_free(tmp); alg = alg->next; } + + return TRUE; } /* Registers configured hash functions. These can then be allocated by the server when needed. */ -void silc_server_config_register_hashfuncs(SilcServerConfig config) +bool silc_server_config_register_hashfuncs(SilcServerConfig config) { SilcServerConfigSectionAlg *alg; SilcServer server = (SilcServer)config->server; SILC_LOG_DEBUG(("Registering configured hash functions")); + if (!config->hash_func) + return FALSE; + alg = config->hash_func; while(alg) { if (!alg->sim_name) { - /* Hash module is supposed to be built in. Nothing to be done - here except to test that the hash function really is built in. */ - SilcHash tmp = NULL; - - if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) { - SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name)); + int i; + + for (i = 0; silc_default_hash[i].name; i++) + if (!strcmp(silc_default_hash[i].name, alg->alg_name)) { + silc_hash_register(&silc_default_hash[i]); + break; + } + + if (!silc_hash_is_supported(alg->alg_name)) { + SILC_LOG_ERROR(("Unknown hash funtion `%s'", alg->alg_name)); silc_server_stop(server); exit(1); } - silc_hash_free(tmp); #ifdef SILC_SIM } else { @@ -1340,31 +1446,29 @@ void silc_server_config_register_hashfuncs(SilcServerConfig config) alg = alg->next; } + + return TRUE; } /* Registers configure HMACs. These can then be allocated by the server when needed. */ -void silc_server_config_register_hmacs(SilcServerConfig config) +bool silc_server_config_register_hmacs(SilcServerConfig config) { SilcServerConfigSectionAlg *alg; SilcServer server = (SilcServer)config->server; SILC_LOG_DEBUG(("Registering configured HMACs")); - if (!config->hmac) { - SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without " - "HMACs")); - silc_server_stop(server); - exit(1); - } + if (!config->hmac) + return FALSE; alg = config->hmac; while(alg) { SilcHmacObject hmac; if (!silc_hash_is_supported(alg->sim_name)) { - SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name)); + SILC_LOG_ERROR(("Unknown hash function `%s'", alg->sim_name)); silc_server_stop(server); exit(1); } @@ -1377,10 +1481,13 @@ void silc_server_config_register_hmacs(SilcServerConfig config) alg = alg->next; } + + return TRUE; } /* Returns client authentication information from server configuration - by host (name or ip). */ + by host (name or ip). If `port' is non-null then both name or IP and + the port must match. */ SilcServerConfigSectionClientConnection * silc_server_config_find_client_conn(SilcServerConfig config, @@ -1388,6 +1495,7 @@ silc_server_config_find_client_conn(SilcServerConfig config, { int i; SilcServerConfigSectionClientConnection *client = NULL; + bool match = FALSE; if (!host) return NULL; @@ -1399,7 +1507,14 @@ silc_server_config_find_client_conn(SilcServerConfig config, for (i = 0; client; i++) { if (silc_string_compare(client->host, host)) + match = TRUE; + + if (port && client->port && client->port != port) + match = FALSE; + + if (match) break; + client = client->next; } @@ -1410,7 +1525,8 @@ silc_server_config_find_client_conn(SilcServerConfig config, } /* Returns server connection info from server configuartion by host - (name or ip). */ + (name or ip). If `port' is non-null then both name or IP and the port + must match. */ SilcServerConfigSectionServerConnection * silc_server_config_find_server_conn(SilcServerConfig config, @@ -1418,6 +1534,7 @@ silc_server_config_find_server_conn(SilcServerConfig config, { int i; SilcServerConfigSectionServerConnection *serv = NULL; + bool match = FALSE; if (!host) return NULL; @@ -1428,7 +1545,14 @@ silc_server_config_find_server_conn(SilcServerConfig config, serv = config->servers; for (i = 0; serv; i++) { if (silc_string_compare(serv->host, host)) + match = TRUE; + + if (port && serv->port && serv->port != port) + match = FALSE; + + if (match) break; + serv = serv->next; } @@ -1447,6 +1571,7 @@ silc_server_config_find_router_conn(SilcServerConfig config, { int i; SilcServerConfigSectionServerConnection *serv = NULL; + bool match = FALSE; if (!host) return NULL; @@ -1457,7 +1582,14 @@ silc_server_config_find_router_conn(SilcServerConfig config, serv = config->routers; for (i = 0; serv; i++) { if (silc_string_compare(serv->host, host)) + match = TRUE; + + if (port && serv->port && serv->port != port) + match = FALSE; + + if (match) break; + serv = serv->next; } @@ -1467,6 +1599,47 @@ silc_server_config_find_router_conn(SilcServerConfig config, return serv; } +/* Returns TRUE if configuartion for a router connection that we are + initiating exists. */ + +bool silc_server_config_is_primary_route(SilcServerConfig config) +{ + int i; + SilcServerConfigSectionServerConnection *serv = NULL; + bool found = FALSE; + + serv = config->routers; + for (i = 0; serv; i++) { + if (serv->initiator == TRUE && serv->backup_router == FALSE) { + found = TRUE; + break; + } + + serv = serv->next; + } + + return found; +} + +/* Returns our primary connection configuration or NULL if we do not + have primary router configured. */ + +SilcServerConfigSectionServerConnection * +silc_server_config_get_primary_router(SilcServerConfig config) +{ + int i; + SilcServerConfigSectionServerConnection *serv = NULL; + + serv = config->routers; + for (i = 0; serv; i++) { + if (serv->initiator == TRUE && serv->backup_router == FALSE) + return serv; + serv = serv->next; + } + + return NULL; +} + /* Returns Admin connection configuration by host, username and/or nickname. */ @@ -1503,64 +1676,38 @@ silc_server_config_find_admin(SilcServerConfig config, return admin; } -/* Prints out example configuration file with default built in - configuration values. */ +/* Returns the Denied connection configuration by host and port. */ -void silc_server_config_print() +SilcServerConfigSectionDenyConnection * +silc_server_config_denied_conn(SilcServerConfig config, char *host, + int port) { - char *buf; - - buf = "\ -#\n\ -# Automatically generated example SILCd configuration file with default\n\ -# built in values. Use this as a guide to configure your SILCd configuration\n\ -# file for your system. For detailed description of different configuration\n\ -# sections refer to silcd(8) manual page.\n\ -#\n"; - /* -# -#+blowfish -#+twofish -#+rc5 -#+rc6 -#+3des - -# -#+md5 -#+sha1 - - -+lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333 - - -+Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi - - -+10.2.1.6:10.2.1.6:1333 + int i; + SilcServerConfigSectionDenyConnection *deny = NULL; + bool match = FALSE; - -+infologfile:silcd.log:10000 -#+warninglogfile:/var/log/silcd_warning.log:10000 -#+errorlogfile:ERROR.log:10000 -#+fatallogfile:/var/log/silcd_error.log: + if (!host) + return NULL; - - +1:100:100:100 - +2:200:300:400 + if (!config->denied) + return NULL; - -+10.2.1.199:priikone:333:1 + deny = config->denied; + for (i = 0; deny; i++) { + if (silc_string_compare(deny->host, host)) + match = TRUE; - -+10.2.1.199:priikone:priikone:1 + if (port && deny->port && deny->port != port) + match = FALSE; - + if (match) + break; - + deny = deny->next; + } - - - */ + if (!deny) + return NULL; - fprintf(stdout, "%s\n", buf); + return deny; }