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")) {
608 char *file_tmp = (char *) val;
609 CONFIG_IS_DOUBLE(server_info->private_key);
611 /* Check the private key file permissions. */
612 if ((stat(file_tmp, &st)) != -1) {
613 if ((st.st_mode & 0777) != 0600) {
614 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
615 "file \"%s\". The permissions must be "
617 return SILC_CONFIG_ESILENT;
621 /* Try to load specified file, if fail stop config parsing */
622 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
623 "", 0, SILC_PKCS_FILE_BIN))
624 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
625 "", 0, SILC_PKCS_FILE_PEM)) {
626 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
627 return SILC_CONFIG_EPRINTLINE;
631 return SILC_CONFIG_EINTERNAL;
632 return SILC_CONFIG_OK;
635 /* Here we need to check if tmp exists because this function handles
636 * misc data (multiple fields and single-only fields) */
638 silc_free(tmp->server_ip);
645 SILC_CONFIG_CALLBACK(fetch_logging)
647 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
649 if (!strcmp(name, "timestamp")) {
650 config->logging_timestamp = *(bool *)val;
652 else if (!strcmp(name, "quicklogs")) {
653 config->logging_quick = *(bool *)val;
655 else if (!strcmp(name, "flushdelay")) {
656 int flushdelay = *(int *)val;
657 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
658 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
659 "Invalid flushdelay value, use quicklogs if you "
660 "want real-time logging."));
661 return SILC_CONFIG_EPRINTLINE;
663 config->logging_flushdelay = (long) flushdelay;
666 /* The following istances happens only in Logging's sub-blocks, a match
667 for the sub-block name means that you should store the filename/maxsize
668 temporary struct to the proper logging channel.
669 If we get a match for "file" or "maxsize" this means that we are inside
670 a sub-sub-block and it is safe to alloc a new tmp. */
671 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
672 else if (!strcmp(name, __chan__)) { \
673 if (!tmp) return SILC_CONFIG_OK; \
675 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
677 config->__member__ = tmp; \
678 config->tmp = NULL; \
680 FETCH_LOGGING_CHAN("info", logging_info)
681 FETCH_LOGGING_CHAN("warnings", logging_warnings)
682 FETCH_LOGGING_CHAN("errors", logging_errors)
683 FETCH_LOGGING_CHAN("fatals", logging_fatals)
684 #undef FETCH_LOGGING_CHAN
685 else if (!strcmp(name, "file")) {
686 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
687 CONFIG_IS_DOUBLE(tmp->file);
688 tmp->file = strdup((char *) val);
690 else if (!strcmp(name, "size")) {
692 config->tmp = silc_calloc(1, sizeof(*tmp));
693 tmp = (SilcServerConfigLogging *) config->tmp;
695 tmp->maxsize = *(SilcUInt32 *) val;
698 return SILC_CONFIG_EINTERNAL;
699 return SILC_CONFIG_OK;
702 silc_free(tmp->file);
708 SILC_CONFIG_CALLBACK(fetch_connparam)
710 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
712 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
713 type, name, context));
714 if (type == SILC_CONFIG_ARG_BLOCK) {
715 /* check the temporary struct's fields */
716 if (!tmp) /* discard empty sub-blocks */
717 return SILC_CONFIG_OK;
719 got_errno = SILC_CONFIG_EMISSFIELDS;
723 my_set_param_defaults(tmp, &config->param);
725 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
727 return SILC_CONFIG_OK;
729 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
731 if (!strcmp(name, "name")) {
732 CONFIG_IS_DOUBLE(tmp->name);
733 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
735 else if (!strcmp(name, "connections_max")) {
736 tmp->connections_max = *(SilcUInt32 *)val;
738 else if (!strcmp(name, "connections_max_per_host")) {
739 tmp->connections_max_per_host = *(SilcUInt32 *)val;
741 else if (!strcmp(name, "keepalive_secs")) {
742 tmp->keepalive_secs = *(SilcUInt32 *)val;
744 else if (!strcmp(name, "reconnect_count")) {
745 tmp->reconnect_count = *(SilcUInt32 *)val;
747 else if (!strcmp(name, "reconnect_interval")) {
748 tmp->reconnect_interval = *(SilcUInt32 *)val;
750 else if (!strcmp(name, "reconnect_interval_max")) {
751 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
753 else if (!strcmp(name, "reconnect_keep_trying")) {
754 tmp->reconnect_keep_trying = *(bool *)val;
756 else if (!strcmp(name, "key_exchange_rekey")) {
757 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
759 else if (!strcmp(name, "key_exchange_pfs")) {
760 tmp->key_exchange_pfs = *(bool *)val;
762 else if (!strcmp(name, "version_protocol")) {
763 CONFIG_IS_DOUBLE(tmp->version_protocol);
764 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
766 else if (!strcmp(name, "version_software")) {
767 CONFIG_IS_DOUBLE(tmp->version_software);
768 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
770 else if (!strcmp(name, "version_software_vendor")) {
771 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
772 tmp->version_software_vendor =
773 (*(char *)val ? strdup((char *) val) : NULL);
775 else if (!strcmp(name, "anonymous")) {
776 tmp->anonymous = *(bool *)val;
778 else if (!strcmp(name, "qos")) {
779 tmp->qos = *(bool *)val;
781 else if (!strcmp(name, "qos_rate_limit")) {
782 tmp->qos_rate_limit = *(SilcUInt32 *)val;
784 else if (!strcmp(name, "qos_bytes_limit")) {
785 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
787 else if (!strcmp(name, "qos_limit_sec")) {
788 tmp->qos_limit_sec = *(SilcUInt32 *)val;
790 else if (!strcmp(name, "qos_limit_usec")) {
791 tmp->qos_limit_usec = *(SilcUInt32 *)val;
794 return SILC_CONFIG_EINTERNAL;
796 return SILC_CONFIG_OK;
799 silc_free(tmp->name);
805 SILC_CONFIG_CALLBACK(fetch_client)
807 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
809 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
810 type, name, context));
812 /* Alloc before block checking, because empty sub-blocks are welcome here */
813 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
815 if (type == SILC_CONFIG_ARG_BLOCK) {
816 /* empty sub-blocks are welcome */
817 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
819 return SILC_CONFIG_OK;
822 /* Identify and save this value */
823 if (!strcmp(name, "host")) {
824 CONFIG_IS_DOUBLE(tmp->host);
825 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
827 else if (!strcmp(name, "passphrase")) {
828 CONFIG_IS_DOUBLE(tmp->passphrase);
829 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
830 (void **)&tmp->passphrase,
831 &tmp->passphrase_len)) {
832 got_errno = SILC_CONFIG_EPRINTLINE;
836 else if (!strcmp(name, "publickey")) {
837 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
838 (void **)&tmp->publickeys, NULL)) {
839 got_errno = SILC_CONFIG_EPRINTLINE;
843 else if (!strcmp(name, "publickeydir")) {
844 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
845 got_errno = SILC_CONFIG_EPRINTLINE;
849 else if (!strcmp(name, "params")) {
850 CONFIG_IS_DOUBLE(tmp->param);
851 tmp->param = my_find_param(config, (char *) val);
852 if (!tmp->param) { /* error message already output */
853 got_errno = SILC_CONFIG_EPRINTLINE;
858 return SILC_CONFIG_EINTERNAL;
859 return SILC_CONFIG_OK;
862 silc_free(tmp->host);
863 CONFIG_FREE_AUTH(tmp);
869 SILC_CONFIG_CALLBACK(fetch_admin)
871 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
873 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
874 type, name, context));
875 if (type == SILC_CONFIG_ARG_BLOCK) {
876 /* check the temporary struct's fields */
877 if (!tmp) /* discard empty sub-blocks */
878 return SILC_CONFIG_OK;
880 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
882 return SILC_CONFIG_OK;
884 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
886 /* Identify and save this value */
887 if (!strcmp(name, "host")) {
888 CONFIG_IS_DOUBLE(tmp->host);
889 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
891 else if (!strcmp(name, "user")) {
892 CONFIG_IS_DOUBLE(tmp->user);
893 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
895 else if (!strcmp(name, "nick")) {
896 CONFIG_IS_DOUBLE(tmp->nick);
897 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
899 else if (!strcmp(name, "passphrase")) {
900 CONFIG_IS_DOUBLE(tmp->passphrase);
901 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
902 (void **)&tmp->passphrase,
903 &tmp->passphrase_len)) {
904 got_errno = SILC_CONFIG_EPRINTLINE;
908 else if (!strcmp(name, "publickey")) {
909 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
910 (void **)&tmp->publickeys, NULL)) {
911 got_errno = SILC_CONFIG_EPRINTLINE;
915 else if (!strcmp(name, "publickeydir")) {
916 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
917 got_errno = SILC_CONFIG_EPRINTLINE;
922 return SILC_CONFIG_EINTERNAL;
923 return SILC_CONFIG_OK;
926 silc_free(tmp->host);
927 silc_free(tmp->user);
928 silc_free(tmp->nick);
929 CONFIG_FREE_AUTH(tmp);
935 SILC_CONFIG_CALLBACK(fetch_deny)
937 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
939 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
940 type, name, context));
941 if (type == SILC_CONFIG_ARG_BLOCK) {
942 /* check the temporary struct's fields */
943 if (!tmp) /* discard empty sub-blocks */
944 return SILC_CONFIG_OK;
946 got_errno = SILC_CONFIG_EMISSFIELDS;
950 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
952 return SILC_CONFIG_OK;
954 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
956 /* Identify and save this value */
957 if (!strcmp(name, "host")) {
958 CONFIG_IS_DOUBLE(tmp->host);
959 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
961 else if (!strcmp(name, "reason")) {
962 CONFIG_IS_DOUBLE(tmp->reason);
963 tmp->reason = strdup((char *) val);
966 return SILC_CONFIG_EINTERNAL;
967 return SILC_CONFIG_OK;
970 silc_free(tmp->host);
971 silc_free(tmp->reason);
977 SILC_CONFIG_CALLBACK(fetch_server)
979 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
981 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
982 type, name, context));
983 if (type == SILC_CONFIG_ARG_BLOCK) {
984 /* check the temporary struct's fields */
985 if (!tmp) /* discard empty sub-blocks */
986 return SILC_CONFIG_OK;
988 /* the temporary struct is ok, append it to the list */
989 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
991 return SILC_CONFIG_OK;
993 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
995 /* Identify and save this value */
996 if (!strcmp(name, "host")) {
997 CONFIG_IS_DOUBLE(tmp->host);
998 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1000 else if (!strcmp(name, "passphrase")) {
1001 CONFIG_IS_DOUBLE(tmp->passphrase);
1002 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1003 (void **)&tmp->passphrase,
1004 &tmp->passphrase_len)) {
1005 got_errno = SILC_CONFIG_EPRINTLINE;
1009 else if (!strcmp(name, "publickey")) {
1010 CONFIG_IS_DOUBLE(tmp->publickeys);
1011 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1012 (void **)&tmp->publickeys, NULL)) {
1013 got_errno = SILC_CONFIG_EPRINTLINE;
1017 else if (!strcmp(name, "params")) {
1018 CONFIG_IS_DOUBLE(tmp->param);
1019 tmp->param = my_find_param(config, (char *) val);
1020 if (!tmp->param) { /* error message already output */
1021 got_errno = SILC_CONFIG_EPRINTLINE;
1025 else if (!strcmp(name, "backup")) {
1026 tmp->backup_router = *(bool *)val;
1029 return SILC_CONFIG_EINTERNAL;
1031 return SILC_CONFIG_OK;
1034 silc_free(tmp->host);
1035 CONFIG_FREE_AUTH(tmp);
1041 SILC_CONFIG_CALLBACK(fetch_router)
1043 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1045 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1046 type, name, context));
1047 if (type == SILC_CONFIG_ARG_BLOCK) {
1048 if (!tmp) /* discard empty sub-blocks */
1049 return SILC_CONFIG_OK;
1051 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1053 return SILC_CONFIG_OK;
1055 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1057 /* Identify and save this value */
1058 if (!strcmp(name, "host")) {
1059 CONFIG_IS_DOUBLE(tmp->host);
1060 tmp->host = strdup((char *) val);
1062 else if (!strcmp(name, "port")) {
1063 int port = *(int *)val;
1064 if ((port <= 0) || (port > 65535)) {
1065 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1066 "Invalid port number!"));
1067 got_errno = SILC_CONFIG_EPRINTLINE;
1070 tmp->port = (SilcUInt16) port;
1072 else if (!strcmp(name, "passphrase")) {
1073 CONFIG_IS_DOUBLE(tmp->passphrase);
1074 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1075 (void **)&tmp->passphrase,
1076 &tmp->passphrase_len)) {
1077 got_errno = SILC_CONFIG_EPRINTLINE;
1081 else if (!strcmp(name, "publickey")) {
1082 CONFIG_IS_DOUBLE(tmp->publickeys);
1083 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1084 (void **)&tmp->publickeys, NULL)) {
1085 got_errno = SILC_CONFIG_EPRINTLINE;
1089 else if (!strcmp(name, "params")) {
1090 CONFIG_IS_DOUBLE(tmp->param);
1091 tmp->param = my_find_param(config, (char *) val);
1092 if (!tmp->param) { /* error message already output */
1093 got_errno = SILC_CONFIG_EPRINTLINE;
1097 else if (!strcmp(name, "initiator")) {
1098 tmp->initiator = *(bool *)val;
1100 else if (!strcmp(name, "backuphost")) {
1101 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1102 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1104 tmp->backup_router = TRUE;
1106 else if (!strcmp(name, "backupport")) {
1107 int port = *(int *)val;
1108 if ((port <= 0) || (port > 65535)) {
1109 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1110 "Invalid port number!"));
1111 got_errno = SILC_CONFIG_EPRINTLINE;
1114 tmp->backup_replace_port = (SilcUInt16) port;
1116 else if (!strcmp(name, "backuplocal")) {
1117 tmp->backup_local = *(bool *)val;
1120 return SILC_CONFIG_EINTERNAL;
1122 return SILC_CONFIG_OK;
1125 silc_free(tmp->host);
1126 silc_free(tmp->backup_replace_ip);
1127 CONFIG_FREE_AUTH(tmp);
1133 /* known config options tables */
1134 static const SilcConfigTable table_general[] = {
1135 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1136 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1137 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1138 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1139 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1140 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1141 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1142 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1143 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1144 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1145 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1146 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1147 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1148 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1149 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1150 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1151 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1152 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1153 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1154 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1155 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1156 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1157 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1158 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1159 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1163 static const SilcConfigTable table_cipher[] = {
1164 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1165 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1166 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1167 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1171 static const SilcConfigTable table_hash[] = {
1172 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1173 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1174 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1175 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1179 static const SilcConfigTable table_hmac[] = {
1180 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1181 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1182 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1186 static const SilcConfigTable table_pkcs[] = {
1187 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1191 static const SilcConfigTable table_serverinfo_c[] = {
1192 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1193 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1197 static const SilcConfigTable table_serverinfo[] = {
1198 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1199 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1200 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1201 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1202 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1203 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1204 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1205 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1206 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1207 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1208 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1209 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1210 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1214 static const SilcConfigTable table_logging_c[] = {
1215 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1216 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1217 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1221 static const SilcConfigTable table_logging[] = {
1222 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1223 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1224 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1225 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1226 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1227 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1228 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1232 static const SilcConfigTable table_connparam[] = {
1233 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1234 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1235 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1236 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1237 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1238 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1239 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1240 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1241 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1242 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1243 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1244 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1245 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1246 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1247 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1248 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1249 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1250 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1251 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1252 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1256 static const SilcConfigTable table_client[] = {
1257 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1258 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1259 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1260 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1261 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1265 static const SilcConfigTable table_admin[] = {
1266 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1267 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1268 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1269 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1270 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1271 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1272 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1273 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1277 static const SilcConfigTable table_deny[] = {
1278 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1279 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1283 static const SilcConfigTable table_serverconn[] = {
1284 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1285 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1286 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1287 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1288 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1292 static const SilcConfigTable table_routerconn[] = {
1293 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1294 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1295 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1296 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1297 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1298 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1299 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1300 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1301 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1305 static const SilcConfigTable table_main[] = {
1306 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1307 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1308 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1309 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1310 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1311 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1312 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1313 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1314 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1315 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1316 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1317 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1318 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1322 /* Set default values to stuff that was not configured. */
1324 static void silc_server_config_set_defaults(SilcServerConfig config)
1326 my_set_param_defaults(&config->param, NULL);
1328 config->channel_rekey_secs = (config->channel_rekey_secs ?
1329 config->channel_rekey_secs :
1330 SILC_SERVER_CHANNEL_REKEY);
1331 config->key_exchange_timeout = (config->key_exchange_timeout ?
1332 config->key_exchange_timeout :
1333 SILC_SERVER_SKE_TIMEOUT);
1334 config->conn_auth_timeout = (config->conn_auth_timeout ?
1335 config->conn_auth_timeout :
1336 SILC_SERVER_CONNAUTH_TIMEOUT);
1339 /* Check for correctness of the configuration */
1341 static bool silc_server_config_check(SilcServerConfig config)
1344 SilcServerConfigServer *s;
1345 SilcServerConfigRouter *r;
1348 /* ServerConfig is mandatory */
1349 if (!config->server_info) {
1350 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1354 /* RouterConnection sanity checks */
1356 if (config->routers && config->routers->backup_router == TRUE &&
1358 SILC_SERVER_LOG_ERROR((
1359 "\nError: First RouterConnection block must be primary router "
1360 "connection. You have marked it incorrectly as backup router."));
1363 if (config->routers && config->routers->initiator == FALSE &&
1364 config->routers->backup_router == FALSE) {
1365 SILC_SERVER_LOG_ERROR((
1366 "\nError: First RouterConnection block must be primary router "
1367 "connection and it must be marked as Initiator."));
1370 if (config->routers && config->routers->backup_router == TRUE &&
1371 !config->servers && !config->routers->next) {
1372 SILC_SERVER_LOG_ERROR((
1373 "\nError: You have configured backup router but not primary router. "
1374 "If backup router is configured also primary router must be "
1379 /* Backup router sanity checks */
1381 for (r = config->routers; r; r = r->next) {
1382 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1383 SILC_SERVER_LOG_ERROR((
1384 "\nError: Backup router connection incorrectly configured to use "
1385 "primary and backup router as same host `%s'. They must not be "
1386 "same host.", r->host));
1391 /* ServerConnection sanity checks */
1393 for (s = config->servers; s; s = s->next) {
1394 if (s->backup_router) {
1400 for (s = config->servers; s; s = s->next) {
1401 if (!s->backup_router) {
1402 SILC_SERVER_LOG_ERROR((
1403 "\nError: Your server is backup router but not all ServerConnection "
1404 "blocks were marked as backup connections. They all must be "
1405 "marked as backup connections."));
1415 /* Allocates a new configuration object, opens configuration file and
1416 parses it. The parsed data is returned to the newly allocated
1417 configuration object. The SilcServerConfig must be freed by calling
1418 the silc_server_config_destroy function. */
1420 SilcServerConfig silc_server_config_alloc(const char *filename)
1422 SilcServerConfig config_new;
1423 SilcConfigEntity ent;
1424 SilcConfigFile *file;
1426 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1428 /* alloc a config object */
1429 config_new = silc_calloc(1, sizeof(*config_new));
1433 /* general config defaults */
1434 config_new->refcount = 1;
1435 config_new->logging_timestamp = TRUE;
1437 /* obtain a config file object */
1438 file = silc_config_open(filename);
1440 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1445 /* obtain a SilcConfig entity, we can use it to start the parsing */
1446 ent = silc_config_init(file);
1448 /* load the known configuration options, give our empty object as context */
1449 silc_config_register_table(ent, table_main, (void *) config_new);
1451 /* enter the main parsing loop. When this returns, we have the parsing
1452 * result and the object filled (or partially, in case of errors). */
1453 ret = silc_config_main(ent);
1454 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1455 silc_config_strerror(ret)));
1457 /* Check if the parser returned errors */
1459 /* handle this special error return which asks to quietly return */
1460 if (ret != SILC_CONFIG_ESILENT) {
1461 char *linebuf, *filename = silc_config_get_filename(file);
1462 SilcUInt32 line = silc_config_get_line(file);
1463 if (ret != SILC_CONFIG_EPRINTLINE)
1464 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1465 silc_config_strerror(ret)));
1466 linebuf = silc_config_read_line(file, line);
1468 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1473 silc_server_config_destroy(config_new);
1474 silc_config_close(file);
1478 /* close (destroy) the file object */
1479 silc_config_close(file);
1481 /* Check the configuration */
1482 if (!silc_server_config_check(config_new)) {
1483 silc_server_config_destroy(config_new);
1487 /* Set default to configuration parameters */
1488 silc_server_config_set_defaults(config_new);
1493 /* Increments the reference counter of a config object */
1495 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1500 ref->config = config;
1501 ref->ref_ptr = ref_ptr;
1502 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1503 config->refcount - 1, config->refcount));
1507 /* Decrements the reference counter of a config object. If the counter
1508 reaches 0, the config object is destroyed. */
1510 void silc_server_config_unref(SilcServerConfigRef *ref)
1513 silc_server_config_destroy(ref->config);
1516 /* Destroy a config object with all his children lists */
1518 void silc_server_config_destroy(SilcServerConfig config)
1523 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1524 config->refcount + 1, config->refcount));
1525 if (config->refcount > 0)
1528 SILC_LOG_DEBUG(("Freeing config context"));
1530 /* Destroy general config stuff */
1531 silc_free(config->module_path);
1532 silc_free(config->param.version_protocol);
1533 silc_free(config->param.version_software);
1534 silc_free(config->param.version_software_vendor);
1536 /* Destroy Logging channels */
1537 if (config->logging_info)
1538 silc_free(config->logging_info->file);
1539 if (config->logging_warnings)
1540 silc_free(config->logging_warnings->file);
1541 if (config->logging_errors)
1542 silc_free(config->logging_errors->file);
1543 if (config->logging_fatals)
1544 silc_free(config->logging_fatals->file);
1545 silc_free(config->logging_info);
1546 silc_free(config->logging_warnings);
1547 silc_free(config->logging_errors);
1548 silc_free(config->logging_fatals);
1550 /* Destroy the ServerInfo struct */
1551 if (config->server_info) {
1552 register SilcServerConfigServerInfo *si = config->server_info;
1553 silc_free(si->server_name);
1555 silc_free(si->primary->server_ip);
1556 silc_free(si->primary);
1558 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1560 silc_free(di->server_ip);
1563 silc_free(si->server_type);
1564 silc_free(si->location);
1565 silc_free(si->admin);
1566 silc_free(si->email);
1567 silc_free(si->user);
1568 silc_free(si->group);
1569 silc_free(si->motd_file);
1570 silc_free(si->pid_file);
1571 silc_pkcs_public_key_free(si->public_key);
1572 silc_pkcs_private_key_free(si->private_key);
1576 /* Now let's destroy the lists */
1578 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1580 silc_free(di->name);
1581 silc_free(di->module);
1584 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1585 silc_free(di->name);
1586 silc_free(di->module);
1589 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1590 silc_free(di->name);
1591 silc_free(di->hash);
1594 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1595 silc_free(di->name);
1598 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1599 config->conn_params)
1600 silc_free(di->name);
1601 silc_free(di->version_protocol);
1602 silc_free(di->version_software);
1603 silc_free(di->version_software_vendor);
1606 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1607 silc_free(di->host);
1608 CONFIG_FREE_AUTH(di);
1611 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1612 silc_free(di->host);
1613 silc_free(di->user);
1614 silc_free(di->nick);
1615 CONFIG_FREE_AUTH(di);
1618 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1619 silc_free(di->host);
1620 silc_free(di->reason);
1623 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1625 silc_free(di->host);
1626 CONFIG_FREE_AUTH(di);
1629 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1631 silc_free(di->host);
1632 silc_free(di->backup_replace_ip);
1633 CONFIG_FREE_AUTH(di);
1637 memset(config, 'F', sizeof(*config));
1641 /* Registers configured ciphers. These can then be allocated by the
1642 server when needed. */
1644 bool silc_server_config_register_ciphers(SilcServer server)
1646 SilcServerConfig config = server->config;
1647 SilcServerConfigCipher *cipher = config->cipher;
1648 char *module_path = config->module_path;
1650 SILC_LOG_DEBUG(("Registering configured ciphers"));
1652 if (!cipher) /* any cipher in the config file? */
1656 /* if there isn't a module_path OR there isn't a module sim name try to
1657 * use buil-in functions */
1658 if (!module_path || !cipher->module) {
1660 for (i = 0; silc_default_ciphers[i].name; i++)
1661 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1662 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1665 if (!silc_cipher_is_supported(cipher->name)) {
1666 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1667 silc_server_stop(server);
1672 /* Load (try at least) the crypto SIM module */
1673 char buf[1023], *alg_name;
1674 SilcCipherObject cipher_obj;
1677 memset(&cipher_obj, 0, sizeof(cipher_obj));
1678 cipher_obj.name = cipher->name;
1679 cipher_obj.block_len = cipher->block_length;
1680 cipher_obj.key_len = cipher->key_length * 8;
1682 /* build the libname */
1683 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1685 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1687 alg_name = strdup(cipher->name);
1688 if (strchr(alg_name, '-'))
1689 *strchr(alg_name, '-') = '\0';
1691 if (silc_sim_load(sim)) {
1692 cipher_obj.set_key =
1693 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1694 SILC_CIPHER_SIM_SET_KEY));
1695 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1696 cipher_obj.set_key_with_string =
1697 silc_sim_getsym(sim,
1698 silc_sim_symname(alg_name,
1699 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1700 SILC_LOG_DEBUG(("set_key_with_string=%p",
1701 cipher_obj.set_key_with_string));
1702 cipher_obj.encrypt =
1703 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1704 SILC_CIPHER_SIM_ENCRYPT_CBC));
1705 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1706 cipher_obj.decrypt =
1707 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1708 SILC_CIPHER_SIM_DECRYPT_CBC));
1709 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1710 cipher_obj.context_len =
1711 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1712 SILC_CIPHER_SIM_CONTEXT_LEN));
1713 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1715 /* Put the SIM to the list of all SIM's in server */
1716 silc_dlist_add(server->sim, sim);
1718 silc_free(alg_name);
1720 SILC_LOG_ERROR(("Error configuring ciphers"));
1722 silc_server_stop(server);
1726 /* Register the cipher */
1727 silc_cipher_register(&cipher_obj);
1729 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1730 "can't load modules!"));
1731 silc_server_stop(server);
1735 cipher = cipher->next;
1741 /* Registers configured hash functions. These can then be allocated by the
1742 server when needed. */
1744 bool silc_server_config_register_hashfuncs(SilcServer server)
1746 SilcServerConfig config = server->config;
1747 SilcServerConfigHash *hash = config->hash;
1748 char *module_path = config->module_path;
1750 SILC_LOG_DEBUG(("Registering configured hash functions"));
1752 if (!hash) /* any hash func in the config file? */
1756 /* if there isn't a module_path OR there isn't a module sim name try to
1757 * use buil-in functions */
1758 if (!module_path || !hash->module) {
1760 for (i = 0; silc_default_hash[i].name; i++)
1761 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1762 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1765 if (!silc_hash_is_supported(hash->name)) {
1766 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1767 silc_server_stop(server);
1772 /* Load (try at least) the hash SIM module */
1773 SilcHashObject hash_obj;
1776 memset(&hash_obj, 0, sizeof(hash_obj));
1777 hash_obj.name = hash->name;
1778 hash_obj.block_len = hash->block_length;
1779 hash_obj.hash_len = hash->digest_length;
1781 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1783 if ((silc_sim_load(sim))) {
1785 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1786 SILC_HASH_SIM_INIT));
1787 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1789 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1790 SILC_HASH_SIM_UPDATE));
1791 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1793 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1794 SILC_HASH_SIM_FINAL));
1795 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1796 hash_obj.context_len =
1797 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1798 SILC_HASH_SIM_CONTEXT_LEN));
1799 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1801 /* Put the SIM to the table of all SIM's in server */
1802 silc_dlist_add(server->sim, sim);
1804 SILC_LOG_ERROR(("Error configuring hash functions"));
1806 silc_server_stop(server);
1810 /* Register the hash function */
1811 silc_hash_register(&hash_obj);
1813 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1814 "can't load modules!"));
1815 silc_server_stop(server);
1825 /* Registers configure HMACs. These can then be allocated by the server
1828 bool silc_server_config_register_hmacs(SilcServer server)
1830 SilcServerConfig config = server->config;
1831 SilcServerConfigHmac *hmac = config->hmac;
1833 SILC_LOG_DEBUG(("Registering configured HMACs"));
1839 SilcHmacObject hmac_obj;
1840 if (!silc_hash_is_supported(hmac->hash)) {
1841 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1842 silc_server_stop(server);
1846 /* Register the HMAC */
1847 memset(&hmac_obj, 0, sizeof(hmac_obj));
1848 hmac_obj.name = hmac->name;
1849 hmac_obj.len = hmac->mac_length;
1850 silc_hmac_register(&hmac_obj);
1858 /* Registers configured PKCS's. */
1860 bool silc_server_config_register_pkcs(SilcServer server)
1862 SilcServerConfig config = server->config;
1863 SilcServerConfigPkcs *pkcs = config->pkcs;
1865 SILC_LOG_DEBUG(("Registering configured PKCS"));
1872 for (i = 0; silc_default_pkcs[i].name; i++)
1873 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1874 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1877 if (!silc_pkcs_is_supported(pkcs->name)) {
1878 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1879 silc_server_stop(server);
1888 /* Sets log files where log messages are saved by the server logger. */
1890 void silc_server_config_setlogfiles(SilcServer server)
1892 SilcServerConfig config = server->config;
1893 SilcServerConfigLogging *this;
1895 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1897 silc_log_timestamp = config->logging_timestamp;
1898 silc_log_quick = config->logging_quick;
1899 silc_log_flushdelay = (config->logging_flushdelay ?
1900 config->logging_flushdelay :
1901 SILC_SERVER_LOG_FLUSH_DELAY);
1903 if ((this = config->logging_fatals))
1904 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1906 if ((this = config->logging_errors))
1907 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1909 if ((this = config->logging_warnings))
1910 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1912 if ((this = config->logging_info))
1913 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1917 /* Returns client authentication information from configuration file by host
1920 SilcServerConfigClient *
1921 silc_server_config_find_client(SilcServer server, char *host)
1923 SilcServerConfig config = server->config;
1924 SilcServerConfigClient *client;
1926 if (!config || !host)
1929 for (client = config->clients; client; client = client->next) {
1930 if (client->host && !silc_string_compare(client->host, host))
1935 /* if none matched, then client is already NULL */
1939 /* Returns admin connection configuration by host, username and/or
1942 SilcServerConfigAdmin *
1943 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1946 SilcServerConfig config = server->config;
1947 SilcServerConfigAdmin *admin;
1949 /* make sure we have a value for the matching parameters */
1957 for (admin = config->admins; admin; admin = admin->next) {
1958 if (admin->host && !silc_string_compare(admin->host, host))
1960 if (admin->user && !silc_string_compare(admin->user, user))
1962 if (admin->nick && !silc_string_compare(admin->nick, nick))
1964 /* no checks failed -> this entry matches */
1968 /* if none matched, then admin is already NULL */
1972 /* Returns the denied connection configuration entry by host. */
1974 SilcServerConfigDeny *
1975 silc_server_config_find_denied(SilcServer server, char *host)
1977 SilcServerConfig config = server->config;
1978 SilcServerConfigDeny *deny;
1980 /* make sure we have a value for the matching parameters */
1981 if (!config || !host)
1984 for (deny = config->denied; deny; deny = deny->next) {
1985 if (deny->host && !silc_string_compare(deny->host, host))
1990 /* if none matched, then deny is already NULL */
1994 /* Returns server connection info from server configuartion by host
1997 SilcServerConfigServer *
1998 silc_server_config_find_server_conn(SilcServer server, char *host)
2000 SilcServerConfig config = server->config;
2001 SilcServerConfigServer *serv = NULL;
2006 if (!config->servers)
2009 for (serv = config->servers; serv; serv = serv->next) {
2010 if (!silc_string_compare(serv->host, host))
2018 /* Returns router connection info from server configuration by
2019 host (name or ip). */
2021 SilcServerConfigRouter *
2022 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
2024 SilcServerConfig config = server->config;
2025 SilcServerConfigRouter *serv = NULL;
2030 if (!config->routers)
2033 for (serv = config->routers; serv; serv = serv->next) {
2034 if (!silc_string_compare(serv->host, host))
2036 if (port && serv->port && serv->port != port)
2044 /* Find backup router connection by host (name or ip) */
2046 SilcServerConfigRouter *
2047 silc_server_config_find_backup_conn(SilcServer server, char *host)
2049 SilcServerConfig config = server->config;
2050 SilcServerConfigRouter *serv = NULL;
2055 if (!config->routers)
2058 for (serv = config->routers; serv; serv = serv->next) {
2059 if (!serv->backup_router)
2061 if (!silc_string_compare(serv->host, host))
2069 /* Returns TRUE if configuration for a router connection that we are
2070 initiating exists. */
2072 bool silc_server_config_is_primary_route(SilcServer server)
2074 SilcServerConfig config = server->config;
2075 SilcServerConfigRouter *serv = NULL;
2079 serv = config->routers;
2080 for (i = 0; serv; i++) {
2081 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2092 /* Returns our primary connection configuration or NULL if we do not
2093 have primary router configured. */
2095 SilcServerConfigRouter *
2096 silc_server_config_get_primary_router(SilcServer server)
2098 SilcServerConfig config = server->config;
2099 SilcServerConfigRouter *serv = NULL;
2102 serv = config->routers;
2103 for (i = 0; serv; i++) {
2104 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2112 /* If we have backup router configured that is going to replace us this
2113 function returns it. */
2115 SilcServerConfigRouter *
2116 silc_server_config_get_backup_router(SilcServer server)
2118 SilcServerConfig config = server->config;
2119 SilcServerConfigRouter *serv = NULL;
2122 if (server->server_type != SILC_ROUTER)
2125 serv = config->routers;
2126 for (i = 0; serv; i++) {
2127 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2128 serv->backup_local == TRUE &&
2129 !strcmp(server->config->server_info->primary->server_ip,
2130 serv->backup_replace_ip) &&
2131 server->config->server_info->primary->port ==
2132 serv->backup_replace_port)