5 Author: Johnny Mnemonic <johnny@themnemonic.org>
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 /* if there isn't the struct alloc it */
500 config->server_info = server_info = (SilcServerConfigServerInfo *)
501 silc_calloc(1, sizeof(*server_info));
503 if (type == SILC_CONFIG_ARG_BLOCK) {
504 if (!strcmp(name, "primary")) {
505 CONFIG_IS_DOUBLE(server_info->primary);
507 return SILC_CONFIG_OK;
508 server_info->primary = tmp;
510 return SILC_CONFIG_OK;
511 } else if (!strcmp(name, "secondary")) {
513 return SILC_CONFIG_OK;
514 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
516 return SILC_CONFIG_OK;
517 } else if (!server_info->public_key || !server_info->private_key) {
518 got_errno = SILC_CONFIG_EMISSFIELDS;
521 return SILC_CONFIG_OK;
523 if (!strcmp(name, "hostname")) {
524 CONFIG_IS_DOUBLE(server_info->server_name);
525 server_info->server_name = strdup((char *) val);
527 else if (!strcmp(name, "ip")) {
528 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
529 CONFIG_IS_DOUBLE(tmp->server_ip);
530 tmp->server_ip = strdup((char *) val);
532 else if (!strcmp(name, "port")) {
533 int port = *(int *)val;
534 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
535 if ((port <= 0) || (port > 65535)) {
536 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
537 "Invalid port number!"));
538 got_errno = SILC_CONFIG_EPRINTLINE;
541 tmp->port = (SilcUInt16) port;
543 else if (!strcmp(name, "servertype")) {
544 CONFIG_IS_DOUBLE(server_info->server_type);
545 server_info->server_type = strdup((char *) val);
547 else if (!strcmp(name, "admin")) {
548 CONFIG_IS_DOUBLE(server_info->admin);
549 server_info->admin = strdup((char *) val);
551 else if (!strcmp(name, "adminemail")) {
552 CONFIG_IS_DOUBLE(server_info->email);
553 server_info->email = strdup((char *) val);
555 else if (!strcmp(name, "location")) {
556 CONFIG_IS_DOUBLE(server_info->location);
557 server_info->location = strdup((char *) val);
559 else if (!strcmp(name, "user")) {
560 CONFIG_IS_DOUBLE(server_info->user);
561 server_info->user = strdup((char *) val);
563 else if (!strcmp(name, "group")) {
564 CONFIG_IS_DOUBLE(server_info->group);
565 server_info->group = strdup((char *) val);
567 else if (!strcmp(name, "motdfile")) {
568 CONFIG_IS_DOUBLE(server_info->motd_file);
569 server_info->motd_file = strdup((char *) val);
571 else if (!strcmp(name, "pidfile")) {
572 CONFIG_IS_DOUBLE(server_info->pid_file);
573 server_info->pid_file = strdup((char *) val);
575 else if (!strcmp(name, "publickey")) {
576 char *file_tmp = (char *) val;
577 CONFIG_IS_DOUBLE(server_info->public_key);
579 /* try to load specified file, if fail stop config parsing */
580 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
582 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
583 SILC_PKCS_FILE_BIN)) {
584 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
585 return SILC_CONFIG_EPRINTLINE;
588 else if (!strcmp(name, "privatekey")) {
589 char *file_tmp = (char *) val;
590 CONFIG_IS_DOUBLE(server_info->private_key);
592 /* try to load specified file, if fail stop config parsing */
593 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
594 "", 0, SILC_PKCS_FILE_BIN))
595 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
596 "", 0, SILC_PKCS_FILE_PEM)) {
597 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
598 return SILC_CONFIG_EPRINTLINE;
602 return SILC_CONFIG_EINTERNAL;
603 return SILC_CONFIG_OK;
607 silc_free(config->tmp);
612 SILC_CONFIG_CALLBACK(fetch_logging)
614 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
616 if (!strcmp(name, "timestamp")) {
617 config->logging_timestamp = *(bool *)val;
619 else if (!strcmp(name, "quicklogs")) {
620 config->logging_quick = *(bool *)val;
622 else if (!strcmp(name, "flushdelay")) {
623 int flushdelay = *(int *)val;
624 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
625 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
626 "Invalid flushdelay value, use quicklogs if you "
627 "want real-time logging."));
628 return SILC_CONFIG_EPRINTLINE;
630 config->logging_flushdelay = (long) flushdelay;
633 /* The following istances happens only in Logging's sub-blocks, a match
634 for the sub-block name means that you should store the filename/maxsize
635 temporary struct to the proper logging channel.
636 If we get a match for "file" or "maxsize" this means that we are inside
637 a sub-sub-block and it is safe to alloc a new tmp. */
638 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
639 else if (!strcmp(name, __chan__)) { \
640 if (!tmp) return SILC_CONFIG_OK; \
642 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
644 config->__member__ = tmp; \
645 config->tmp = NULL; \
647 FETCH_LOGGING_CHAN("info", logging_info)
648 FETCH_LOGGING_CHAN("warnings", logging_warnings)
649 FETCH_LOGGING_CHAN("errors", logging_errors)
650 FETCH_LOGGING_CHAN("fatals", logging_fatals)
651 #undef FETCH_LOGGING_CHAN
652 else if (!strcmp(name, "file")) {
653 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
654 CONFIG_IS_DOUBLE(tmp->file);
655 tmp->file = strdup((char *) val);
657 else if (!strcmp(name, "size")) {
659 config->tmp = silc_calloc(1, sizeof(*tmp));
660 tmp = (SilcServerConfigLogging *) config->tmp;
662 tmp->maxsize = *(SilcUInt32 *) val;
665 return SILC_CONFIG_EINTERNAL;
666 return SILC_CONFIG_OK;
669 silc_free(tmp->file);
675 SILC_CONFIG_CALLBACK(fetch_connparam)
677 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
679 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
680 type, name, context));
681 if (type == SILC_CONFIG_ARG_BLOCK) {
682 /* check the temporary struct's fields */
683 if (!tmp) /* discard empty sub-blocks */
684 return SILC_CONFIG_OK;
686 got_errno = SILC_CONFIG_EMISSFIELDS;
690 my_set_param_defaults(tmp, &config->param);
692 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
694 return SILC_CONFIG_OK;
696 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
698 if (!strcmp(name, "name")) {
699 CONFIG_IS_DOUBLE(tmp->name);
700 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
702 else if (!strcmp(name, "connections_max")) {
703 tmp->connections_max = *(SilcUInt32 *)val;
705 else if (!strcmp(name, "connections_max_per_host")) {
706 tmp->connections_max_per_host = *(SilcUInt32 *)val;
708 else if (!strcmp(name, "keepalive_secs")) {
709 tmp->keepalive_secs = *(SilcUInt32 *)val;
711 else if (!strcmp(name, "reconnect_count")) {
712 tmp->reconnect_count = *(SilcUInt32 *)val;
714 else if (!strcmp(name, "reconnect_interval")) {
715 tmp->reconnect_interval = *(SilcUInt32 *)val;
717 else if (!strcmp(name, "reconnect_interval_max")) {
718 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
720 else if (!strcmp(name, "reconnect_keep_trying")) {
721 tmp->reconnect_keep_trying = *(bool *)val;
723 else if (!strcmp(name, "key_exchange_rekey")) {
724 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
726 else if (!strcmp(name, "key_exchange_pfs")) {
727 tmp->key_exchange_pfs = *(bool *)val;
729 else if (!strcmp(name, "version_protocol")) {
730 CONFIG_IS_DOUBLE(tmp->version_protocol);
731 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
733 else if (!strcmp(name, "version_software")) {
734 CONFIG_IS_DOUBLE(tmp->version_software);
735 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
737 else if (!strcmp(name, "version_software_vendor")) {
738 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
739 tmp->version_software_vendor =
740 (*(char *)val ? strdup((char *) val) : NULL);
742 else if (!strcmp(name, "anonymous")) {
743 tmp->anonymous = *(bool *)val;
745 else if (!strcmp(name, "qos")) {
746 tmp->qos = *(bool *)val;
748 else if (!strcmp(name, "qos_rate_limit")) {
749 tmp->qos_rate_limit = *(SilcUInt32 *)val;
751 else if (!strcmp(name, "qos_bytes_limit")) {
752 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
754 else if (!strcmp(name, "qos_limit_sec")) {
755 tmp->qos_limit_sec = *(SilcUInt32 *)val;
757 else if (!strcmp(name, "qos_limit_usec")) {
758 tmp->qos_limit_usec = *(SilcUInt32 *)val;
761 return SILC_CONFIG_EINTERNAL;
763 return SILC_CONFIG_OK;
766 silc_free(tmp->name);
772 SILC_CONFIG_CALLBACK(fetch_client)
774 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
776 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
777 type, name, context));
779 /* Alloc before block checking, because empty sub-blocks are welcome here */
780 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
782 if (type == SILC_CONFIG_ARG_BLOCK) {
783 /* empty sub-blocks are welcome */
784 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
786 return SILC_CONFIG_OK;
789 /* Identify and save this value */
790 if (!strcmp(name, "host")) {
791 CONFIG_IS_DOUBLE(tmp->host);
792 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
794 else if (!strcmp(name, "passphrase")) {
795 CONFIG_IS_DOUBLE(tmp->passphrase);
796 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
797 (void **)&tmp->passphrase,
798 &tmp->passphrase_len)) {
799 got_errno = SILC_CONFIG_EPRINTLINE;
803 else if (!strcmp(name, "publickey")) {
804 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
805 (void **)&tmp->publickeys, NULL)) {
806 got_errno = SILC_CONFIG_EPRINTLINE;
810 else if (!strcmp(name, "publickeydir")) {
811 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
812 got_errno = SILC_CONFIG_EPRINTLINE;
816 else if (!strcmp(name, "params")) {
817 CONFIG_IS_DOUBLE(tmp->param);
818 tmp->param = my_find_param(config, (char *) val);
819 if (!tmp->param) { /* error message already output */
820 got_errno = SILC_CONFIG_EPRINTLINE;
825 return SILC_CONFIG_EINTERNAL;
826 return SILC_CONFIG_OK;
829 silc_free(tmp->host);
830 CONFIG_FREE_AUTH(tmp);
836 SILC_CONFIG_CALLBACK(fetch_admin)
838 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
840 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
841 type, name, context));
842 if (type == SILC_CONFIG_ARG_BLOCK) {
843 /* check the temporary struct's fields */
844 if (!tmp) /* discard empty sub-blocks */
845 return SILC_CONFIG_OK;
847 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
849 return SILC_CONFIG_OK;
851 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
853 /* Identify and save this value */
854 if (!strcmp(name, "host")) {
855 CONFIG_IS_DOUBLE(tmp->host);
856 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
858 else if (!strcmp(name, "user")) {
859 CONFIG_IS_DOUBLE(tmp->user);
860 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
862 else if (!strcmp(name, "nick")) {
863 CONFIG_IS_DOUBLE(tmp->nick);
864 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
866 else if (!strcmp(name, "passphrase")) {
867 CONFIG_IS_DOUBLE(tmp->passphrase);
868 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
869 (void **)&tmp->passphrase,
870 &tmp->passphrase_len)) {
871 got_errno = SILC_CONFIG_EPRINTLINE;
875 else if (!strcmp(name, "publickey")) {
876 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
877 (void **)&tmp->publickeys, NULL)) {
878 got_errno = SILC_CONFIG_EPRINTLINE;
882 else if (!strcmp(name, "publickeydir")) {
883 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
884 got_errno = SILC_CONFIG_EPRINTLINE;
889 return SILC_CONFIG_EINTERNAL;
890 return SILC_CONFIG_OK;
893 silc_free(tmp->host);
894 silc_free(tmp->user);
895 silc_free(tmp->nick);
896 CONFIG_FREE_AUTH(tmp);
902 SILC_CONFIG_CALLBACK(fetch_deny)
904 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
906 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
907 type, name, context));
908 if (type == SILC_CONFIG_ARG_BLOCK) {
909 /* check the temporary struct's fields */
910 if (!tmp) /* discard empty sub-blocks */
911 return SILC_CONFIG_OK;
913 got_errno = SILC_CONFIG_EMISSFIELDS;
917 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
919 return SILC_CONFIG_OK;
921 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
923 /* Identify and save this value */
924 if (!strcmp(name, "host")) {
925 CONFIG_IS_DOUBLE(tmp->host);
926 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
928 else if (!strcmp(name, "reason")) {
929 CONFIG_IS_DOUBLE(tmp->reason);
930 tmp->reason = strdup((char *) val);
933 return SILC_CONFIG_EINTERNAL;
934 return SILC_CONFIG_OK;
937 silc_free(tmp->host);
938 silc_free(tmp->reason);
944 SILC_CONFIG_CALLBACK(fetch_server)
946 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
948 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
949 type, name, context));
950 if (type == SILC_CONFIG_ARG_BLOCK) {
951 /* check the temporary struct's fields */
952 if (!tmp) /* discard empty sub-blocks */
953 return SILC_CONFIG_OK;
955 /* the temporary struct is ok, append it to the list */
956 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
958 return SILC_CONFIG_OK;
960 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
962 /* Identify and save this value */
963 if (!strcmp(name, "host")) {
964 CONFIG_IS_DOUBLE(tmp->host);
965 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
967 else if (!strcmp(name, "passphrase")) {
968 CONFIG_IS_DOUBLE(tmp->passphrase);
969 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
970 (void **)&tmp->passphrase,
971 &tmp->passphrase_len)) {
972 got_errno = SILC_CONFIG_EPRINTLINE;
976 else if (!strcmp(name, "publickey")) {
977 CONFIG_IS_DOUBLE(tmp->publickeys);
978 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
979 (void **)&tmp->publickeys, NULL)) {
980 got_errno = SILC_CONFIG_EPRINTLINE;
984 else if (!strcmp(name, "params")) {
985 CONFIG_IS_DOUBLE(tmp->param);
986 tmp->param = my_find_param(config, (char *) val);
987 if (!tmp->param) { /* error message already output */
988 got_errno = SILC_CONFIG_EPRINTLINE;
992 else if (!strcmp(name, "backup")) {
993 tmp->backup_router = *(bool *)val;
996 return SILC_CONFIG_EINTERNAL;
998 return SILC_CONFIG_OK;
1001 silc_free(tmp->host);
1002 CONFIG_FREE_AUTH(tmp);
1008 SILC_CONFIG_CALLBACK(fetch_router)
1010 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1012 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1013 type, name, context));
1014 if (type == SILC_CONFIG_ARG_BLOCK) {
1015 if (!tmp) /* discard empty sub-blocks */
1016 return SILC_CONFIG_OK;
1018 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1020 return SILC_CONFIG_OK;
1022 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1024 /* Identify and save this value */
1025 if (!strcmp(name, "host")) {
1026 CONFIG_IS_DOUBLE(tmp->host);
1027 tmp->host = strdup((char *) val);
1029 else if (!strcmp(name, "port")) {
1030 int port = *(int *)val;
1031 if ((port <= 0) || (port > 65535)) {
1032 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1033 "Invalid port number!"));
1034 got_errno = SILC_CONFIG_EPRINTLINE;
1037 tmp->port = (SilcUInt16) port;
1039 else if (!strcmp(name, "passphrase")) {
1040 CONFIG_IS_DOUBLE(tmp->passphrase);
1041 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1042 (void **)&tmp->passphrase,
1043 &tmp->passphrase_len)) {
1044 got_errno = SILC_CONFIG_EPRINTLINE;
1048 else if (!strcmp(name, "publickey")) {
1049 CONFIG_IS_DOUBLE(tmp->publickeys);
1050 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1051 (void **)&tmp->publickeys, NULL)) {
1052 got_errno = SILC_CONFIG_EPRINTLINE;
1056 else if (!strcmp(name, "params")) {
1057 CONFIG_IS_DOUBLE(tmp->param);
1058 tmp->param = my_find_param(config, (char *) val);
1059 if (!tmp->param) { /* error message already output */
1060 got_errno = SILC_CONFIG_EPRINTLINE;
1064 else if (!strcmp(name, "initiator")) {
1065 tmp->initiator = *(bool *)val;
1067 else if (!strcmp(name, "backuphost")) {
1068 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1069 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1071 tmp->backup_router = TRUE;
1073 else if (!strcmp(name, "backupport")) {
1074 int port = *(int *)val;
1075 if ((port <= 0) || (port > 65535)) {
1076 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1077 "Invalid port number!"));
1078 got_errno = SILC_CONFIG_EPRINTLINE;
1081 tmp->backup_replace_port = (SilcUInt16) port;
1083 else if (!strcmp(name, "backuplocal")) {
1084 tmp->backup_local = *(bool *)val;
1087 return SILC_CONFIG_EINTERNAL;
1089 return SILC_CONFIG_OK;
1092 silc_free(tmp->host);
1093 silc_free(tmp->backup_replace_ip);
1094 CONFIG_FREE_AUTH(tmp);
1100 /* known config options tables */
1101 static const SilcConfigTable table_general[] = {
1102 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1103 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1104 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1105 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1106 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1107 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1108 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1109 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1110 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1111 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1112 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1113 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1114 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1115 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1116 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1117 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1118 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1119 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1120 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1121 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1122 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1123 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1124 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1125 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1126 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1130 static const SilcConfigTable table_cipher[] = {
1131 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1132 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1133 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1134 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1138 static const SilcConfigTable table_hash[] = {
1139 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1140 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1141 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1142 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1146 static const SilcConfigTable table_hmac[] = {
1147 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1148 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1149 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1153 static const SilcConfigTable table_pkcs[] = {
1154 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1158 static const SilcConfigTable table_serverinfo_c[] = {
1159 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1160 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1164 static const SilcConfigTable table_serverinfo[] = {
1165 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1166 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1167 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1168 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1169 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1170 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1171 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1172 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1173 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1174 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1175 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1176 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1177 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1181 static const SilcConfigTable table_logging_c[] = {
1182 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1183 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1184 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1188 static const SilcConfigTable table_logging[] = {
1189 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1190 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1191 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1192 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1193 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1194 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1195 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1199 static const SilcConfigTable table_connparam[] = {
1200 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1201 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1202 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1203 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1204 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1205 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1206 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1207 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1208 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1209 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1210 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1211 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1212 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1213 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1214 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1215 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1216 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1217 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1218 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1219 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1223 static const SilcConfigTable table_client[] = {
1224 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1225 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1226 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1227 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1228 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1232 static const SilcConfigTable table_admin[] = {
1233 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1234 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1235 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1236 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1237 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1238 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1239 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1240 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1244 static const SilcConfigTable table_deny[] = {
1245 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1246 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1250 static const SilcConfigTable table_serverconn[] = {
1251 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1252 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1253 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1254 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1255 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1259 static const SilcConfigTable table_routerconn[] = {
1260 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1261 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1262 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1263 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1264 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1265 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1266 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1267 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1268 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1272 static const SilcConfigTable table_main[] = {
1273 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1274 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1275 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1276 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1277 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1278 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1279 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1280 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1281 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1282 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1283 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1284 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1285 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1289 /* Set default values to stuff that was not configured. */
1291 static void silc_server_config_set_defaults(SilcServerConfig config)
1293 my_set_param_defaults(&config->param, NULL);
1295 config->channel_rekey_secs = (config->channel_rekey_secs ?
1296 config->channel_rekey_secs :
1297 SILC_SERVER_CHANNEL_REKEY);
1298 config->key_exchange_timeout = (config->key_exchange_timeout ?
1299 config->key_exchange_timeout :
1300 SILC_SERVER_SKE_TIMEOUT);
1301 config->conn_auth_timeout = (config->conn_auth_timeout ?
1302 config->conn_auth_timeout :
1303 SILC_SERVER_CONNAUTH_TIMEOUT);
1306 /* Check for correctness of the configuration */
1308 static bool silc_server_config_check(SilcServerConfig config)
1311 SilcServerConfigServer *s;
1312 SilcServerConfigRouter *r;
1315 /* ServerConfig is mandatory */
1316 if (!config->server_info) {
1317 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1321 /* RouterConnection sanity checks */
1323 if (config->routers && config->routers->backup_router == TRUE &&
1325 SILC_SERVER_LOG_ERROR((
1326 "\nError: First RouterConnection block must be primary router "
1327 "connection. You have marked it incorrectly as backup router."));
1330 if (config->routers && config->routers->initiator == FALSE &&
1331 config->routers->backup_router == FALSE) {
1332 SILC_SERVER_LOG_ERROR((
1333 "\nError: First RouterConnection block must be primary router "
1334 "connection and it must be marked as Initiator."));
1337 if (config->routers && config->routers->backup_router == TRUE &&
1338 !config->servers && !config->routers->next) {
1339 SILC_SERVER_LOG_ERROR((
1340 "\nError: You have configured backup router but not primary router. "
1341 "If backup router is configured also primary router must be "
1346 /* Backup router sanity checks */
1348 for (r = config->routers; r; r = r->next) {
1349 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1350 SILC_SERVER_LOG_ERROR((
1351 "\nError: Backup router connection incorrectly configured to use "
1352 "primary and backup router as same host `%s'. They must not be "
1353 "same host.", r->host));
1358 /* ServerConnection sanity checks */
1360 for (s = config->servers; s; s = s->next) {
1361 if (s->backup_router) {
1367 for (s = config->servers; s; s = s->next) {
1368 if (!s->backup_router) {
1369 SILC_SERVER_LOG_ERROR((
1370 "\nError: Your server is backup router but not all ServerConnection "
1371 "blocks were marked as backup connections. They all must be "
1372 "marked as backup connections."));
1382 /* Allocates a new configuration object, opens configuration file and
1383 parses it. The parsed data is returned to the newly allocated
1384 configuration object. The SilcServerConfig must be freed by calling
1385 the silc_server_config_destroy function. */
1387 SilcServerConfig silc_server_config_alloc(const char *filename)
1389 SilcServerConfig config_new;
1390 SilcConfigEntity ent;
1391 SilcConfigFile *file;
1393 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1395 /* alloc a config object */
1396 config_new = silc_calloc(1, sizeof(*config_new));
1400 /* general config defaults */
1401 config_new->refcount = 1;
1402 config_new->logging_timestamp = TRUE;
1404 /* obtain a config file object */
1405 file = silc_config_open(filename);
1407 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1412 /* obtain a SilcConfig entity, we can use it to start the parsing */
1413 ent = silc_config_init(file);
1415 /* load the known configuration options, give our empty object as context */
1416 silc_config_register_table(ent, table_main, (void *) config_new);
1418 /* enter the main parsing loop. When this returns, we have the parsing
1419 * result and the object filled (or partially, in case of errors). */
1420 ret = silc_config_main(ent);
1421 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1422 silc_config_strerror(ret)));
1424 /* Check if the parser returned errors */
1426 /* handle this special error return which asks to quietly return */
1427 if (ret != SILC_CONFIG_ESILENT) {
1428 char *linebuf, *filename = silc_config_get_filename(file);
1429 SilcUInt32 line = silc_config_get_line(file);
1430 if (ret != SILC_CONFIG_EPRINTLINE)
1431 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1432 silc_config_strerror(ret)));
1433 linebuf = silc_config_read_line(file, line);
1435 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1440 silc_server_config_destroy(config_new);
1444 /* close (destroy) the file object */
1445 silc_config_close(file);
1447 /* Check the configuration */
1448 if (!silc_server_config_check(config_new)) {
1449 silc_server_config_destroy(config_new);
1453 /* Set default to configuration parameters */
1454 silc_server_config_set_defaults(config_new);
1459 /* Increments the reference counter of a config object */
1461 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1466 ref->config = config;
1467 ref->ref_ptr = ref_ptr;
1468 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1469 config->refcount - 1, config->refcount));
1473 /* Decrements the reference counter of a config object. If the counter
1474 reaches 0, the config object is destroyed. */
1476 void silc_server_config_unref(SilcServerConfigRef *ref)
1479 silc_server_config_destroy(ref->config);
1482 /* Destroy a config object with all his children lists */
1484 void silc_server_config_destroy(SilcServerConfig config)
1489 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1490 config->refcount + 1, config->refcount));
1491 if (config->refcount > 0)
1494 SILC_LOG_DEBUG(("Freeing config context"));
1496 /* Destroy general config stuff */
1497 silc_free(config->module_path);
1498 silc_free(config->param.version_protocol);
1499 silc_free(config->param.version_software);
1500 silc_free(config->param.version_software_vendor);
1502 /* Destroy Logging channels */
1503 if (config->logging_info)
1504 silc_free(config->logging_info->file);
1505 if (config->logging_warnings)
1506 silc_free(config->logging_warnings->file);
1507 if (config->logging_errors)
1508 silc_free(config->logging_errors->file);
1509 if (config->logging_fatals)
1510 silc_free(config->logging_fatals->file);
1511 silc_free(config->logging_info);
1512 silc_free(config->logging_warnings);
1513 silc_free(config->logging_errors);
1514 silc_free(config->logging_fatals);
1516 /* Destroy the ServerInfo struct */
1517 if (config->server_info) {
1518 register SilcServerConfigServerInfo *si = config->server_info;
1519 silc_free(si->server_name);
1521 silc_free(si->primary->server_ip);
1522 silc_free(si->primary);
1524 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1526 silc_free(di->server_ip);
1529 silc_free(si->server_type);
1530 silc_free(si->location);
1531 silc_free(si->admin);
1532 silc_free(si->email);
1533 silc_free(si->user);
1534 silc_free(si->group);
1535 silc_free(si->motd_file);
1536 silc_free(si->pid_file);
1537 silc_pkcs_public_key_free(si->public_key);
1538 silc_pkcs_private_key_free(si->private_key);
1542 /* Now let's destroy the lists */
1544 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1546 silc_free(di->name);
1547 silc_free(di->module);
1550 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1551 silc_free(di->name);
1552 silc_free(di->module);
1555 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1556 silc_free(di->name);
1557 silc_free(di->hash);
1560 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1561 silc_free(di->name);
1564 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1565 config->conn_params)
1566 silc_free(di->name);
1567 silc_free(di->version_protocol);
1568 silc_free(di->version_software);
1569 silc_free(di->version_software_vendor);
1572 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1573 silc_free(di->host);
1574 CONFIG_FREE_AUTH(di);
1577 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1578 silc_free(di->host);
1579 silc_free(di->user);
1580 silc_free(di->nick);
1581 CONFIG_FREE_AUTH(di);
1584 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1585 silc_free(di->host);
1586 silc_free(di->reason);
1589 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1591 silc_free(di->host);
1592 CONFIG_FREE_AUTH(di);
1595 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1597 silc_free(di->host);
1598 silc_free(di->backup_replace_ip);
1599 CONFIG_FREE_AUTH(di);
1603 memset(config, 'F', sizeof(*config));
1607 /* Registers configured ciphers. These can then be allocated by the
1608 server when needed. */
1610 bool silc_server_config_register_ciphers(SilcServer server)
1612 SilcServerConfig config = server->config;
1613 SilcServerConfigCipher *cipher = config->cipher;
1614 char *module_path = config->module_path;
1616 SILC_LOG_DEBUG(("Registering configured ciphers"));
1618 if (!cipher) /* any cipher in the config file? */
1622 /* if there isn't a module_path OR there isn't a module sim name try to
1623 * use buil-in functions */
1624 if (!module_path || !cipher->module) {
1626 for (i = 0; silc_default_ciphers[i].name; i++)
1627 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1628 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1631 if (!silc_cipher_is_supported(cipher->name)) {
1632 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1633 silc_server_stop(server);
1638 /* Load (try at least) the crypto SIM module */
1639 char buf[1023], *alg_name;
1640 SilcCipherObject cipher_obj;
1643 memset(&cipher_obj, 0, sizeof(cipher_obj));
1644 cipher_obj.name = cipher->name;
1645 cipher_obj.block_len = cipher->block_length;
1646 cipher_obj.key_len = cipher->key_length * 8;
1648 /* build the libname */
1649 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1651 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1653 alg_name = strdup(cipher->name);
1654 if (strchr(alg_name, '-'))
1655 *strchr(alg_name, '-') = '\0';
1657 if (silc_sim_load(sim)) {
1658 cipher_obj.set_key =
1659 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1660 SILC_CIPHER_SIM_SET_KEY));
1661 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1662 cipher_obj.set_key_with_string =
1663 silc_sim_getsym(sim,
1664 silc_sim_symname(alg_name,
1665 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1666 SILC_LOG_DEBUG(("set_key_with_string=%p",
1667 cipher_obj.set_key_with_string));
1668 cipher_obj.encrypt =
1669 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1670 SILC_CIPHER_SIM_ENCRYPT_CBC));
1671 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1672 cipher_obj.decrypt =
1673 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1674 SILC_CIPHER_SIM_DECRYPT_CBC));
1675 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1676 cipher_obj.context_len =
1677 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1678 SILC_CIPHER_SIM_CONTEXT_LEN));
1679 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1681 /* Put the SIM to the list of all SIM's in server */
1682 silc_dlist_add(server->sim, sim);
1684 silc_free(alg_name);
1686 SILC_LOG_ERROR(("Error configuring ciphers"));
1688 silc_server_stop(server);
1692 /* Register the cipher */
1693 silc_cipher_register(&cipher_obj);
1695 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1696 "can't load modules!"));
1697 silc_server_stop(server);
1701 cipher = cipher->next;
1707 /* Registers configured hash functions. These can then be allocated by the
1708 server when needed. */
1710 bool silc_server_config_register_hashfuncs(SilcServer server)
1712 SilcServerConfig config = server->config;
1713 SilcServerConfigHash *hash = config->hash;
1714 char *module_path = config->module_path;
1716 SILC_LOG_DEBUG(("Registering configured hash functions"));
1718 if (!hash) /* any hash func in the config file? */
1722 /* if there isn't a module_path OR there isn't a module sim name try to
1723 * use buil-in functions */
1724 if (!module_path || !hash->module) {
1726 for (i = 0; silc_default_hash[i].name; i++)
1727 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1728 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1731 if (!silc_hash_is_supported(hash->name)) {
1732 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1733 silc_server_stop(server);
1738 /* Load (try at least) the hash SIM module */
1739 SilcHashObject hash_obj;
1742 memset(&hash_obj, 0, sizeof(hash_obj));
1743 hash_obj.name = hash->name;
1744 hash_obj.block_len = hash->block_length;
1745 hash_obj.hash_len = hash->digest_length;
1747 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1749 if ((silc_sim_load(sim))) {
1751 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1752 SILC_HASH_SIM_INIT));
1753 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1755 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1756 SILC_HASH_SIM_UPDATE));
1757 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1759 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1760 SILC_HASH_SIM_FINAL));
1761 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1762 hash_obj.context_len =
1763 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1764 SILC_HASH_SIM_CONTEXT_LEN));
1765 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1767 /* Put the SIM to the table of all SIM's in server */
1768 silc_dlist_add(server->sim, sim);
1770 SILC_LOG_ERROR(("Error configuring hash functions"));
1772 silc_server_stop(server);
1776 /* Register the hash function */
1777 silc_hash_register(&hash_obj);
1779 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1780 "can't load modules!"));
1781 silc_server_stop(server);
1791 /* Registers configure HMACs. These can then be allocated by the server
1794 bool silc_server_config_register_hmacs(SilcServer server)
1796 SilcServerConfig config = server->config;
1797 SilcServerConfigHmac *hmac = config->hmac;
1799 SILC_LOG_DEBUG(("Registering configured HMACs"));
1805 SilcHmacObject hmac_obj;
1806 if (!silc_hash_is_supported(hmac->hash)) {
1807 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1808 silc_server_stop(server);
1812 /* Register the HMAC */
1813 memset(&hmac_obj, 0, sizeof(hmac_obj));
1814 hmac_obj.name = hmac->name;
1815 hmac_obj.len = hmac->mac_length;
1816 silc_hmac_register(&hmac_obj);
1824 /* Registers configured PKCS's. */
1826 bool silc_server_config_register_pkcs(SilcServer server)
1828 SilcServerConfig config = server->config;
1829 SilcServerConfigPkcs *pkcs = config->pkcs;
1831 SILC_LOG_DEBUG(("Registering configured PKCS"));
1838 for (i = 0; silc_default_pkcs[i].name; i++)
1839 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1840 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1843 if (!silc_pkcs_is_supported(pkcs->name)) {
1844 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1845 silc_server_stop(server);
1854 /* Sets log files where log messages are saved by the server logger. */
1856 void silc_server_config_setlogfiles(SilcServer server)
1858 SilcServerConfig config = server->config;
1859 SilcServerConfigLogging *this;
1861 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1863 silc_log_timestamp = config->logging_timestamp;
1864 silc_log_quick = config->logging_quick;
1865 silc_log_flushdelay = (config->logging_flushdelay ?
1866 config->logging_flushdelay :
1867 SILC_SERVER_LOG_FLUSH_DELAY);
1869 if ((this = config->logging_fatals))
1870 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1872 if ((this = config->logging_errors))
1873 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1875 if ((this = config->logging_warnings))
1876 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1878 if ((this = config->logging_info))
1879 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1883 /* Returns client authentication information from configuration file by host
1886 SilcServerConfigClient *
1887 silc_server_config_find_client(SilcServer server, char *host)
1889 SilcServerConfig config = server->config;
1890 SilcServerConfigClient *client;
1892 if (!config || !host)
1895 for (client = config->clients; client; client = client->next) {
1896 if (client->host && !silc_string_compare(client->host, host))
1901 /* if none matched, then client is already NULL */
1905 /* Returns admin connection configuration by host, username and/or
1908 SilcServerConfigAdmin *
1909 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1912 SilcServerConfig config = server->config;
1913 SilcServerConfigAdmin *admin;
1915 /* make sure we have a value for the matching parameters */
1923 for (admin = config->admins; admin; admin = admin->next) {
1924 if (admin->host && !silc_string_compare(admin->host, host))
1926 if (admin->user && !silc_string_compare(admin->user, user))
1928 if (admin->nick && !silc_string_compare(admin->nick, nick))
1930 /* no checks failed -> this entry matches */
1934 /* if none matched, then admin is already NULL */
1938 /* Returns the denied connection configuration entry by host. */
1940 SilcServerConfigDeny *
1941 silc_server_config_find_denied(SilcServer server, char *host)
1943 SilcServerConfig config = server->config;
1944 SilcServerConfigDeny *deny;
1946 /* make sure we have a value for the matching parameters */
1947 if (!config || !host)
1950 for (deny = config->denied; deny; deny = deny->next) {
1951 if (deny->host && !silc_string_compare(deny->host, host))
1956 /* if none matched, then deny is already NULL */
1960 /* Returns server connection info from server configuartion by host
1963 SilcServerConfigServer *
1964 silc_server_config_find_server_conn(SilcServer server, char *host)
1966 SilcServerConfig config = server->config;
1967 SilcServerConfigServer *serv = NULL;
1972 if (!config->servers)
1975 for (serv = config->servers; serv; serv = serv->next) {
1976 if (!silc_string_compare(serv->host, host))
1984 /* Returns router connection info from server configuration by
1985 host (name or ip). */
1987 SilcServerConfigRouter *
1988 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1990 SilcServerConfig config = server->config;
1991 SilcServerConfigRouter *serv = NULL;
1996 if (!config->routers)
1999 for (serv = config->routers; serv; serv = serv->next) {
2000 if (!silc_string_compare(serv->host, host))
2002 if (port && serv->port && serv->port != port)
2010 /* Find backup router connection by host (name or ip) */
2012 SilcServerConfigRouter *
2013 silc_server_config_find_backup_conn(SilcServer server, char *host)
2015 SilcServerConfig config = server->config;
2016 SilcServerConfigRouter *serv = NULL;
2021 if (!config->routers)
2024 for (serv = config->routers; serv; serv = serv->next) {
2025 if (!serv->backup_router)
2027 if (!silc_string_compare(serv->host, host))
2035 /* Returns TRUE if configuration for a router connection that we are
2036 initiating exists. */
2038 bool silc_server_config_is_primary_route(SilcServer server)
2040 SilcServerConfig config = server->config;
2041 SilcServerConfigRouter *serv = NULL;
2045 serv = config->routers;
2046 for (i = 0; serv; i++) {
2047 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2058 /* Returns our primary connection configuration or NULL if we do not
2059 have primary router configured. */
2061 SilcServerConfigRouter *
2062 silc_server_config_get_primary_router(SilcServer server)
2064 SilcServerConfig config = server->config;
2065 SilcServerConfigRouter *serv = NULL;
2068 serv = config->routers;
2069 for (i = 0; serv; i++) {
2070 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2078 /* If we have backup router configured that is going to replace us this
2079 function returns it. */
2081 SilcServerConfigRouter *
2082 silc_server_config_get_backup_router(SilcServer server)
2084 SilcServerConfig config = server->config;
2085 SilcServerConfigRouter *serv = NULL;
2088 if (server->server_type != SILC_ROUTER)
2091 serv = config->routers;
2092 for (i = 0; serv; i++) {
2093 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2094 serv->backup_local == TRUE &&
2095 !strcmp(server->config->server_info->primary->server_ip,
2096 serv->backup_replace_ip) &&
2097 server->config->server_info->primary->port ==
2098 serv->backup_replace_port)