5 Author: Giovanni Giacobbi <giovanni@giacobbi.net>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "serverincludes.h"
23 #include "server_internal.h"
27 #define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
29 #define SERVER_CONFIG_DEBUG(fmt)
32 /* auto-declare needed variables for the common list parsing */
33 #define SILC_SERVER_CONFIG_SECTION_INIT(__type__) \
34 SilcServerConfig config = (SilcServerConfig) context; \
35 __type__ *findtmp, *tmp = (__type__ *) config->tmp; \
38 /* allocate the tmp field for fetching data */
39 #define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
41 config->tmp = silc_calloc(1, sizeof(*findtmp)); \
42 tmp = (__type__ *) config->tmp; \
45 /* append the tmp field to the specified list */
46 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
50 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
51 findtmp->next = tmp; \
54 /* loops all elements in a list and provides a di struct pointer of the
55 * specified type containing the current element */
56 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
57 for (tmp = (void *) __list__; tmp;) { \
58 __type__ *di = (__type__ *) tmp; \
59 tmp = (void *) di->next;
61 /* Set EDOUBLE error value and bail out if necessary */
62 #define CONFIG_IS_DOUBLE(__x__) \
64 got_errno = SILC_CONFIG_EDOUBLE; \
68 /* Free the authentication fields in the specified struct
69 * Expands to two instructions */
70 #define CONFIG_FREE_AUTH(__section__) \
71 silc_free(__section__->passphrase); \
72 if (__section__->publickeys) \
73 silc_hash_table_free(__section__->publickeys);
75 static void my_free_public_key(void *key, void *context, void *user_data)
77 silc_pkcs_public_key_free(context);
80 /* Set default values to those parameters that have not been defined */
82 my_set_param_defaults(SilcServerConfigConnParams *params,
83 SilcServerConfigConnParams *defaults)
85 #define SET_PARAM_DEFAULT(p, d) params->p = \
86 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
88 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
89 SET_PARAM_DEFAULT(connections_max_per_host,
90 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
91 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
92 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
93 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
94 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
95 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
96 SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
97 SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
98 SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
99 SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
101 #undef SET_PARAM_DEFAULT
104 /* Find connection parameters by the parameter block name. */
105 static SilcServerConfigConnParams *
106 my_find_param(SilcServerConfig config, const char *name)
108 SilcServerConfigConnParams *param;
110 for (param = config->conn_params; param; param = param->next) {
111 if (!strcasecmp(param->name, name))
115 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
116 "Cannot find Params \"%s\".", name));
121 /* parse an authdata according to its auth method */
122 static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p,
123 void **auth_data, SilcUInt32 *auth_data_len)
125 if (auth_meth == SILC_AUTH_PASSWORD) {
126 /* p is a plain text password */
127 if (auth_data && auth_data_len) {
128 if (!silc_utf8_valid(p, strlen(p))) {
129 *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
130 SILC_STRING_LANGUAGE);
131 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
132 silc_utf8_encode(p, strlen(p), SILC_STRING_LANGUAGE, *auth_data,
135 *auth_data = (void *) strdup(p);
136 *auth_data_len = (SilcUInt32) strlen(p);
139 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
140 /* p is a public key file name */
141 SilcPublicKey public_key;
142 SilcPublicKey cached_key;
144 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
145 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
146 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
147 "Could not load public key file!"));
152 silc_hash_table_find_ext(*auth_data, public_key, (void **)&cached_key,
153 NULL, silc_hash_public_key, NULL,
154 silc_hash_public_key_compare, NULL)) {
155 silc_pkcs_public_key_free(public_key);
156 SILC_SERVER_LOG_WARNING(("Warning: public key file \"%s\" already "
157 "configured, ignoring this key", p));
158 return TRUE; /* non fatal error */
161 /* The auth_data is a pointer to the hash table of public keys. */
163 if (*auth_data == NULL)
164 *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL,
166 my_free_public_key, NULL,
168 silc_hash_table_add(*auth_data, public_key, public_key);
176 static bool my_parse_publickeydir(const char *dirname, void **auth_data)
179 struct dirent *get_file;
182 if (!(dp = opendir(dirname))) {
183 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
184 "Could not open directory \"%s\"", dirname));
188 /* errors are not considered fatal */
189 while ((get_file = readdir(dp))) {
190 const char *filename = get_file->d_name;
192 int dirname_len = strlen(dirname), filename_len = strlen(filename);
193 struct stat check_file;
195 /* Ignore "." and "..", and take files only with ".pub" suffix. */
196 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
197 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
200 memset(buf, 0, sizeof(buf));
201 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
202 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
204 if (stat(buf, &check_file) < 0) {
205 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
207 } else if (S_ISREG(check_file.st_mode)) {
208 my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL);
213 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
219 SILC_CONFIG_CALLBACK(fetch_generic)
221 SilcServerConfig config = (SilcServerConfig) context;
224 if (!strcmp(name, "module_path")) {
225 CONFIG_IS_DOUBLE(config->module_path);
226 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
228 else if (!strcmp(name, "prefer_passphrase_auth")) {
229 config->prefer_passphrase_auth = *(bool *)val;
231 else if (!strcmp(name, "require_reverse_lookup")) {
232 config->require_reverse_lookup = *(bool *)val;
234 else if (!strcmp(name, "connections_max")) {
235 config->param.connections_max = (SilcUInt32) *(int *)val;
237 else if (!strcmp(name, "connections_max_per_host")) {
238 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
240 else if (!strcmp(name, "keepalive_secs")) {
241 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
243 else if (!strcmp(name, "reconnect_count")) {
244 config->param.reconnect_count = (SilcUInt32) *(int *)val;
246 else if (!strcmp(name, "reconnect_interval")) {
247 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
249 else if (!strcmp(name, "reconnect_interval_max")) {
250 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
252 else if (!strcmp(name, "reconnect_keep_trying")) {
253 config->param.reconnect_keep_trying = *(bool *)val;
255 else if (!strcmp(name, "key_exchange_rekey")) {
256 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
258 else if (!strcmp(name, "key_exchange_pfs")) {
259 config->param.key_exchange_pfs = *(bool *)val;
261 else if (!strcmp(name, "channel_rekey_secs")) {
262 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
264 else if (!strcmp(name, "key_exchange_timeout")) {
265 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
267 else if (!strcmp(name, "conn_auth_timeout")) {
268 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
270 else if (!strcmp(name, "version_protocol")) {
271 CONFIG_IS_DOUBLE(config->param.version_protocol);
272 config->param.version_protocol =
273 (*(char *)val ? strdup((char *) val) : NULL);
275 else if (!strcmp(name, "version_software")) {
276 CONFIG_IS_DOUBLE(config->param.version_software);
277 config->param.version_software =
278 (*(char *)val ? strdup((char *) val) : NULL);
280 else if (!strcmp(name, "version_software_vendor")) {
281 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
282 config->param.version_software_vendor =
283 (*(char *)val ? strdup((char *) val) : NULL);
285 else if (!strcmp(name, "detach_disabled")) {
286 config->detach_disabled = *(bool *)val;
288 else if (!strcmp(name, "detach_timeout")) {
289 config->detach_timeout = (SilcUInt32) *(int *)val;
291 else if (!strcmp(name, "qos")) {
292 config->param.qos = *(bool *)val;
294 else if (!strcmp(name, "qos_rate_limit")) {
295 config->param.qos_rate_limit = *(SilcUInt32 *)val;
297 else if (!strcmp(name, "qos_bytes_limit")) {
298 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
300 else if (!strcmp(name, "qos_limit_sec")) {
301 config->param.qos_limit_sec = *(SilcUInt32 *)val;
303 else if (!strcmp(name, "qos_limit_usec")) {
304 config->param.qos_limit_usec = *(SilcUInt32 *)val;
307 return SILC_CONFIG_EINTERNAL;
309 return SILC_CONFIG_OK;
315 SILC_CONFIG_CALLBACK(fetch_cipher)
317 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
319 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
320 type, name, context));
321 if (type == SILC_CONFIG_ARG_BLOCK) {
322 /* check the temporary struct's fields */
323 if (!tmp) /* discard empty sub-blocks */
324 return SILC_CONFIG_OK;
326 got_errno = SILC_CONFIG_EMISSFIELDS;
330 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
332 return SILC_CONFIG_OK;
334 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
336 /* Identify and save this value */
337 if (!strcmp(name, "name")) {
338 CONFIG_IS_DOUBLE(tmp->name);
339 tmp->name = strdup((char *) val);
341 else if (!strcmp(name, "module")) {
342 CONFIG_IS_DOUBLE(tmp->module);
343 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
345 else if (!strcmp(name, "keylength")) {
346 tmp->key_length = *(SilcUInt32 *)val;
348 else if (!strcmp(name, "blocklength")) {
349 tmp->block_length = *(SilcUInt32 *)val;
352 return SILC_CONFIG_EINTERNAL;
353 return SILC_CONFIG_OK;
356 silc_free(tmp->name);
357 silc_free(tmp->module);
363 SILC_CONFIG_CALLBACK(fetch_hash)
365 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
367 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
368 type, name, context));
369 if (type == SILC_CONFIG_ARG_BLOCK) {
370 /* check the temporary struct's fields */
371 if (!tmp) /* discard empty sub-blocks */
372 return SILC_CONFIG_OK;
373 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
374 got_errno = SILC_CONFIG_EMISSFIELDS;
378 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
380 return SILC_CONFIG_OK;
382 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
384 /* Identify and save this value */
385 if (!strcmp(name, "name")) {
386 CONFIG_IS_DOUBLE(tmp->name);
387 tmp->name = strdup((char *) val);
389 else if (!strcmp(name, "module")) {
390 CONFIG_IS_DOUBLE(tmp->module);
391 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
393 else if (!strcmp(name, "blocklength")) {
394 tmp->block_length = *(int *)val;
396 else if (!strcmp(name, "digestlength")) {
397 tmp->digest_length = *(int *)val;
400 return SILC_CONFIG_EINTERNAL;
401 return SILC_CONFIG_OK;
404 silc_free(tmp->name);
405 silc_free(tmp->module);
411 SILC_CONFIG_CALLBACK(fetch_hmac)
413 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
415 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
416 type, name, context));
417 if (type == SILC_CONFIG_ARG_BLOCK) {
418 /* check the temporary struct's fields */
419 if (!tmp) /* discard empty sub-blocks */
420 return SILC_CONFIG_OK;
421 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
422 got_errno = SILC_CONFIG_EMISSFIELDS;
426 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
428 return SILC_CONFIG_OK;
430 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
432 /* Identify and save this value */
433 if (!strcmp(name, "name")) {
434 CONFIG_IS_DOUBLE(tmp->name);
435 tmp->name = strdup((char *) val);
437 else if (!strcmp(name, "hash")) {
438 CONFIG_IS_DOUBLE(tmp->hash);
439 tmp->hash = strdup((char *) val);
441 else if (!strcmp(name, "maclength")) {
442 tmp->mac_length = *(int *)val;
445 return SILC_CONFIG_EINTERNAL;
446 return SILC_CONFIG_OK;
449 silc_free(tmp->name);
450 silc_free(tmp->hash);
456 SILC_CONFIG_CALLBACK(fetch_pkcs)
458 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
460 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
461 type, name, context));
462 if (type == SILC_CONFIG_ARG_BLOCK) {
463 /* check the temporary struct's fields */
464 if (!tmp) /* discard empty sub-blocks */
465 return SILC_CONFIG_OK;
467 got_errno = SILC_CONFIG_EMISSFIELDS;
471 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
473 return SILC_CONFIG_OK;
475 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
477 /* Identify and save this value */
478 if (!strcmp(name, "name")) {
479 CONFIG_IS_DOUBLE(tmp->name);
480 tmp->name = strdup((char *) val);
483 return SILC_CONFIG_EINTERNAL;
484 return SILC_CONFIG_OK;
487 silc_free(tmp->name);
493 SILC_CONFIG_CALLBACK(fetch_serverinfo)
495 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
496 SilcServerConfigServerInfo *server_info = config->server_info;
498 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
499 type, name, context));
501 /* if there isn't the main struct alloc it */
503 config->server_info = server_info = (SilcServerConfigServerInfo *)
504 silc_calloc(1, sizeof(*server_info));
506 if (type == SILC_CONFIG_ARG_BLOCK) {
507 if (!strcmp(name, "primary")) {
508 if (server_info->primary) {
509 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
510 "Double primary specification."));
511 got_errno = SILC_CONFIG_EPRINTLINE;
514 CONFIG_IS_DOUBLE(server_info->primary);
516 /* now check the temporary struct, don't accept empty block and
517 make sure all fields are there */
518 if (!tmp || !tmp->server_ip || !tmp->port) {
519 got_errno = SILC_CONFIG_EMISSFIELDS;
522 server_info->primary = tmp;
524 return SILC_CONFIG_OK;
525 } else if (!strcmp(name, "secondary")) {
527 return SILC_CONFIG_OK;
528 if (!tmp || !tmp->server_ip || !tmp->port) {
529 got_errno = SILC_CONFIG_EMISSFIELDS;
532 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
534 return SILC_CONFIG_OK;
535 } else if (!server_info->public_key || !server_info->private_key) {
536 got_errno = SILC_CONFIG_EMISSFIELDS;
539 return SILC_CONFIG_OK;
541 if (!strcmp(name, "hostname")) {
542 CONFIG_IS_DOUBLE(server_info->server_name);
543 server_info->server_name = strdup((char *) val);
545 else if (!strcmp(name, "ip")) {
546 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
547 CONFIG_IS_DOUBLE(tmp->server_ip);
548 tmp->server_ip = strdup((char *) val);
550 else if (!strcmp(name, "port")) {
551 int port = *(int *)val;
552 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
553 if ((port <= 0) || (port > 65535)) {
554 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
555 "Invalid port number!"));
556 got_errno = SILC_CONFIG_EPRINTLINE;
559 tmp->port = (SilcUInt16) port;
561 else if (!strcmp(name, "servertype")) {
562 CONFIG_IS_DOUBLE(server_info->server_type);
563 server_info->server_type = strdup((char *) val);
565 else if (!strcmp(name, "admin")) {
566 CONFIG_IS_DOUBLE(server_info->admin);
567 server_info->admin = strdup((char *) val);
569 else if (!strcmp(name, "adminemail")) {
570 CONFIG_IS_DOUBLE(server_info->email);
571 server_info->email = strdup((char *) val);
573 else if (!strcmp(name, "location")) {
574 CONFIG_IS_DOUBLE(server_info->location);
575 server_info->location = strdup((char *) val);
577 else if (!strcmp(name, "user")) {
578 CONFIG_IS_DOUBLE(server_info->user);
579 server_info->user = strdup((char *) val);
581 else if (!strcmp(name, "group")) {
582 CONFIG_IS_DOUBLE(server_info->group);
583 server_info->group = strdup((char *) val);
585 else if (!strcmp(name, "motdfile")) {
586 CONFIG_IS_DOUBLE(server_info->motd_file);
587 server_info->motd_file = strdup((char *) val);
589 else if (!strcmp(name, "pidfile")) {
590 CONFIG_IS_DOUBLE(server_info->pid_file);
591 server_info->pid_file = strdup((char *) val);
593 else if (!strcmp(name, "publickey")) {
594 char *file_tmp = (char *) val;
595 CONFIG_IS_DOUBLE(server_info->public_key);
597 /* try to load specified file, if fail stop config parsing */
598 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
600 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
601 SILC_PKCS_FILE_BIN)) {
602 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
603 return SILC_CONFIG_EPRINTLINE;
606 else if (!strcmp(name, "privatekey")) {
607 char *file_tmp = (char *) val;
608 CONFIG_IS_DOUBLE(server_info->private_key);
610 /* try to load specified file, if fail stop config parsing */
611 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
612 "", 0, SILC_PKCS_FILE_BIN))
613 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
614 "", 0, SILC_PKCS_FILE_PEM)) {
615 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
616 return SILC_CONFIG_EPRINTLINE;
620 return SILC_CONFIG_EINTERNAL;
621 return SILC_CONFIG_OK;
624 /* here we need to check if tmp exists because this function handles
625 * misc data (multiple fields and single-only fields) */
627 silc_free(tmp->server_ip);
634 SILC_CONFIG_CALLBACK(fetch_logging)
636 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
638 if (!strcmp(name, "timestamp")) {
639 config->logging_timestamp = *(bool *)val;
641 else if (!strcmp(name, "quicklogs")) {
642 config->logging_quick = *(bool *)val;
644 else if (!strcmp(name, "flushdelay")) {
645 int flushdelay = *(int *)val;
646 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
647 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
648 "Invalid flushdelay value, use quicklogs if you "
649 "want real-time logging."));
650 return SILC_CONFIG_EPRINTLINE;
652 config->logging_flushdelay = (long) flushdelay;
655 /* The following istances happens only in Logging's sub-blocks, a match
656 for the sub-block name means that you should store the filename/maxsize
657 temporary struct to the proper logging channel.
658 If we get a match for "file" or "maxsize" this means that we are inside
659 a sub-sub-block and it is safe to alloc a new tmp. */
660 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
661 else if (!strcmp(name, __chan__)) { \
662 if (!tmp) return SILC_CONFIG_OK; \
664 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
666 config->__member__ = tmp; \
667 config->tmp = NULL; \
669 FETCH_LOGGING_CHAN("info", logging_info)
670 FETCH_LOGGING_CHAN("warnings", logging_warnings)
671 FETCH_LOGGING_CHAN("errors", logging_errors)
672 FETCH_LOGGING_CHAN("fatals", logging_fatals)
673 #undef FETCH_LOGGING_CHAN
674 else if (!strcmp(name, "file")) {
675 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
676 CONFIG_IS_DOUBLE(tmp->file);
677 tmp->file = strdup((char *) val);
679 else if (!strcmp(name, "size")) {
681 config->tmp = silc_calloc(1, sizeof(*tmp));
682 tmp = (SilcServerConfigLogging *) config->tmp;
684 tmp->maxsize = *(SilcUInt32 *) val;
687 return SILC_CONFIG_EINTERNAL;
688 return SILC_CONFIG_OK;
691 silc_free(tmp->file);
697 SILC_CONFIG_CALLBACK(fetch_connparam)
699 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
701 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
702 type, name, context));
703 if (type == SILC_CONFIG_ARG_BLOCK) {
704 /* check the temporary struct's fields */
705 if (!tmp) /* discard empty sub-blocks */
706 return SILC_CONFIG_OK;
708 got_errno = SILC_CONFIG_EMISSFIELDS;
712 my_set_param_defaults(tmp, &config->param);
714 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
716 return SILC_CONFIG_OK;
718 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
720 if (!strcmp(name, "name")) {
721 CONFIG_IS_DOUBLE(tmp->name);
722 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
724 else if (!strcmp(name, "connections_max")) {
725 tmp->connections_max = *(SilcUInt32 *)val;
727 else if (!strcmp(name, "connections_max_per_host")) {
728 tmp->connections_max_per_host = *(SilcUInt32 *)val;
730 else if (!strcmp(name, "keepalive_secs")) {
731 tmp->keepalive_secs = *(SilcUInt32 *)val;
733 else if (!strcmp(name, "reconnect_count")) {
734 tmp->reconnect_count = *(SilcUInt32 *)val;
736 else if (!strcmp(name, "reconnect_interval")) {
737 tmp->reconnect_interval = *(SilcUInt32 *)val;
739 else if (!strcmp(name, "reconnect_interval_max")) {
740 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
742 else if (!strcmp(name, "reconnect_keep_trying")) {
743 tmp->reconnect_keep_trying = *(bool *)val;
745 else if (!strcmp(name, "key_exchange_rekey")) {
746 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
748 else if (!strcmp(name, "key_exchange_pfs")) {
749 tmp->key_exchange_pfs = *(bool *)val;
751 else if (!strcmp(name, "version_protocol")) {
752 CONFIG_IS_DOUBLE(tmp->version_protocol);
753 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
755 else if (!strcmp(name, "version_software")) {
756 CONFIG_IS_DOUBLE(tmp->version_software);
757 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
759 else if (!strcmp(name, "version_software_vendor")) {
760 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
761 tmp->version_software_vendor =
762 (*(char *)val ? strdup((char *) val) : NULL);
764 else if (!strcmp(name, "anonymous")) {
765 tmp->anonymous = *(bool *)val;
767 else if (!strcmp(name, "qos")) {
768 tmp->qos = *(bool *)val;
770 else if (!strcmp(name, "qos_rate_limit")) {
771 tmp->qos_rate_limit = *(SilcUInt32 *)val;
773 else if (!strcmp(name, "qos_bytes_limit")) {
774 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
776 else if (!strcmp(name, "qos_limit_sec")) {
777 tmp->qos_limit_sec = *(SilcUInt32 *)val;
779 else if (!strcmp(name, "qos_limit_usec")) {
780 tmp->qos_limit_usec = *(SilcUInt32 *)val;
783 return SILC_CONFIG_EINTERNAL;
785 return SILC_CONFIG_OK;
788 silc_free(tmp->name);
794 SILC_CONFIG_CALLBACK(fetch_client)
796 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
798 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
799 type, name, context));
801 /* Alloc before block checking, because empty sub-blocks are welcome here */
802 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
804 if (type == SILC_CONFIG_ARG_BLOCK) {
805 /* empty sub-blocks are welcome */
806 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
808 return SILC_CONFIG_OK;
811 /* Identify and save this value */
812 if (!strcmp(name, "host")) {
813 CONFIG_IS_DOUBLE(tmp->host);
814 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
816 else if (!strcmp(name, "passphrase")) {
817 CONFIG_IS_DOUBLE(tmp->passphrase);
818 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
819 (void **)&tmp->passphrase,
820 &tmp->passphrase_len)) {
821 got_errno = SILC_CONFIG_EPRINTLINE;
825 else if (!strcmp(name, "publickey")) {
826 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
827 (void **)&tmp->publickeys, NULL)) {
828 got_errno = SILC_CONFIG_EPRINTLINE;
832 else if (!strcmp(name, "publickeydir")) {
833 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
834 got_errno = SILC_CONFIG_EPRINTLINE;
838 else if (!strcmp(name, "params")) {
839 CONFIG_IS_DOUBLE(tmp->param);
840 tmp->param = my_find_param(config, (char *) val);
841 if (!tmp->param) { /* error message already output */
842 got_errno = SILC_CONFIG_EPRINTLINE;
847 return SILC_CONFIG_EINTERNAL;
848 return SILC_CONFIG_OK;
851 silc_free(tmp->host);
852 CONFIG_FREE_AUTH(tmp);
858 SILC_CONFIG_CALLBACK(fetch_admin)
860 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
862 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
863 type, name, context));
864 if (type == SILC_CONFIG_ARG_BLOCK) {
865 /* check the temporary struct's fields */
866 if (!tmp) /* discard empty sub-blocks */
867 return SILC_CONFIG_OK;
869 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
871 return SILC_CONFIG_OK;
873 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
875 /* Identify and save this value */
876 if (!strcmp(name, "host")) {
877 CONFIG_IS_DOUBLE(tmp->host);
878 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
880 else if (!strcmp(name, "user")) {
881 CONFIG_IS_DOUBLE(tmp->user);
882 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
884 else if (!strcmp(name, "nick")) {
885 CONFIG_IS_DOUBLE(tmp->nick);
886 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
888 else if (!strcmp(name, "passphrase")) {
889 CONFIG_IS_DOUBLE(tmp->passphrase);
890 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
891 (void **)&tmp->passphrase,
892 &tmp->passphrase_len)) {
893 got_errno = SILC_CONFIG_EPRINTLINE;
897 else if (!strcmp(name, "publickey")) {
898 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
899 (void **)&tmp->publickeys, NULL)) {
900 got_errno = SILC_CONFIG_EPRINTLINE;
904 else if (!strcmp(name, "publickeydir")) {
905 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
906 got_errno = SILC_CONFIG_EPRINTLINE;
911 return SILC_CONFIG_EINTERNAL;
912 return SILC_CONFIG_OK;
915 silc_free(tmp->host);
916 silc_free(tmp->user);
917 silc_free(tmp->nick);
918 CONFIG_FREE_AUTH(tmp);
924 SILC_CONFIG_CALLBACK(fetch_deny)
926 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
928 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
929 type, name, context));
930 if (type == SILC_CONFIG_ARG_BLOCK) {
931 /* check the temporary struct's fields */
932 if (!tmp) /* discard empty sub-blocks */
933 return SILC_CONFIG_OK;
935 got_errno = SILC_CONFIG_EMISSFIELDS;
939 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
941 return SILC_CONFIG_OK;
943 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
945 /* Identify and save this value */
946 if (!strcmp(name, "host")) {
947 CONFIG_IS_DOUBLE(tmp->host);
948 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
950 else if (!strcmp(name, "reason")) {
951 CONFIG_IS_DOUBLE(tmp->reason);
952 tmp->reason = strdup((char *) val);
955 return SILC_CONFIG_EINTERNAL;
956 return SILC_CONFIG_OK;
959 silc_free(tmp->host);
960 silc_free(tmp->reason);
966 SILC_CONFIG_CALLBACK(fetch_server)
968 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
970 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
971 type, name, context));
972 if (type == SILC_CONFIG_ARG_BLOCK) {
973 /* check the temporary struct's fields */
974 if (!tmp) /* discard empty sub-blocks */
975 return SILC_CONFIG_OK;
977 /* the temporary struct is ok, append it to the list */
978 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
980 return SILC_CONFIG_OK;
982 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
984 /* Identify and save this value */
985 if (!strcmp(name, "host")) {
986 CONFIG_IS_DOUBLE(tmp->host);
987 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
989 else if (!strcmp(name, "passphrase")) {
990 CONFIG_IS_DOUBLE(tmp->passphrase);
991 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
992 (void **)&tmp->passphrase,
993 &tmp->passphrase_len)) {
994 got_errno = SILC_CONFIG_EPRINTLINE;
998 else if (!strcmp(name, "publickey")) {
999 CONFIG_IS_DOUBLE(tmp->publickeys);
1000 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1001 (void **)&tmp->publickeys, NULL)) {
1002 got_errno = SILC_CONFIG_EPRINTLINE;
1006 else if (!strcmp(name, "params")) {
1007 CONFIG_IS_DOUBLE(tmp->param);
1008 tmp->param = my_find_param(config, (char *) val);
1009 if (!tmp->param) { /* error message already output */
1010 got_errno = SILC_CONFIG_EPRINTLINE;
1014 else if (!strcmp(name, "backup")) {
1015 tmp->backup_router = *(bool *)val;
1018 return SILC_CONFIG_EINTERNAL;
1020 return SILC_CONFIG_OK;
1023 silc_free(tmp->host);
1024 CONFIG_FREE_AUTH(tmp);
1030 SILC_CONFIG_CALLBACK(fetch_router)
1032 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1034 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1035 type, name, context));
1036 if (type == SILC_CONFIG_ARG_BLOCK) {
1037 if (!tmp) /* discard empty sub-blocks */
1038 return SILC_CONFIG_OK;
1040 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1042 return SILC_CONFIG_OK;
1044 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1046 /* Identify and save this value */
1047 if (!strcmp(name, "host")) {
1048 CONFIG_IS_DOUBLE(tmp->host);
1049 tmp->host = strdup((char *) val);
1051 else if (!strcmp(name, "port")) {
1052 int port = *(int *)val;
1053 if ((port <= 0) || (port > 65535)) {
1054 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1055 "Invalid port number!"));
1056 got_errno = SILC_CONFIG_EPRINTLINE;
1059 tmp->port = (SilcUInt16) port;
1061 else if (!strcmp(name, "passphrase")) {
1062 CONFIG_IS_DOUBLE(tmp->passphrase);
1063 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1064 (void **)&tmp->passphrase,
1065 &tmp->passphrase_len)) {
1066 got_errno = SILC_CONFIG_EPRINTLINE;
1070 else if (!strcmp(name, "publickey")) {
1071 CONFIG_IS_DOUBLE(tmp->publickeys);
1072 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1073 (void **)&tmp->publickeys, NULL)) {
1074 got_errno = SILC_CONFIG_EPRINTLINE;
1078 else if (!strcmp(name, "params")) {
1079 CONFIG_IS_DOUBLE(tmp->param);
1080 tmp->param = my_find_param(config, (char *) val);
1081 if (!tmp->param) { /* error message already output */
1082 got_errno = SILC_CONFIG_EPRINTLINE;
1086 else if (!strcmp(name, "initiator")) {
1087 tmp->initiator = *(bool *)val;
1089 else if (!strcmp(name, "backuphost")) {
1090 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1091 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1093 tmp->backup_router = TRUE;
1095 else if (!strcmp(name, "backupport")) {
1096 int port = *(int *)val;
1097 if ((port <= 0) || (port > 65535)) {
1098 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1099 "Invalid port number!"));
1100 got_errno = SILC_CONFIG_EPRINTLINE;
1103 tmp->backup_replace_port = (SilcUInt16) port;
1105 else if (!strcmp(name, "backuplocal")) {
1106 tmp->backup_local = *(bool *)val;
1109 return SILC_CONFIG_EINTERNAL;
1111 return SILC_CONFIG_OK;
1114 silc_free(tmp->host);
1115 silc_free(tmp->backup_replace_ip);
1116 CONFIG_FREE_AUTH(tmp);
1122 /* known config options tables */
1123 static const SilcConfigTable table_general[] = {
1124 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1125 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1126 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1127 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1128 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1129 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1130 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1131 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1132 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1133 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1134 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1135 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1136 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1137 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1138 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1139 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1140 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1141 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1142 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1143 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1144 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1145 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1146 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1147 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1148 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1152 static const SilcConfigTable table_cipher[] = {
1153 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1154 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1155 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1156 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1160 static const SilcConfigTable table_hash[] = {
1161 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1162 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1163 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1164 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1168 static const SilcConfigTable table_hmac[] = {
1169 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1170 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1171 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1175 static const SilcConfigTable table_pkcs[] = {
1176 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1180 static const SilcConfigTable table_serverinfo_c[] = {
1181 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1182 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1186 static const SilcConfigTable table_serverinfo[] = {
1187 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1188 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1189 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1190 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1191 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1192 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1193 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1194 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1195 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1196 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1197 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1198 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1199 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1203 static const SilcConfigTable table_logging_c[] = {
1204 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1205 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1206 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1210 static const SilcConfigTable table_logging[] = {
1211 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1212 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1213 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1214 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1215 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1216 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1217 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1221 static const SilcConfigTable table_connparam[] = {
1222 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1223 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1224 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1225 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1226 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1227 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1228 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1229 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1230 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1231 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1232 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1233 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1234 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1235 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1236 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1237 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1238 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1239 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1240 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1241 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1245 static const SilcConfigTable table_client[] = {
1246 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1247 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1248 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1249 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1250 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1254 static const SilcConfigTable table_admin[] = {
1255 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1256 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1257 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1258 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1259 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1260 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1261 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1262 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1266 static const SilcConfigTable table_deny[] = {
1267 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1268 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1272 static const SilcConfigTable table_serverconn[] = {
1273 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1274 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1275 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1276 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1277 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1281 static const SilcConfigTable table_routerconn[] = {
1282 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1283 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1284 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1285 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1286 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1287 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1288 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1289 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1290 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1294 static const SilcConfigTable table_main[] = {
1295 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1296 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1297 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1298 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1299 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1300 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1301 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1302 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1303 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1304 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1305 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1306 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1307 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1311 /* Set default values to stuff that was not configured. */
1313 static void silc_server_config_set_defaults(SilcServerConfig config)
1315 my_set_param_defaults(&config->param, NULL);
1317 config->channel_rekey_secs = (config->channel_rekey_secs ?
1318 config->channel_rekey_secs :
1319 SILC_SERVER_CHANNEL_REKEY);
1320 config->key_exchange_timeout = (config->key_exchange_timeout ?
1321 config->key_exchange_timeout :
1322 SILC_SERVER_SKE_TIMEOUT);
1323 config->conn_auth_timeout = (config->conn_auth_timeout ?
1324 config->conn_auth_timeout :
1325 SILC_SERVER_CONNAUTH_TIMEOUT);
1328 /* Check for correctness of the configuration */
1330 static bool silc_server_config_check(SilcServerConfig config)
1333 SilcServerConfigServer *s;
1334 SilcServerConfigRouter *r;
1337 /* ServerConfig is mandatory */
1338 if (!config->server_info) {
1339 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1343 /* RouterConnection sanity checks */
1345 if (config->routers && config->routers->backup_router == TRUE &&
1347 SILC_SERVER_LOG_ERROR((
1348 "\nError: First RouterConnection block must be primary router "
1349 "connection. You have marked it incorrectly as backup router."));
1352 if (config->routers && config->routers->initiator == FALSE &&
1353 config->routers->backup_router == FALSE) {
1354 SILC_SERVER_LOG_ERROR((
1355 "\nError: First RouterConnection block must be primary router "
1356 "connection and it must be marked as Initiator."));
1359 if (config->routers && config->routers->backup_router == TRUE &&
1360 !config->servers && !config->routers->next) {
1361 SILC_SERVER_LOG_ERROR((
1362 "\nError: You have configured backup router but not primary router. "
1363 "If backup router is configured also primary router must be "
1368 /* Backup router sanity checks */
1370 for (r = config->routers; r; r = r->next) {
1371 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1372 SILC_SERVER_LOG_ERROR((
1373 "\nError: Backup router connection incorrectly configured to use "
1374 "primary and backup router as same host `%s'. They must not be "
1375 "same host.", r->host));
1380 /* ServerConnection sanity checks */
1382 for (s = config->servers; s; s = s->next) {
1383 if (s->backup_router) {
1389 for (s = config->servers; s; s = s->next) {
1390 if (!s->backup_router) {
1391 SILC_SERVER_LOG_ERROR((
1392 "\nError: Your server is backup router but not all ServerConnection "
1393 "blocks were marked as backup connections. They all must be "
1394 "marked as backup connections."));
1404 /* Allocates a new configuration object, opens configuration file and
1405 parses it. The parsed data is returned to the newly allocated
1406 configuration object. The SilcServerConfig must be freed by calling
1407 the silc_server_config_destroy function. */
1409 SilcServerConfig silc_server_config_alloc(const char *filename)
1411 SilcServerConfig config_new;
1412 SilcConfigEntity ent;
1413 SilcConfigFile *file;
1415 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1417 /* alloc a config object */
1418 config_new = silc_calloc(1, sizeof(*config_new));
1422 /* general config defaults */
1423 config_new->refcount = 1;
1424 config_new->logging_timestamp = TRUE;
1426 /* obtain a config file object */
1427 file = silc_config_open(filename);
1429 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1434 /* obtain a SilcConfig entity, we can use it to start the parsing */
1435 ent = silc_config_init(file);
1437 /* load the known configuration options, give our empty object as context */
1438 silc_config_register_table(ent, table_main, (void *) config_new);
1440 /* enter the main parsing loop. When this returns, we have the parsing
1441 * result and the object filled (or partially, in case of errors). */
1442 ret = silc_config_main(ent);
1443 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1444 silc_config_strerror(ret)));
1446 /* Check if the parser returned errors */
1448 /* handle this special error return which asks to quietly return */
1449 if (ret != SILC_CONFIG_ESILENT) {
1450 char *linebuf, *filename = silc_config_get_filename(file);
1451 SilcUInt32 line = silc_config_get_line(file);
1452 if (ret != SILC_CONFIG_EPRINTLINE)
1453 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1454 silc_config_strerror(ret)));
1455 linebuf = silc_config_read_line(file, line);
1457 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1462 silc_server_config_destroy(config_new);
1463 silc_config_close(file);
1467 /* close (destroy) the file object */
1468 silc_config_close(file);
1470 /* Check the configuration */
1471 if (!silc_server_config_check(config_new)) {
1472 silc_server_config_destroy(config_new);
1476 /* Set default to configuration parameters */
1477 silc_server_config_set_defaults(config_new);
1482 /* Increments the reference counter of a config object */
1484 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1489 ref->config = config;
1490 ref->ref_ptr = ref_ptr;
1491 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1492 config->refcount - 1, config->refcount));
1496 /* Decrements the reference counter of a config object. If the counter
1497 reaches 0, the config object is destroyed. */
1499 void silc_server_config_unref(SilcServerConfigRef *ref)
1502 silc_server_config_destroy(ref->config);
1505 /* Destroy a config object with all his children lists */
1507 void silc_server_config_destroy(SilcServerConfig config)
1512 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1513 config->refcount + 1, config->refcount));
1514 if (config->refcount > 0)
1517 SILC_LOG_DEBUG(("Freeing config context"));
1519 /* Destroy general config stuff */
1520 silc_free(config->module_path);
1521 silc_free(config->param.version_protocol);
1522 silc_free(config->param.version_software);
1523 silc_free(config->param.version_software_vendor);
1525 /* Destroy Logging channels */
1526 if (config->logging_info)
1527 silc_free(config->logging_info->file);
1528 if (config->logging_warnings)
1529 silc_free(config->logging_warnings->file);
1530 if (config->logging_errors)
1531 silc_free(config->logging_errors->file);
1532 if (config->logging_fatals)
1533 silc_free(config->logging_fatals->file);
1534 silc_free(config->logging_info);
1535 silc_free(config->logging_warnings);
1536 silc_free(config->logging_errors);
1537 silc_free(config->logging_fatals);
1539 /* Destroy the ServerInfo struct */
1540 if (config->server_info) {
1541 register SilcServerConfigServerInfo *si = config->server_info;
1542 silc_free(si->server_name);
1544 silc_free(si->primary->server_ip);
1545 silc_free(si->primary);
1547 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1549 silc_free(di->server_ip);
1552 silc_free(si->server_type);
1553 silc_free(si->location);
1554 silc_free(si->admin);
1555 silc_free(si->email);
1556 silc_free(si->user);
1557 silc_free(si->group);
1558 silc_free(si->motd_file);
1559 silc_free(si->pid_file);
1560 silc_pkcs_public_key_free(si->public_key);
1561 silc_pkcs_private_key_free(si->private_key);
1565 /* Now let's destroy the lists */
1567 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1569 silc_free(di->name);
1570 silc_free(di->module);
1573 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1574 silc_free(di->name);
1575 silc_free(di->module);
1578 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1579 silc_free(di->name);
1580 silc_free(di->hash);
1583 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1584 silc_free(di->name);
1587 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1588 config->conn_params)
1589 silc_free(di->name);
1590 silc_free(di->version_protocol);
1591 silc_free(di->version_software);
1592 silc_free(di->version_software_vendor);
1595 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1596 silc_free(di->host);
1597 CONFIG_FREE_AUTH(di);
1600 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1601 silc_free(di->host);
1602 silc_free(di->user);
1603 silc_free(di->nick);
1604 CONFIG_FREE_AUTH(di);
1607 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1608 silc_free(di->host);
1609 silc_free(di->reason);
1612 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1614 silc_free(di->host);
1615 CONFIG_FREE_AUTH(di);
1618 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1620 silc_free(di->host);
1621 silc_free(di->backup_replace_ip);
1622 CONFIG_FREE_AUTH(di);
1626 memset(config, 'F', sizeof(*config));
1630 /* Registers configured ciphers. These can then be allocated by the
1631 server when needed. */
1633 bool silc_server_config_register_ciphers(SilcServer server)
1635 SilcServerConfig config = server->config;
1636 SilcServerConfigCipher *cipher = config->cipher;
1637 char *module_path = config->module_path;
1639 SILC_LOG_DEBUG(("Registering configured ciphers"));
1641 if (!cipher) /* any cipher in the config file? */
1645 /* if there isn't a module_path OR there isn't a module sim name try to
1646 * use buil-in functions */
1647 if (!module_path || !cipher->module) {
1649 for (i = 0; silc_default_ciphers[i].name; i++)
1650 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1651 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1654 if (!silc_cipher_is_supported(cipher->name)) {
1655 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1656 silc_server_stop(server);
1661 /* Load (try at least) the crypto SIM module */
1662 char buf[1023], *alg_name;
1663 SilcCipherObject cipher_obj;
1666 memset(&cipher_obj, 0, sizeof(cipher_obj));
1667 cipher_obj.name = cipher->name;
1668 cipher_obj.block_len = cipher->block_length;
1669 cipher_obj.key_len = cipher->key_length * 8;
1671 /* build the libname */
1672 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1674 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1676 alg_name = strdup(cipher->name);
1677 if (strchr(alg_name, '-'))
1678 *strchr(alg_name, '-') = '\0';
1680 if (silc_sim_load(sim)) {
1681 cipher_obj.set_key =
1682 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1683 SILC_CIPHER_SIM_SET_KEY));
1684 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1685 cipher_obj.set_key_with_string =
1686 silc_sim_getsym(sim,
1687 silc_sim_symname(alg_name,
1688 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1689 SILC_LOG_DEBUG(("set_key_with_string=%p",
1690 cipher_obj.set_key_with_string));
1691 cipher_obj.encrypt =
1692 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1693 SILC_CIPHER_SIM_ENCRYPT_CBC));
1694 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1695 cipher_obj.decrypt =
1696 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1697 SILC_CIPHER_SIM_DECRYPT_CBC));
1698 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1699 cipher_obj.context_len =
1700 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1701 SILC_CIPHER_SIM_CONTEXT_LEN));
1702 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1704 /* Put the SIM to the list of all SIM's in server */
1705 silc_dlist_add(server->sim, sim);
1707 silc_free(alg_name);
1709 SILC_LOG_ERROR(("Error configuring ciphers"));
1711 silc_server_stop(server);
1715 /* Register the cipher */
1716 silc_cipher_register(&cipher_obj);
1718 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1719 "can't load modules!"));
1720 silc_server_stop(server);
1724 cipher = cipher->next;
1730 /* Registers configured hash functions. These can then be allocated by the
1731 server when needed. */
1733 bool silc_server_config_register_hashfuncs(SilcServer server)
1735 SilcServerConfig config = server->config;
1736 SilcServerConfigHash *hash = config->hash;
1737 char *module_path = config->module_path;
1739 SILC_LOG_DEBUG(("Registering configured hash functions"));
1741 if (!hash) /* any hash func in the config file? */
1745 /* if there isn't a module_path OR there isn't a module sim name try to
1746 * use buil-in functions */
1747 if (!module_path || !hash->module) {
1749 for (i = 0; silc_default_hash[i].name; i++)
1750 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1751 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1754 if (!silc_hash_is_supported(hash->name)) {
1755 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1756 silc_server_stop(server);
1761 /* Load (try at least) the hash SIM module */
1762 SilcHashObject hash_obj;
1765 memset(&hash_obj, 0, sizeof(hash_obj));
1766 hash_obj.name = hash->name;
1767 hash_obj.block_len = hash->block_length;
1768 hash_obj.hash_len = hash->digest_length;
1770 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1772 if ((silc_sim_load(sim))) {
1774 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1775 SILC_HASH_SIM_INIT));
1776 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1778 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1779 SILC_HASH_SIM_UPDATE));
1780 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1782 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1783 SILC_HASH_SIM_FINAL));
1784 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1785 hash_obj.context_len =
1786 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1787 SILC_HASH_SIM_CONTEXT_LEN));
1788 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1790 /* Put the SIM to the table of all SIM's in server */
1791 silc_dlist_add(server->sim, sim);
1793 SILC_LOG_ERROR(("Error configuring hash functions"));
1795 silc_server_stop(server);
1799 /* Register the hash function */
1800 silc_hash_register(&hash_obj);
1802 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1803 "can't load modules!"));
1804 silc_server_stop(server);
1814 /* Registers configure HMACs. These can then be allocated by the server
1817 bool silc_server_config_register_hmacs(SilcServer server)
1819 SilcServerConfig config = server->config;
1820 SilcServerConfigHmac *hmac = config->hmac;
1822 SILC_LOG_DEBUG(("Registering configured HMACs"));
1828 SilcHmacObject hmac_obj;
1829 if (!silc_hash_is_supported(hmac->hash)) {
1830 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1831 silc_server_stop(server);
1835 /* Register the HMAC */
1836 memset(&hmac_obj, 0, sizeof(hmac_obj));
1837 hmac_obj.name = hmac->name;
1838 hmac_obj.len = hmac->mac_length;
1839 silc_hmac_register(&hmac_obj);
1847 /* Registers configured PKCS's. */
1849 bool silc_server_config_register_pkcs(SilcServer server)
1851 SilcServerConfig config = server->config;
1852 SilcServerConfigPkcs *pkcs = config->pkcs;
1854 SILC_LOG_DEBUG(("Registering configured PKCS"));
1861 for (i = 0; silc_default_pkcs[i].name; i++)
1862 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1863 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1866 if (!silc_pkcs_is_supported(pkcs->name)) {
1867 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1868 silc_server_stop(server);
1877 /* Sets log files where log messages are saved by the server logger. */
1879 void silc_server_config_setlogfiles(SilcServer server)
1881 SilcServerConfig config = server->config;
1882 SilcServerConfigLogging *this;
1884 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1886 silc_log_timestamp = config->logging_timestamp;
1887 silc_log_quick = config->logging_quick;
1888 silc_log_flushdelay = (config->logging_flushdelay ?
1889 config->logging_flushdelay :
1890 SILC_SERVER_LOG_FLUSH_DELAY);
1892 if ((this = config->logging_fatals))
1893 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1895 if ((this = config->logging_errors))
1896 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1898 if ((this = config->logging_warnings))
1899 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1901 if ((this = config->logging_info))
1902 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1906 /* Returns client authentication information from configuration file by host
1909 SilcServerConfigClient *
1910 silc_server_config_find_client(SilcServer server, char *host)
1912 SilcServerConfig config = server->config;
1913 SilcServerConfigClient *client;
1915 if (!config || !host)
1918 for (client = config->clients; client; client = client->next) {
1919 if (client->host && !silc_string_compare(client->host, host))
1924 /* if none matched, then client is already NULL */
1928 /* Returns admin connection configuration by host, username and/or
1931 SilcServerConfigAdmin *
1932 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1935 SilcServerConfig config = server->config;
1936 SilcServerConfigAdmin *admin;
1938 /* make sure we have a value for the matching parameters */
1946 for (admin = config->admins; admin; admin = admin->next) {
1947 if (admin->host && !silc_string_compare(admin->host, host))
1949 if (admin->user && !silc_string_compare(admin->user, user))
1951 if (admin->nick && !silc_string_compare(admin->nick, nick))
1953 /* no checks failed -> this entry matches */
1957 /* if none matched, then admin is already NULL */
1961 /* Returns the denied connection configuration entry by host. */
1963 SilcServerConfigDeny *
1964 silc_server_config_find_denied(SilcServer server, char *host)
1966 SilcServerConfig config = server->config;
1967 SilcServerConfigDeny *deny;
1969 /* make sure we have a value for the matching parameters */
1970 if (!config || !host)
1973 for (deny = config->denied; deny; deny = deny->next) {
1974 if (deny->host && !silc_string_compare(deny->host, host))
1979 /* if none matched, then deny is already NULL */
1983 /* Returns server connection info from server configuartion by host
1986 SilcServerConfigServer *
1987 silc_server_config_find_server_conn(SilcServer server, char *host)
1989 SilcServerConfig config = server->config;
1990 SilcServerConfigServer *serv = NULL;
1995 if (!config->servers)
1998 for (serv = config->servers; serv; serv = serv->next) {
1999 if (!silc_string_compare(serv->host, host))
2007 /* Returns router connection info from server configuration by
2008 host (name or ip). */
2010 SilcServerConfigRouter *
2011 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
2013 SilcServerConfig config = server->config;
2014 SilcServerConfigRouter *serv = NULL;
2019 if (!config->routers)
2022 for (serv = config->routers; serv; serv = serv->next) {
2023 if (!silc_string_compare(serv->host, host))
2025 if (port && serv->port && serv->port != port)
2033 /* Find backup router connection by host (name or ip) */
2035 SilcServerConfigRouter *
2036 silc_server_config_find_backup_conn(SilcServer server, char *host)
2038 SilcServerConfig config = server->config;
2039 SilcServerConfigRouter *serv = NULL;
2044 if (!config->routers)
2047 for (serv = config->routers; serv; serv = serv->next) {
2048 if (!serv->backup_router)
2050 if (!silc_string_compare(serv->host, host))
2058 /* Returns TRUE if configuration for a router connection that we are
2059 initiating exists. */
2061 bool silc_server_config_is_primary_route(SilcServer server)
2063 SilcServerConfig config = server->config;
2064 SilcServerConfigRouter *serv = NULL;
2068 serv = config->routers;
2069 for (i = 0; serv; i++) {
2070 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2081 /* Returns our primary connection configuration or NULL if we do not
2082 have primary router configured. */
2084 SilcServerConfigRouter *
2085 silc_server_config_get_primary_router(SilcServer server)
2087 SilcServerConfig config = server->config;
2088 SilcServerConfigRouter *serv = NULL;
2091 serv = config->routers;
2092 for (i = 0; serv; i++) {
2093 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2101 /* If we have backup router configured that is going to replace us this
2102 function returns it. */
2104 SilcServerConfigRouter *
2105 silc_server_config_get_backup_router(SilcServer server)
2107 SilcServerConfig config = server->config;
2108 SilcServerConfigRouter *serv = NULL;
2111 if (server->server_type != SILC_ROUTER)
2114 serv = config->routers;
2115 for (i = 0; serv; i++) {
2116 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2117 serv->backup_local == TRUE &&
2118 !strcmp(server->config->server_info->primary->server_ip,
2119 serv->backup_replace_ip) &&
2120 server->config->server_info->primary->port ==
2121 serv->backup_replace_port)