X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fserverconfig.c;h=0afc3f39d67f77aaaf67d490672dc8c5a26c27f1;hb=c257b555225193e54d85daf541d29578b3c93882;hp=911caff0dde735085b13ccc4fa628097740cbe6e;hpb=382d15d447b7a95390decfa783836ae4fe255b3d;p=silc.git diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 911caff0..0afc3f39 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -2,9 +2,9 @@ serverconfig.c - Author: Johnny Mnemonic + Author: Giovanni Giacobbi - Copyright (C) 1997 - 2002 Pekka Riikonen + Copyright (C) 1997 - 2004 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 @@ -127,9 +127,9 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *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_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); @@ -149,7 +149,7 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p, } if (*auth_data && - silc_hash_table_find_ext(*auth_data, public_key, (void **)&cached_key, + 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); @@ -165,6 +165,8 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p, 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 @@ -303,6 +305,10 @@ SILC_CONFIG_CALLBACK(fetch_generic) else if (!strcmp(name, "qos_limit_usec")) { config->param.qos_limit_usec = *(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; @@ -460,7 +466,7 @@ SILC_CONFIG_CALLBACK(fetch_pkcs) 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 */ + /* Check the temporary struct's fields */ if (!tmp) /* discard empty sub-blocks */ return SILC_CONFIG_OK; if (!tmp->name) { @@ -495,22 +501,40 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface); SilcServerConfigServerInfo *server_info = config->server_info; - /* 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) { 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); - if (!tmp) - return SILC_CONFIG_OK; + + /* 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; @@ -576,7 +600,7 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) 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, @@ -586,10 +610,21 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) } } else if (!strcmp(name, "privatekey")) { + struct stat st; char *file_tmp = (char *) val; CONFIG_IS_DOUBLE(server_info->private_key); - /* try to load specified file, if fail stop config parsing */ + /* 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 */ 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, @@ -603,9 +638,13 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) return SILC_CONFIG_OK; got_err: - silc_free(tmp); - silc_free(config->tmp); - config->tmp = NULL; + /* 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; } @@ -693,7 +732,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); @@ -794,7 +836,7 @@ 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, + (void *)&tmp->passphrase, &tmp->passphrase_len)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; @@ -802,13 +844,13 @@ SILC_CONFIG_CALLBACK(fetch_client) } else if (!strcmp(name, "publickey")) { if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, - (void **)&tmp->publickeys, NULL)) { + (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)) { + if (!my_parse_publickeydir((char *) val, (void *)&tmp->publickeys)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } @@ -866,7 +908,7 @@ 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, + (void *)&tmp->passphrase, &tmp->passphrase_len)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; @@ -874,13 +916,13 @@ SILC_CONFIG_CALLBACK(fetch_admin) } else if (!strcmp(name, "publickey")) { if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, - (void **)&tmp->publickeys, NULL)) { + (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)) { + if (!my_parse_publickeydir((char *) val, (void *)&tmp->publickeys)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } @@ -951,6 +993,10 @@ SILC_CONFIG_CALLBACK(fetch_server) /* check the temporary struct's fields */ 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); @@ -967,7 +1013,7 @@ 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, + (void *)&tmp->passphrase, &tmp->passphrase_len)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; @@ -976,7 +1022,7 @@ 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 *)&tmp->publickeys, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } @@ -1014,6 +1060,10 @@ SILC_CONFIG_CALLBACK(fetch_router) if (type == SILC_CONFIG_ARG_BLOCK) { if (!tmp) /* discard empty sub-blocks */ return SILC_CONFIG_OK; + if (!tmp->host) { + got_errno = SILC_CONFIG_EMISSFIELDS; + goto got_err; + } SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers); config->tmp = NULL; @@ -1039,7 +1089,7 @@ 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, + (void *)&tmp->passphrase, &tmp->passphrase_len)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; @@ -1048,7 +1098,7 @@ 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 *)&tmp->publickeys, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } @@ -1124,6 +1174,7 @@ 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 }, + { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL }, { 0, 0, 0, 0 } }; @@ -1212,11 +1263,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 } }; @@ -1327,6 +1378,7 @@ static bool silc_server_config_check(SilcServerConfig config) "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(( @@ -1334,6 +1386,7 @@ static bool silc_server_config_check(SilcServerConfig config) "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(( @@ -1353,10 +1406,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; @@ -1400,6 +1459,7 @@ 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; /* obtain a config file object */ file = silc_config_open(filename); @@ -1438,6 +1498,7 @@ SilcServerConfig silc_server_config_alloc(const char *filename) } } silc_server_config_destroy(config_new); + silc_config_close(file); return NULL; } @@ -1495,6 +1556,7 @@ void silc_server_config_destroy(SilcServerConfig config) /* 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);