5 Author: Giovanni Giacobbi <giovanni@giacobbi.net>
7 Copyright (C) 1997 - 2007 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "serverincludes.h"
22 #include "server_internal.h"
26 #define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
28 #define SERVER_CONFIG_DEBUG(fmt)
31 /* auto-declare needed variables for the common list parsing */
32 #define SILC_SERVER_CONFIG_SECTION_INIT(__type__) \
33 SilcServerConfig config = (SilcServerConfig) context; \
34 __type__ *findtmp, *tmp = (__type__ *) config->tmp; \
37 /* allocate the tmp field for fetching data */
38 #define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
40 config->tmp = silc_calloc(1, sizeof(*findtmp)); \
41 tmp = (__type__ *) config->tmp; \
44 /* append the tmp field to the specified list */
45 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
49 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
50 findtmp->next = tmp; \
53 /* loops all elements in a list and provides a di struct pointer of the
54 * specified type containing the current element */
55 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
56 for (tmp = (void *) __list__; tmp;) { \
57 __type__ *di = (__type__ *) tmp; \
58 tmp = (void *) di->next;
60 /* Set EDOUBLE error value and bail out if necessary */
61 #define CONFIG_IS_DOUBLE(__x__) \
63 got_errno = SILC_CONFIG_EDOUBLE; \
67 /* Free the authentication fields in the specified struct
68 * Expands to two instructions */
69 #define CONFIG_FREE_AUTH(__section__) \
70 silc_free(__section__->passphrase);
72 /* Set default values to those parameters that have not been defined */
74 my_set_param_defaults(SilcServerConfigConnParams *params,
75 SilcServerConfigConnParams *defaults)
77 #define SET_PARAM_DEFAULT(p, d) params->p = \
78 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
80 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
81 SET_PARAM_DEFAULT(connections_max_per_host,
82 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
83 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
84 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
85 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
86 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
87 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
88 SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
89 SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
90 SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
91 SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
92 SET_PARAM_DEFAULT(chlimit, SILC_SERVER_CH_JOIN_LIMIT);
94 #undef SET_PARAM_DEFAULT
97 /* Find connection parameters by the parameter block name. */
98 static SilcServerConfigConnParams *
99 my_find_param(SilcServerConfig config, const char *name)
101 SilcServerConfigConnParams *param;
103 for (param = config->conn_params; param; param = param->next) {
104 if (!strcasecmp(param->name, name))
108 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
109 "Cannot find Params \"%s\".", name));
114 /* SKR find callbcak */
116 static void my_find_callback(SilcSKR skr, SilcSKRFind find,
117 SilcSKRStatus status, SilcDList keys,
120 SilcSKRStatus *s = context;
124 silc_dlist_uninit(keys);
126 silc_skr_find_free(find);
129 /* parse an authdata according to its auth method */
130 static SilcBool my_parse_authdata(SilcAuthMethod auth_meth, const char *p,
131 void **auth_data, SilcUInt32 *auth_data_len,
132 SilcSKRKeyUsage usage, void *key_context)
134 if (auth_meth == SILC_AUTH_PASSWORD) {
135 /* p is a plain text password */
136 if (auth_data && auth_data_len) {
137 if (!silc_utf8_valid(p, strlen(p))) {
138 *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
140 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
141 silc_utf8_encode(p, strlen(p), SILC_STRING_LOCALE, *auth_data,
144 *auth_data = (void *) strdup(p);
145 *auth_data_len = (SilcUInt32) strlen(p);
148 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
149 /* p is a public key file name */
150 SilcPublicKey public_key;
151 SilcSKR skr = *auth_data;
153 SilcSKRStatus status = SILC_SKR_NOT_FOUND;
155 if (!silc_pkcs_load_public_key(p, &public_key)) {
156 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
157 "Could not load public key file!"));
161 find = silc_skr_find_alloc();
162 silc_skr_find_set_public_key(find, public_key);
163 silc_skr_find_set_usage(find, usage);
165 silc_skr_find_set_context(find, SILC_32_TO_PTR(usage));
166 silc_skr_find(skr, NULL, find, my_find_callback, &status);
167 if (status == SILC_SKR_OK) {
168 /* Already added, ignore error */
169 silc_pkcs_public_key_free(public_key);
173 /* Add the public key to repository */
174 status = silc_skr_add_public_key(skr, public_key, usage,
175 key_context ? key_context :
176 (void *)usage, NULL);
177 if (status != SILC_SKR_OK) {
178 SILC_SERVER_LOG_ERROR(("Error while adding public key \"%s\"", p));
186 static int my_parse_publickeydir(const char *dirname, void **auth_data,
187 SilcSKRKeyUsage usage)
190 struct dirent *get_file;
193 if (!(dp = opendir(dirname))) {
194 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
195 "Could not open directory \"%s\"", dirname));
199 /* errors are not considered fatal */
200 while ((get_file = readdir(dp))) {
201 const char *filename = get_file->d_name;
203 int dirname_len = strlen(dirname), filename_len = strlen(filename);
204 struct stat check_file;
206 /* Ignore "." and "..", and take files only with ".pub" suffix. */
207 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
208 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
211 memset(buf, 0, sizeof(buf));
212 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
213 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
215 if (stat(buf, &check_file) < 0) {
216 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
218 } else if (S_ISREG(check_file.st_mode)) {
219 if (my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL,
225 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
231 SILC_CONFIG_CALLBACK(fetch_generic)
233 SilcServerConfig config = (SilcServerConfig) context;
236 if (!strcmp(name, "prefer_passphrase_auth")) {
237 config->prefer_passphrase_auth = *(SilcBool *)val;
239 else if (!strcmp(name, "require_reverse_lookup")) {
240 config->require_reverse_lookup = *(SilcBool *)val;
242 else if (!strcmp(name, "connections_max")) {
243 config->param.connections_max = (SilcUInt32) *(int *)val;
245 else if (!strcmp(name, "connections_max_per_host")) {
246 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
248 else if (!strcmp(name, "keepalive_secs")) {
249 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
251 else if (!strcmp(name, "reconnect_count")) {
252 config->param.reconnect_count = (SilcUInt32) *(int *)val;
254 else if (!strcmp(name, "reconnect_interval")) {
255 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
257 else if (!strcmp(name, "reconnect_interval_max")) {
258 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
260 else if (!strcmp(name, "reconnect_keep_trying")) {
261 config->param.reconnect_keep_trying = *(SilcBool *)val;
263 else if (!strcmp(name, "key_exchange_rekey")) {
264 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
266 else if (!strcmp(name, "key_exchange_pfs")) {
267 config->param.key_exchange_pfs = *(SilcBool *)val;
269 else if (!strcmp(name, "channel_rekey_secs")) {
270 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
272 else if (!strcmp(name, "key_exchange_timeout")) {
273 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
275 else if (!strcmp(name, "conn_auth_timeout")) {
276 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
278 else if (!strcmp(name, "version_protocol")) {
279 CONFIG_IS_DOUBLE(config->param.version_protocol);
280 config->param.version_protocol =
281 (*(char *)val ? strdup((char *) val) : NULL);
283 else if (!strcmp(name, "version_software")) {
284 CONFIG_IS_DOUBLE(config->param.version_software);
285 config->param.version_software =
286 (*(char *)val ? strdup((char *) val) : NULL);
288 else if (!strcmp(name, "version_software_vendor")) {
289 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
290 config->param.version_software_vendor =
291 (*(char *)val ? strdup((char *) val) : NULL);
293 else if (!strcmp(name, "detach_disabled")) {
294 config->detach_disabled = *(SilcBool *)val;
296 else if (!strcmp(name, "detach_timeout")) {
297 config->detach_timeout = (SilcUInt32) *(int *)val;
299 else if (!strcmp(name, "qos")) {
300 config->param.qos = *(SilcBool *)val;
302 else if (!strcmp(name, "qos_rate_limit")) {
303 config->param.qos_rate_limit = *(SilcUInt32 *)val;
305 else if (!strcmp(name, "qos_bytes_limit")) {
306 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
308 else if (!strcmp(name, "qos_limit_sec")) {
309 config->param.qos_limit_sec = *(SilcUInt32 *)val;
311 else if (!strcmp(name, "qos_limit_usec")) {
312 config->param.qos_limit_usec = *(SilcUInt32 *)val;
314 else if (!strcmp(name, "channel_join_limit")) {
315 config->param.chlimit = *(SilcUInt32 *)val;
317 else if (!strcmp(name, "debug_string")) {
318 CONFIG_IS_DOUBLE(config->debug_string);
319 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
321 else if (!strcmp(name, "http_server")) {
322 config->httpd = *(SilcBool *)val;
324 else if (!strcmp(name, "http_server_ip")) {
325 CONFIG_IS_DOUBLE(config->httpd_ip);
326 config->httpd_ip = (*(char *)val ? strdup((char *) val) : NULL);
328 else if (!strcmp(name, "http_server_port")) {
329 int port = *(int *)val;
330 if ((port <= 0) || (port > 65535)) {
331 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
332 "Invalid port number!"));
333 got_errno = SILC_CONFIG_EPRINTLINE;
336 config->httpd_port = (SilcUInt16)port;
338 else if (!strcmp(name, "dynamic_server")) {
339 config->dynamic_server = *(SilcBool *)val;
341 else if (!strcmp(name, "local_channels")) {
342 config->local_channels = *(SilcBool *)val;
345 return SILC_CONFIG_EINTERNAL;
347 return SILC_CONFIG_OK;
353 SILC_CONFIG_CALLBACK(fetch_cipher)
355 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
357 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
358 type, name, context));
359 if (type == SILC_CONFIG_ARG_BLOCK) {
360 /* check the temporary struct's fields */
361 if (!tmp) /* discard empty sub-blocks */
362 return SILC_CONFIG_OK;
364 got_errno = SILC_CONFIG_EMISSFIELDS;
368 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
370 return SILC_CONFIG_OK;
372 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
374 /* Identify and save this value */
375 if (!strcmp(name, "name")) {
376 CONFIG_IS_DOUBLE(tmp->name);
377 tmp->name = strdup((char *) val);
379 else if (!strcmp(name, "keylength")) {
380 tmp->key_length = *(SilcUInt32 *)val;
382 else if (!strcmp(name, "blocklength")) {
383 tmp->block_length = *(SilcUInt32 *)val;
386 return SILC_CONFIG_EINTERNAL;
387 return SILC_CONFIG_OK;
390 silc_free(tmp->name);
396 SILC_CONFIG_CALLBACK(fetch_hash)
398 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
400 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
401 type, name, context));
402 if (type == SILC_CONFIG_ARG_BLOCK) {
403 /* check the temporary struct's fields */
404 if (!tmp) /* discard empty sub-blocks */
405 return SILC_CONFIG_OK;
406 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
407 got_errno = SILC_CONFIG_EMISSFIELDS;
411 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
413 return SILC_CONFIG_OK;
415 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
417 /* Identify and save this value */
418 if (!strcmp(name, "name")) {
419 CONFIG_IS_DOUBLE(tmp->name);
420 tmp->name = strdup((char *) val);
422 else if (!strcmp(name, "blocklength")) {
423 tmp->block_length = *(int *)val;
425 else if (!strcmp(name, "digestlength")) {
426 tmp->digest_length = *(int *)val;
429 return SILC_CONFIG_EINTERNAL;
430 return SILC_CONFIG_OK;
433 silc_free(tmp->name);
439 SILC_CONFIG_CALLBACK(fetch_hmac)
441 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
443 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
444 type, name, context));
445 if (type == SILC_CONFIG_ARG_BLOCK) {
446 /* check the temporary struct's fields */
447 if (!tmp) /* discard empty sub-blocks */
448 return SILC_CONFIG_OK;
449 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
450 got_errno = SILC_CONFIG_EMISSFIELDS;
454 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
456 return SILC_CONFIG_OK;
458 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
460 /* Identify and save this value */
461 if (!strcmp(name, "name")) {
462 CONFIG_IS_DOUBLE(tmp->name);
463 tmp->name = strdup((char *) val);
465 else if (!strcmp(name, "hash")) {
466 CONFIG_IS_DOUBLE(tmp->hash);
467 tmp->hash = strdup((char *) val);
469 else if (!strcmp(name, "maclength")) {
470 tmp->mac_length = *(int *)val;
473 return SILC_CONFIG_EINTERNAL;
474 return SILC_CONFIG_OK;
477 silc_free(tmp->name);
478 silc_free(tmp->hash);
484 SILC_CONFIG_CALLBACK(fetch_pkcs)
486 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
488 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
489 type, name, context));
490 if (type == SILC_CONFIG_ARG_BLOCK) {
491 /* Check the temporary struct's fields */
492 if (!tmp) /* discard empty sub-blocks */
493 return SILC_CONFIG_OK;
495 got_errno = SILC_CONFIG_EMISSFIELDS;
499 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
501 return SILC_CONFIG_OK;
503 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
505 /* Identify and save this value */
506 if (!strcmp(name, "name")) {
507 CONFIG_IS_DOUBLE(tmp->name);
508 tmp->name = strdup((char *) val);
511 return SILC_CONFIG_EINTERNAL;
512 return SILC_CONFIG_OK;
515 silc_free(tmp->name);
521 SILC_CONFIG_CALLBACK(fetch_serverinfo)
523 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
524 SilcServerConfigServerInfo *server_info = config->server_info;
526 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
527 type, name, context));
529 /* If there isn't the main struct alloc it */
531 config->server_info = server_info = (SilcServerConfigServerInfo *)
532 silc_calloc(1, sizeof(*server_info));
534 if (type == SILC_CONFIG_ARG_BLOCK) {
535 if (!strcmp(name, "primary")) {
536 if (server_info->primary) {
537 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
538 "Double primary specification."));
539 got_errno = SILC_CONFIG_EPRINTLINE;
542 CONFIG_IS_DOUBLE(server_info->primary);
544 /* now check the temporary struct, don't accept empty block and
545 make sure all fields are there */
546 if (!tmp || !tmp->server_ip || !tmp->port) {
547 got_errno = SILC_CONFIG_EMISSFIELDS;
550 server_info->primary = tmp;
552 return SILC_CONFIG_OK;
553 } else if (!strcmp(name, "secondary")) {
555 return SILC_CONFIG_OK;
556 if (!tmp || !tmp->server_ip || !tmp->port) {
557 got_errno = SILC_CONFIG_EMISSFIELDS;
560 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
562 return SILC_CONFIG_OK;
563 } else if (!server_info->public_key || !server_info->private_key) {
564 got_errno = SILC_CONFIG_EMISSFIELDS;
567 return SILC_CONFIG_OK;
569 if (!strcmp(name, "hostname")) {
570 CONFIG_IS_DOUBLE(server_info->server_name);
571 server_info->server_name = strdup((char *) val);
573 else if (!strcmp(name, "ip")) {
574 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
575 CONFIG_IS_DOUBLE(tmp->server_ip);
576 tmp->server_ip = strdup((char *) val);
578 else if (!strcmp(name, "public_ip")) {
579 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
580 CONFIG_IS_DOUBLE(tmp->public_ip);
581 tmp->public_ip = strdup((char *) val);
583 else if (!strcmp(name, "port")) {
584 int port = *(int *)val;
585 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
586 if ((port <= 0) || (port > 65535)) {
587 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
588 "Invalid port number!"));
589 got_errno = SILC_CONFIG_EPRINTLINE;
592 tmp->port = (SilcUInt16) port;
594 else if (!strcmp(name, "servertype")) {
595 CONFIG_IS_DOUBLE(server_info->server_type);
596 server_info->server_type = strdup((char *) val);
598 else if (!strcmp(name, "externalip")) {
599 CONFIG_IS_DOUBLE(server_info->external_ip);
600 server_info->external_ip = strdup((char *) val);
602 else if (!strcmp(name, "admin")) {
603 CONFIG_IS_DOUBLE(server_info->admin);
604 server_info->admin = strdup((char *) val);
606 else if (!strcmp(name, "adminemail")) {
607 CONFIG_IS_DOUBLE(server_info->email);
608 server_info->email = strdup((char *) val);
610 else if (!strcmp(name, "location")) {
611 CONFIG_IS_DOUBLE(server_info->location);
612 server_info->location = strdup((char *) val);
614 else if (!strcmp(name, "user")) {
615 CONFIG_IS_DOUBLE(server_info->user);
616 server_info->user = strdup((char *) val);
618 else if (!strcmp(name, "group")) {
619 CONFIG_IS_DOUBLE(server_info->group);
620 server_info->group = strdup((char *) val);
622 else if (!strcmp(name, "motdfile")) {
623 CONFIG_IS_DOUBLE(server_info->motd_file);
624 server_info->motd_file = strdup((char *) val);
626 else if (!strcmp(name, "pidfile")) {
627 CONFIG_IS_DOUBLE(server_info->pid_file);
628 server_info->pid_file = strdup((char *) val);
630 else if (!strcmp(name, "publickey")) {
631 char *file_tmp = (char *) val;
632 CONFIG_IS_DOUBLE(server_info->public_key);
634 /* Try to load specified file, if fail stop config parsing */
635 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key)) {
636 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
637 return SILC_CONFIG_EPRINTLINE;
640 else if (!strcmp(name, "privatekey")) {
642 char *file_tmp = (char *) val;
643 CONFIG_IS_DOUBLE(server_info->private_key);
645 /* Check the private key file permissions. */
646 if ((stat(file_tmp, &st)) != -1) {
647 if (((st.st_mode & 0777) != 0600) &&
648 ((st.st_mode & 0777) != 0640)) {
649 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
650 "file \"%s\". The permissions must be "
651 "0600 or 0640.", file_tmp));
652 return SILC_CONFIG_ESILENT;
656 /* Try to load specified file, if fail stop config parsing */
657 if (!silc_pkcs_load_private_key(file_tmp, "", 0,
658 &server_info->private_key)) {
659 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
660 return SILC_CONFIG_EPRINTLINE;
664 return SILC_CONFIG_EINTERNAL;
665 return SILC_CONFIG_OK;
668 /* Here we need to check if tmp exists because this function handles
669 * misc data (multiple fields and single-only fields) */
671 silc_free(tmp->server_ip);
678 SILC_CONFIG_CALLBACK(fetch_logging)
680 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
682 if (!strcmp(name, "timestamp")) {
683 config->logging_timestamp = *(SilcBool *)val;
685 else if (!strcmp(name, "quicklogs")) {
686 config->logging_quick = *(SilcBool *)val;
688 else if (!strcmp(name, "flushdelay")) {
689 int flushdelay = *(int *)val;
690 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
691 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
692 "Invalid flushdelay value, use quicklogs if you "
693 "want real-time logging."));
694 return SILC_CONFIG_EPRINTLINE;
696 config->logging_flushdelay = (long) flushdelay;
699 /* The following istances happens only in Logging's sub-blocks, a match
700 for the sub-block name means that you should store the filename/maxsize
701 temporary struct to the proper logging channel.
702 If we get a match for "file" or "maxsize" this means that we are inside
703 a sub-sub-block and it is safe to alloc a new tmp. */
704 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
705 else if (!strcmp(name, __chan__)) { \
706 if (!tmp) return SILC_CONFIG_OK; \
708 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
710 config->__member__ = tmp; \
711 config->tmp = NULL; \
713 FETCH_LOGGING_CHAN("info", logging_info)
714 FETCH_LOGGING_CHAN("warnings", logging_warnings)
715 FETCH_LOGGING_CHAN("errors", logging_errors)
716 FETCH_LOGGING_CHAN("fatals", logging_fatals)
717 #undef FETCH_LOGGING_CHAN
718 else if (!strcmp(name, "file")) {
719 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
720 CONFIG_IS_DOUBLE(tmp->file);
721 tmp->file = strdup((char *) val);
723 else if (!strcmp(name, "size")) {
725 config->tmp = silc_calloc(1, sizeof(*tmp));
726 tmp = (SilcServerConfigLogging *) config->tmp;
728 tmp->maxsize = *(SilcUInt32 *) val;
731 return SILC_CONFIG_EINTERNAL;
732 return SILC_CONFIG_OK;
735 silc_free(tmp->file);
741 SILC_CONFIG_CALLBACK(fetch_connparam)
743 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
745 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
746 type, name, context));
747 if (type == SILC_CONFIG_ARG_BLOCK) {
748 /* check the temporary struct's fields */
749 if (!tmp) /* discard empty sub-blocks */
750 return SILC_CONFIG_OK;
752 got_errno = SILC_CONFIG_EMISSFIELDS;
756 my_set_param_defaults(tmp, &config->param);
758 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
760 return SILC_CONFIG_OK;
763 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
764 tmp->reconnect_keep_trying = TRUE;
767 if (!strcmp(name, "name")) {
768 CONFIG_IS_DOUBLE(tmp->name);
769 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
771 else if (!strcmp(name, "connections_max")) {
772 tmp->connections_max = *(SilcUInt32 *)val;
774 else if (!strcmp(name, "connections_max_per_host")) {
775 tmp->connections_max_per_host = *(SilcUInt32 *)val;
777 else if (!strcmp(name, "keepalive_secs")) {
778 tmp->keepalive_secs = *(SilcUInt32 *)val;
780 else if (!strcmp(name, "reconnect_count")) {
781 tmp->reconnect_count = *(SilcUInt32 *)val;
783 else if (!strcmp(name, "reconnect_interval")) {
784 tmp->reconnect_interval = *(SilcUInt32 *)val;
786 else if (!strcmp(name, "reconnect_interval_max")) {
787 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
789 else if (!strcmp(name, "reconnect_keep_trying")) {
790 tmp->reconnect_keep_trying = *(SilcBool *)val;
792 else if (!strcmp(name, "key_exchange_rekey")) {
793 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
795 else if (!strcmp(name, "key_exchange_pfs")) {
796 tmp->key_exchange_pfs = *(SilcBool *)val;
798 else if (!strcmp(name, "version_protocol")) {
799 CONFIG_IS_DOUBLE(tmp->version_protocol);
800 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
802 else if (!strcmp(name, "version_software")) {
803 CONFIG_IS_DOUBLE(tmp->version_software);
804 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
806 else if (!strcmp(name, "version_software_vendor")) {
807 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
808 tmp->version_software_vendor =
809 (*(char *)val ? strdup((char *) val) : NULL);
811 else if (!strcmp(name, "anonymous")) {
812 tmp->anonymous = *(SilcBool *)val;
814 else if (!strcmp(name, "qos")) {
815 tmp->qos = *(SilcBool *)val;
817 else if (!strcmp(name, "qos_rate_limit")) {
818 tmp->qos_rate_limit = *(SilcUInt32 *)val;
820 else if (!strcmp(name, "qos_bytes_limit")) {
821 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
823 else if (!strcmp(name, "qos_limit_sec")) {
824 tmp->qos_limit_sec = *(SilcUInt32 *)val;
826 else if (!strcmp(name, "qos_limit_usec")) {
827 tmp->qos_limit_usec = *(SilcUInt32 *)val;
830 return SILC_CONFIG_EINTERNAL;
832 return SILC_CONFIG_OK;
835 silc_free(tmp->name);
841 SILC_CONFIG_CALLBACK(fetch_client)
843 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
845 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
846 type, name, context));
848 /* Alloc before block checking, because empty sub-blocks are welcome here */
849 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
851 if (type == SILC_CONFIG_ARG_BLOCK) {
852 /* empty sub-blocks are welcome */
853 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
855 return SILC_CONFIG_OK;
858 /* Identify and save this value */
859 if (!strcmp(name, "host")) {
860 CONFIG_IS_DOUBLE(tmp->host);
861 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
863 else if (!strcmp(name, "passphrase")) {
864 CONFIG_IS_DOUBLE(tmp->passphrase);
865 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
866 (void *)&tmp->passphrase,
867 &tmp->passphrase_len, 0, NULL)) {
868 got_errno = SILC_CONFIG_EPRINTLINE;
872 else if (!strcmp(name, "publickey")) {
873 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
874 (void *)&config->server->repository, NULL,
875 SILC_SKR_USAGE_AUTH |
876 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
877 got_errno = SILC_CONFIG_EPRINTLINE;
880 tmp->publickeys = TRUE;
882 else if (!strcmp(name, "publickeydir")) {
883 if (my_parse_publickeydir((char *) val,
884 (void *)&config->server->repository,
885 SILC_SKR_USAGE_AUTH |
886 SILC_SKR_USAGE_KEY_AGREEMENT) < 0) {
887 got_errno = SILC_CONFIG_EPRINTLINE;
890 tmp->publickeys = TRUE;
892 else if (!strcmp(name, "params")) {
893 CONFIG_IS_DOUBLE(tmp->param);
894 tmp->param = my_find_param(config, (char *) val);
895 if (!tmp->param) { /* error message already output */
896 got_errno = SILC_CONFIG_EPRINTLINE;
901 return SILC_CONFIG_EINTERNAL;
902 return SILC_CONFIG_OK;
905 silc_free(tmp->host);
906 CONFIG_FREE_AUTH(tmp);
912 SILC_CONFIG_CALLBACK(fetch_admin)
914 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
916 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
917 type, name, context));
918 if (type == SILC_CONFIG_ARG_BLOCK) {
919 /* check the temporary struct's fields */
920 if (!tmp) /* discard empty sub-blocks */
921 return SILC_CONFIG_OK;
923 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
925 return SILC_CONFIG_OK;
927 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
929 /* Identify and save this value */
930 if (!strcmp(name, "host")) {
931 CONFIG_IS_DOUBLE(tmp->host);
932 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
934 else if (!strcmp(name, "user")) {
935 CONFIG_IS_DOUBLE(tmp->user);
936 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
938 else if (!strcmp(name, "nick")) {
939 CONFIG_IS_DOUBLE(tmp->nick);
940 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
942 else if (!strcmp(name, "passphrase")) {
943 CONFIG_IS_DOUBLE(tmp->passphrase);
944 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
945 (void *)&tmp->passphrase,
946 &tmp->passphrase_len, 0, NULL)) {
947 got_errno = SILC_CONFIG_EPRINTLINE;
951 else if (!strcmp(name, "publickey")) {
952 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
953 (void *)&config->server->repository, NULL,
954 SILC_SKR_USAGE_SERVICE_AUTHORIZATION, tmp)) {
955 got_errno = SILC_CONFIG_EPRINTLINE;
958 tmp->publickeys = TRUE;
961 return SILC_CONFIG_EINTERNAL;
962 return SILC_CONFIG_OK;
965 silc_free(tmp->host);
966 silc_free(tmp->user);
967 silc_free(tmp->nick);
968 CONFIG_FREE_AUTH(tmp);
974 SILC_CONFIG_CALLBACK(fetch_deny)
976 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
978 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
979 type, name, context));
980 if (type == SILC_CONFIG_ARG_BLOCK) {
981 /* check the temporary struct's fields */
982 if (!tmp) /* discard empty sub-blocks */
983 return SILC_CONFIG_OK;
985 got_errno = SILC_CONFIG_EMISSFIELDS;
989 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
991 return SILC_CONFIG_OK;
993 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
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, "reason")) {
1001 CONFIG_IS_DOUBLE(tmp->reason);
1002 tmp->reason = strdup((char *) val);
1005 return SILC_CONFIG_EINTERNAL;
1006 return SILC_CONFIG_OK;
1009 silc_free(tmp->host);
1010 silc_free(tmp->reason);
1016 SILC_CONFIG_CALLBACK(fetch_server)
1018 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
1020 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
1021 type, name, context));
1022 if (type == SILC_CONFIG_ARG_BLOCK) {
1023 /* check the temporary struct's fields */
1024 if (!tmp) /* discard empty sub-blocks */
1025 return SILC_CONFIG_OK;
1027 got_errno = SILC_CONFIG_EMISSFIELDS;
1031 /* the temporary struct is ok, append it to the list */
1032 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1034 return SILC_CONFIG_OK;
1036 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1038 /* Identify and save this value */
1039 if (!strcmp(name, "host")) {
1040 CONFIG_IS_DOUBLE(tmp->host);
1041 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1043 else if (!strcmp(name, "passphrase")) {
1044 CONFIG_IS_DOUBLE(tmp->passphrase);
1045 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1046 (void *)&tmp->passphrase,
1047 &tmp->passphrase_len, 0, NULL)) {
1048 got_errno = SILC_CONFIG_EPRINTLINE;
1052 else if (!strcmp(name, "publickey")) {
1053 CONFIG_IS_DOUBLE(tmp->publickeys);
1054 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1055 (void *)&config->server->repository, NULL,
1056 SILC_SKR_USAGE_AUTH |
1057 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1058 got_errno = SILC_CONFIG_EPRINTLINE;
1061 tmp->publickeys = TRUE;
1063 else if (!strcmp(name, "params")) {
1064 CONFIG_IS_DOUBLE(tmp->param);
1065 tmp->param = my_find_param(config, (char *) val);
1066 if (!tmp->param) { /* error message already output */
1067 got_errno = SILC_CONFIG_EPRINTLINE;
1071 else if (!strcmp(name, "backup")) {
1072 tmp->backup_router = *(SilcBool *)val;
1075 return SILC_CONFIG_EINTERNAL;
1077 return SILC_CONFIG_OK;
1080 silc_free(tmp->host);
1081 CONFIG_FREE_AUTH(tmp);
1087 SILC_CONFIG_CALLBACK(fetch_router)
1089 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1091 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1092 type, name, context));
1093 if (type == SILC_CONFIG_ARG_BLOCK) {
1094 if (!tmp) /* discard empty sub-blocks */
1095 return SILC_CONFIG_OK;
1097 got_errno = SILC_CONFIG_EMISSFIELDS;
1101 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1103 return SILC_CONFIG_OK;
1105 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1107 /* Identify and save this value */
1108 if (!strcmp(name, "host")) {
1109 CONFIG_IS_DOUBLE(tmp->host);
1110 tmp->host = strdup((char *) val);
1112 else if (!strcmp(name, "port")) {
1113 int port = *(int *)val;
1114 if ((port <= 0) || (port > 65535)) {
1115 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1116 "Invalid port number!"));
1117 got_errno = SILC_CONFIG_EPRINTLINE;
1120 tmp->port = (SilcUInt16) port;
1122 else if (!strcmp(name, "passphrase")) {
1123 CONFIG_IS_DOUBLE(tmp->passphrase);
1124 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1125 (void *)&tmp->passphrase,
1126 &tmp->passphrase_len, 0, NULL)) {
1127 got_errno = SILC_CONFIG_EPRINTLINE;
1131 else if (!strcmp(name, "publickey")) {
1132 CONFIG_IS_DOUBLE(tmp->publickeys);
1133 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1134 (void *)&config->server->repository, NULL,
1135 SILC_SKR_USAGE_AUTH |
1136 SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) {
1137 got_errno = SILC_CONFIG_EPRINTLINE;
1140 tmp->publickeys = TRUE;
1142 else if (!strcmp(name, "params")) {
1143 CONFIG_IS_DOUBLE(tmp->param);
1144 tmp->param = my_find_param(config, (char *) val);
1145 if (!tmp->param) { /* error message already output */
1146 got_errno = SILC_CONFIG_EPRINTLINE;
1150 else if (!strcmp(name, "initiator")) {
1151 tmp->initiator = *(SilcBool *)val;
1153 else if (!strcmp(name, "backuphost")) {
1154 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1155 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1157 tmp->backup_router = TRUE;
1159 else if (!strcmp(name, "backupport")) {
1160 int port = *(int *)val;
1161 if ((port <= 0) || (port > 65535)) {
1162 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1163 "Invalid port number!"));
1164 got_errno = SILC_CONFIG_EPRINTLINE;
1167 tmp->backup_replace_port = (SilcUInt16) port;
1169 else if (!strcmp(name, "backuplocal")) {
1170 tmp->backup_local = *(SilcBool *)val;
1172 else if (!strcmp(name, "dynamic_connection")) {
1173 tmp->dynamic_connection = *(SilcBool *)val;
1176 return SILC_CONFIG_EINTERNAL;
1178 return SILC_CONFIG_OK;
1181 silc_free(tmp->host);
1182 silc_free(tmp->backup_replace_ip);
1183 CONFIG_FREE_AUTH(tmp);
1189 /* known config options tables */
1190 static const SilcConfigTable table_general[] = {
1191 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1192 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1193 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1194 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1195 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1196 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1197 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1198 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1199 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1200 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1201 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1202 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1203 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1204 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1205 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1206 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1207 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1208 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1209 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1210 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1211 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1212 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1213 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1214 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1215 { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1216 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1217 { "http_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1218 { "http_server_ip", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1219 { "http_server_port", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1220 { "dynamic_server", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1221 { "local_channels", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1225 static const SilcConfigTable table_cipher[] = {
1226 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1227 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1228 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1232 static const SilcConfigTable table_hash[] = {
1233 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1234 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1235 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1239 static const SilcConfigTable table_hmac[] = {
1240 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1241 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1242 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1246 static const SilcConfigTable table_pkcs[] = {
1247 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1251 static const SilcConfigTable table_serverinfo_c[] = {
1252 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1253 { "public_ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1254 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1258 static const SilcConfigTable table_serverinfo[] = {
1259 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1260 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1261 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1262 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1263 { "externalip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1264 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1265 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1266 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1267 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1268 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1269 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1270 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1271 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1272 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1276 static const SilcConfigTable table_logging_c[] = {
1277 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1278 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1279 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1283 static const SilcConfigTable table_logging[] = {
1284 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1285 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1286 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1287 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1288 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1289 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1290 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1294 static const SilcConfigTable table_connparam[] = {
1295 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1296 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1297 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1298 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1299 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1300 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1301 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1302 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1303 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1304 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1305 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1306 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1307 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1308 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1309 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1310 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1311 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1312 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1313 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1314 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1318 static const SilcConfigTable table_client[] = {
1319 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1320 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1321 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1322 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1323 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1327 static const SilcConfigTable table_admin[] = {
1328 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1329 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1330 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1331 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1332 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1333 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1334 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1338 static const SilcConfigTable table_deny[] = {
1339 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1340 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1344 static const SilcConfigTable table_serverconn[] = {
1345 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1346 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1347 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1348 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1349 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1353 static const SilcConfigTable table_routerconn[] = {
1354 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1355 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1356 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1357 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1358 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1359 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1360 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1361 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1362 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1363 { "dynamic_connection", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1367 static const SilcConfigTable table_main[] = {
1368 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1369 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1370 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1371 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1372 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1373 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1374 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1375 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1376 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1377 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1378 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1379 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1380 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1384 /* Set default values to stuff that was not configured. */
1386 static void silc_server_config_set_defaults(SilcServerConfig config)
1388 my_set_param_defaults(&config->param, NULL);
1390 config->channel_rekey_secs = (config->channel_rekey_secs ?
1391 config->channel_rekey_secs :
1392 SILC_SERVER_CHANNEL_REKEY);
1393 config->key_exchange_timeout = (config->key_exchange_timeout ?
1394 config->key_exchange_timeout :
1395 SILC_SERVER_SKE_TIMEOUT);
1396 config->conn_auth_timeout = (config->conn_auth_timeout ?
1397 config->conn_auth_timeout :
1398 SILC_SERVER_CONNAUTH_TIMEOUT);
1401 /* Check for correctness of the configuration */
1403 static SilcBool silc_server_config_check(SilcServerConfig config)
1405 SilcBool ret = TRUE;
1406 SilcServerConfigServer *s;
1407 SilcServerConfigRouter *r;
1410 /* ServerConfig is mandatory */
1411 if (!config->server_info) {
1412 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1416 if (!config->server_info->public_key ||
1417 !config->server_info->private_key) {
1418 SILC_SERVER_LOG_ERROR(("\nError: Server keypair is missing"));
1422 if (!config->server_info->primary) {
1423 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `Primary' "
1424 "in `ServerInfo'"));
1428 if (!config->server_info->primary->server_ip) {
1429 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory field `Ip' "
1430 "in `Primary' in `ServerInfo'"));
1434 /* RouterConnection sanity checks */
1436 if (config->routers && config->routers->backup_router == TRUE &&
1438 SILC_SERVER_LOG_ERROR((
1439 "\nError: First RouterConnection block must be primary router "
1440 "connection. You have marked it incorrectly as backup router."));
1443 if (config->routers && config->routers->backup_router == TRUE &&
1444 !config->servers && !config->routers->next) {
1445 SILC_SERVER_LOG_ERROR((
1446 "\nError: You have configured backup router but not primary router. "
1447 "If backup router is configured also primary router must be "
1452 /* Backup router sanity checks */
1454 for (r = config->routers; r; r = r->next) {
1455 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1456 SILC_SERVER_LOG_ERROR((
1457 "\nError: Backup router connection incorrectly configured to use "
1458 "primary and backup router as same host `%s'. They must not be "
1459 "same host.", r->host));
1463 if (r->initiator == FALSE && r->port != 0) {
1464 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1465 "specified. Ignoring Port value."));
1470 /* ServerConnection sanity checks */
1472 for (s = config->servers; s; s = s->next) {
1473 if (s->backup_router) {
1479 for (s = config->servers; s; s = s->next) {
1480 if (!s->backup_router) {
1481 SILC_SERVER_LOG_ERROR((
1482 "\nError: Your server is backup router but not all ServerConnection "
1483 "blocks were marked as backup connections. They all must be "
1484 "marked as backup connections."));
1494 /* Allocates a new configuration object, opens configuration file and
1495 parses it. The parsed data is returned to the newly allocated
1496 configuration object. The SilcServerConfig must be freed by calling
1497 the silc_server_config_destroy function. */
1499 SilcServerConfig silc_server_config_alloc(const char *filename,
1502 SilcServerConfig config_new;
1503 SilcConfigEntity ent;
1504 SilcConfigFile *file;
1506 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1508 /* alloc a config object */
1509 config_new = silc_calloc(1, sizeof(*config_new));
1513 /* general config defaults */
1514 config_new->refcount = 1;
1515 config_new->logging_timestamp = TRUE;
1516 config_new->param.reconnect_keep_trying = TRUE;
1517 config_new->server = server;
1519 /* obtain a config file object */
1520 file = silc_config_open(filename);
1522 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1527 /* obtain a SilcConfig entity, we can use it to start the parsing */
1528 ent = silc_config_init(file);
1530 /* load the known configuration options, give our empty object as context */
1531 silc_config_register_table(ent, table_main, (void *) config_new);
1533 /* enter the main parsing loop. When this returns, we have the parsing
1534 * result and the object filled (or partially, in case of errors). */
1535 ret = silc_config_main(ent);
1536 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1537 silc_config_strerror(ret)));
1539 /* Check if the parser returned errors */
1541 /* handle this special error return which asks to quietly return */
1542 if (ret != SILC_CONFIG_ESILENT) {
1543 char *linebuf, *filename = silc_config_get_filename(file);
1544 SilcUInt32 line = silc_config_get_line(file);
1545 if (ret != SILC_CONFIG_EPRINTLINE)
1546 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1547 silc_config_strerror(ret)));
1548 linebuf = silc_config_read_line(file, line);
1550 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1555 silc_server_config_destroy(config_new);
1556 silc_config_close(file);
1560 /* close (destroy) the file object */
1561 silc_config_close(file);
1563 /* Check the configuration */
1564 if (!silc_server_config_check(config_new)) {
1565 silc_server_config_destroy(config_new);
1569 /* Set default to configuration parameters */
1570 silc_server_config_set_defaults(config_new);
1575 /* Increments the reference counter of a config object */
1577 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1582 ref->config = config;
1583 ref->ref_ptr = ref_ptr;
1584 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1585 config->refcount - 1, config->refcount));
1589 /* Decrements the reference counter of a config object. If the counter
1590 reaches 0, the config object is destroyed. */
1592 void silc_server_config_unref(SilcServerConfigRef *ref)
1595 silc_server_config_destroy(ref->config);
1598 /* Destroy a config object with all his children lists */
1600 void silc_server_config_destroy(SilcServerConfig config)
1605 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1606 config->refcount + 1, config->refcount));
1607 if (config->refcount > 0)
1610 SILC_LOG_DEBUG(("Freeing config context"));
1612 /* Destroy general config stuff */
1613 silc_free(config->debug_string);
1614 silc_free(config->param.version_protocol);
1615 silc_free(config->param.version_software);
1616 silc_free(config->param.version_software_vendor);
1617 silc_free(config->httpd_ip);
1619 /* Destroy Logging channels */
1620 if (config->logging_info)
1621 silc_free(config->logging_info->file);
1622 if (config->logging_warnings)
1623 silc_free(config->logging_warnings->file);
1624 if (config->logging_errors)
1625 silc_free(config->logging_errors->file);
1626 if (config->logging_fatals)
1627 silc_free(config->logging_fatals->file);
1628 silc_free(config->logging_info);
1629 silc_free(config->logging_warnings);
1630 silc_free(config->logging_errors);
1631 silc_free(config->logging_fatals);
1633 /* Destroy the ServerInfo struct */
1634 if (config->server_info) {
1635 register SilcServerConfigServerInfo *si = config->server_info;
1636 silc_free(si->server_name);
1638 silc_free(si->primary->server_ip);
1639 silc_free(si->primary);
1641 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1643 silc_free(di->server_ip);
1646 silc_free(si->server_type);
1647 silc_free(si->external_ip);
1648 silc_free(si->location);
1649 silc_free(si->admin);
1650 silc_free(si->email);
1651 silc_free(si->user);
1652 silc_free(si->group);
1653 silc_free(si->motd_file);
1654 silc_free(si->pid_file);
1656 silc_pkcs_public_key_free(si->public_key);
1657 if (si->private_key)
1658 silc_pkcs_private_key_free(si->private_key);
1662 /* Now let's destroy the lists */
1664 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1666 silc_free(di->name);
1669 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1670 silc_free(di->name);
1673 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1674 silc_free(di->name);
1675 silc_free(di->hash);
1678 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1679 silc_free(di->name);
1682 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1683 config->conn_params)
1684 silc_free(di->name);
1685 silc_free(di->version_protocol);
1686 silc_free(di->version_software);
1687 silc_free(di->version_software_vendor);
1690 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1691 silc_free(di->host);
1692 CONFIG_FREE_AUTH(di);
1695 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1696 silc_free(di->host);
1697 silc_free(di->user);
1698 silc_free(di->nick);
1699 CONFIG_FREE_AUTH(di);
1702 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1703 silc_free(di->host);
1704 silc_free(di->reason);
1707 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1709 silc_free(di->host);
1710 CONFIG_FREE_AUTH(di);
1713 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1715 silc_free(di->host);
1716 silc_free(di->backup_replace_ip);
1717 CONFIG_FREE_AUTH(di);
1721 memset(config, 'F', sizeof(*config));
1725 /* Registers configured ciphers. These can then be allocated by the
1726 server when needed. */
1728 SilcBool silc_server_config_register_ciphers(SilcServer server)
1730 SilcServerConfig config = server->config;
1731 SilcServerConfigCipher *cipher = config->cipher;
1732 char *module_path = config->module_path;
1734 SILC_LOG_DEBUG(("Registering configured ciphers"));
1736 if (!cipher) /* any cipher in the config file? */
1740 /* if there isn't a module_path OR there isn't a module sim name try to
1741 * use buil-in functions */
1742 if (!module_path || !cipher->module) {
1744 for (i = 0; silc_default_ciphers[i].name; i++)
1745 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1746 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1749 if (!silc_cipher_is_supported(cipher->name)) {
1750 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1751 silc_server_stop(server);
1755 cipher = cipher->next;
1761 /* Registers configured hash functions. These can then be allocated by the
1762 server when needed. */
1764 SilcBool silc_server_config_register_hashfuncs(SilcServer server)
1766 SilcServerConfig config = server->config;
1767 SilcServerConfigHash *hash = config->hash;
1768 char *module_path = config->module_path;
1770 SILC_LOG_DEBUG(("Registering configured hash functions"));
1772 if (!hash) /* any hash func in the config file? */
1776 /* if there isn't a module_path OR there isn't a module sim name try to
1777 * use buil-in functions */
1778 if (!module_path || !hash->module) {
1780 for (i = 0; silc_default_hash[i].name; i++)
1781 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1782 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1785 if (!silc_hash_is_supported(hash->name)) {
1786 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1787 silc_server_stop(server);
1797 /* Registers configure HMACs. These can then be allocated by the server
1800 SilcBool silc_server_config_register_hmacs(SilcServer server)
1802 SilcServerConfig config = server->config;
1803 SilcServerConfigHmac *hmac = config->hmac;
1805 SILC_LOG_DEBUG(("Registering configured HMACs"));
1811 SilcHmacObject hmac_obj;
1812 if (!silc_hash_is_supported(hmac->hash)) {
1813 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1814 silc_server_stop(server);
1818 /* Register the HMAC */
1819 memset(&hmac_obj, 0, sizeof(hmac_obj));
1820 hmac_obj.name = hmac->name;
1821 hmac_obj.len = hmac->mac_length;
1822 silc_hmac_register(&hmac_obj);
1830 /* Registers configured PKCS's. */
1832 SilcBool silc_server_config_register_pkcs(SilcServer server)
1837 /* Sets log files where log messages are saved by the server logger. */
1839 void silc_server_config_setlogfiles(SilcServer server)
1841 SilcServerConfig config = server->config;
1842 SilcServerConfigLogging *this;
1844 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1846 silc_log_timestamp(config->logging_timestamp);
1847 silc_log_quick(config->logging_quick);
1848 silc_log_flushdelay(config->logging_flushdelay ?
1849 config->logging_flushdelay :
1850 SILC_SERVER_LOG_FLUSH_DELAY);
1852 if ((this = config->logging_fatals))
1853 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1855 if ((this = config->logging_errors))
1856 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1858 if ((this = config->logging_warnings))
1859 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1861 if ((this = config->logging_info))
1862 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1866 /* Returns client authentication information from configuration file by host
1869 SilcServerConfigClient *
1870 silc_server_config_find_client(SilcServer server, char *host)
1872 SilcServerConfig config = server->config;
1873 SilcServerConfigClient *client;
1875 if (!config || !host)
1878 for (client = config->clients; client; client = client->next) {
1879 if (client->host && !silc_string_compare(client->host, host))
1884 /* if none matched, then client is already NULL */
1888 /* Returns admin connection configuration by host, username and/or
1891 SilcServerConfigAdmin *
1892 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1895 SilcServerConfig config = server->config;
1896 SilcServerConfigAdmin *admin;
1898 /* make sure we have a value for the matching parameters */
1906 for (admin = config->admins; admin; admin = admin->next) {
1907 if (admin->host && !silc_string_compare(admin->host, host))
1909 if (admin->user && !silc_string_compare(admin->user, user))
1911 if (admin->nick && !silc_string_compare(admin->nick, nick))
1913 /* no checks failed -> this entry matches */
1917 /* if none matched, then admin is already NULL */
1921 /* Returns the denied connection configuration entry by host. */
1923 SilcServerConfigDeny *
1924 silc_server_config_find_denied(SilcServer server, char *host)
1926 SilcServerConfig config = server->config;
1927 SilcServerConfigDeny *deny;
1929 /* make sure we have a value for the matching parameters */
1930 if (!config || !host)
1933 for (deny = config->denied; deny; deny = deny->next) {
1934 if (deny->host && !silc_string_compare(deny->host, host))
1939 /* if none matched, then deny is already NULL */
1943 /* Returns server connection info from server configuartion by host
1946 SilcServerConfigServer *
1947 silc_server_config_find_server_conn(SilcServer server, char *host)
1949 SilcServerConfig config = server->config;
1950 SilcServerConfigServer *serv = NULL;
1955 if (!config->servers)
1958 for (serv = config->servers; serv; serv = serv->next) {
1959 if (!silc_string_compare(serv->host, host))
1967 /* Returns router connection info from server configuration by
1968 host (name or ip). */
1970 SilcServerConfigRouter *
1971 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1973 SilcServerConfig config = server->config;
1974 SilcServerConfigRouter *serv = NULL;
1979 if (!config->routers)
1982 for (serv = config->routers; serv; serv = serv->next) {
1983 if (!silc_string_compare(serv->host, host))
1985 if (port && serv->port && serv->port != port)
1993 /* Find backup router connection by host (name or ip) */
1995 SilcServerConfigRouter *
1996 silc_server_config_find_backup_conn(SilcServer server, char *host)
1998 SilcServerConfig config = server->config;
1999 SilcServerConfigRouter *serv = NULL;
2004 if (!config->routers)
2007 for (serv = config->routers; serv; serv = serv->next) {
2008 if (!serv->backup_router)
2010 if (!silc_string_compare(serv->host, host))
2018 /* Returns TRUE if configuration for a router connection that we are
2019 initiating exists. */
2021 SilcBool silc_server_config_is_primary_route(SilcServer server)
2023 SilcServerConfig config = server->config;
2024 SilcServerConfigRouter *serv = NULL;
2026 SilcBool found = FALSE;
2028 serv = config->routers;
2029 for (i = 0; serv; i++) {
2030 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2041 /* Returns our primary connection configuration or NULL if we do not
2042 have primary router configured. */
2044 SilcServerConfigRouter *
2045 silc_server_config_get_primary_router(SilcServer server)
2047 SilcServerConfig config = server->config;
2048 SilcServerConfigRouter *serv = NULL;
2051 serv = config->routers;
2052 for (i = 0; serv; i++) {
2053 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2061 /* If we have backup router configured that is going to replace us this
2062 function returns it. */
2064 SilcServerConfigRouter *
2065 silc_server_config_get_backup_router(SilcServer server)
2067 SilcServerConfig config = server->config;
2068 SilcServerConfigRouter *serv = NULL;
2071 if (server->server_type != SILC_ROUTER)
2074 serv = config->routers;
2075 for (i = 0; serv; i++) {
2076 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2077 serv->backup_local == TRUE &&
2078 !strcmp(server->config->server_info->primary->server_ip,
2079 serv->backup_replace_ip) &&
2080 server->config->server_info->primary->port ==
2081 serv->backup_replace_port)