5 Author: Giovanni Giacobbi <giovanni@giacobbi.net>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "serverincludes.h"
23 #include "server_internal.h"
27 #define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
29 #define SERVER_CONFIG_DEBUG(fmt)
32 /* auto-declare needed variables for the common list parsing */
33 #define SILC_SERVER_CONFIG_SECTION_INIT(__type__) \
34 SilcServerConfig config = (SilcServerConfig) context; \
35 __type__ *findtmp, *tmp = (__type__ *) config->tmp; \
38 /* allocate the tmp field for fetching data */
39 #define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
41 config->tmp = silc_calloc(1, sizeof(*findtmp)); \
42 tmp = (__type__ *) config->tmp; \
45 /* append the tmp field to the specified list */
46 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
50 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
51 findtmp->next = tmp; \
54 /* loops all elements in a list and provides a di struct pointer of the
55 * specified type containing the current element */
56 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
57 for (tmp = (void *) __list__; tmp;) { \
58 __type__ *di = (__type__ *) tmp; \
59 tmp = (void *) di->next;
61 /* Set EDOUBLE error value and bail out if necessary */
62 #define CONFIG_IS_DOUBLE(__x__) \
64 got_errno = SILC_CONFIG_EDOUBLE; \
68 /* Free the authentication fields in the specified struct
69 * Expands to two instructions */
70 #define CONFIG_FREE_AUTH(__section__) \
71 silc_free(__section__->passphrase); \
72 if (__section__->publickeys) \
73 silc_hash_table_free(__section__->publickeys);
75 static void my_free_public_key(void *key, void *context, void *user_data)
77 silc_pkcs_public_key_free(context);
80 /* Set default values to those parameters that have not been defined */
82 my_set_param_defaults(SilcServerConfigConnParams *params,
83 SilcServerConfigConnParams *defaults)
85 #define SET_PARAM_DEFAULT(p, d) params->p = \
86 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
88 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
89 SET_PARAM_DEFAULT(connections_max_per_host,
90 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
91 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
92 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
93 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
94 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
95 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
96 SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
97 SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
98 SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
99 SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
101 #undef SET_PARAM_DEFAULT
104 /* Find connection parameters by the parameter block name. */
105 static SilcServerConfigConnParams *
106 my_find_param(SilcServerConfig config, const char *name)
108 SilcServerConfigConnParams *param;
110 for (param = config->conn_params; param; param = param->next) {
111 if (!strcasecmp(param->name, name))
115 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
116 "Cannot find Params \"%s\".", name));
121 /* parse an authdata according to its auth method */
122 static bool my_parse_authdata(SilcAuthMethod auth_meth, const char *p,
123 void **auth_data, SilcUInt32 *auth_data_len)
125 if (auth_meth == SILC_AUTH_PASSWORD) {
126 /* p is a plain text password */
127 if (auth_data && auth_data_len) {
128 if (!silc_utf8_valid(p, strlen(p))) {
129 *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
130 SILC_STRING_LANGUAGE);
131 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
132 silc_utf8_encode(p, strlen(p), SILC_STRING_LANGUAGE, *auth_data,
135 *auth_data = (void *) strdup(p);
136 *auth_data_len = (SilcUInt32) strlen(p);
139 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
140 /* p is a public key file name */
141 SilcPublicKey public_key;
142 SilcPublicKey cached_key;
144 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
145 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
146 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
147 "Could not load public key file!"));
152 silc_hash_table_find_ext(*auth_data, public_key, (void **)&cached_key,
153 NULL, silc_hash_public_key, NULL,
154 silc_hash_public_key_compare, NULL)) {
155 silc_pkcs_public_key_free(public_key);
156 SILC_SERVER_LOG_WARNING(("Warning: public key file \"%s\" already "
157 "configured, ignoring this key", p));
158 return TRUE; /* non fatal error */
161 /* The auth_data is a pointer to the hash table of public keys. */
163 if (*auth_data == NULL)
164 *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL,
166 my_free_public_key, NULL,
168 silc_hash_table_add(*auth_data, public_key, public_key);
176 static bool my_parse_publickeydir(const char *dirname, void **auth_data)
179 struct dirent *get_file;
182 if (!(dp = opendir(dirname))) {
183 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
184 "Could not open directory \"%s\"", dirname));
188 /* errors are not considered fatal */
189 while ((get_file = readdir(dp))) {
190 const char *filename = get_file->d_name;
192 int dirname_len = strlen(dirname), filename_len = strlen(filename);
193 struct stat check_file;
195 /* Ignore "." and "..", and take files only with ".pub" suffix. */
196 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
197 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
200 memset(buf, 0, sizeof(buf));
201 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
202 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
204 if (stat(buf, &check_file) < 0) {
205 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
207 } else if (S_ISREG(check_file.st_mode)) {
208 my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL);
213 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
219 SILC_CONFIG_CALLBACK(fetch_generic)
221 SilcServerConfig config = (SilcServerConfig) context;
224 if (!strcmp(name, "module_path")) {
225 CONFIG_IS_DOUBLE(config->module_path);
226 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
228 else if (!strcmp(name, "prefer_passphrase_auth")) {
229 config->prefer_passphrase_auth = *(bool *)val;
231 else if (!strcmp(name, "require_reverse_lookup")) {
232 config->require_reverse_lookup = *(bool *)val;
234 else if (!strcmp(name, "connections_max")) {
235 config->param.connections_max = (SilcUInt32) *(int *)val;
237 else if (!strcmp(name, "connections_max_per_host")) {
238 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
240 else if (!strcmp(name, "keepalive_secs")) {
241 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
243 else if (!strcmp(name, "reconnect_count")) {
244 config->param.reconnect_count = (SilcUInt32) *(int *)val;
246 else if (!strcmp(name, "reconnect_interval")) {
247 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
249 else if (!strcmp(name, "reconnect_interval_max")) {
250 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
252 else if (!strcmp(name, "reconnect_keep_trying")) {
253 config->param.reconnect_keep_trying = *(bool *)val;
255 else if (!strcmp(name, "key_exchange_rekey")) {
256 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
258 else if (!strcmp(name, "key_exchange_pfs")) {
259 config->param.key_exchange_pfs = *(bool *)val;
261 else if (!strcmp(name, "channel_rekey_secs")) {
262 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
264 else if (!strcmp(name, "key_exchange_timeout")) {
265 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
267 else if (!strcmp(name, "conn_auth_timeout")) {
268 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
270 else if (!strcmp(name, "version_protocol")) {
271 CONFIG_IS_DOUBLE(config->param.version_protocol);
272 config->param.version_protocol =
273 (*(char *)val ? strdup((char *) val) : NULL);
275 else if (!strcmp(name, "version_software")) {
276 CONFIG_IS_DOUBLE(config->param.version_software);
277 config->param.version_software =
278 (*(char *)val ? strdup((char *) val) : NULL);
280 else if (!strcmp(name, "version_software_vendor")) {
281 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
282 config->param.version_software_vendor =
283 (*(char *)val ? strdup((char *) val) : NULL);
285 else if (!strcmp(name, "detach_disabled")) {
286 config->detach_disabled = *(bool *)val;
288 else if (!strcmp(name, "detach_timeout")) {
289 config->detach_timeout = (SilcUInt32) *(int *)val;
291 else if (!strcmp(name, "qos")) {
292 config->param.qos = *(bool *)val;
294 else if (!strcmp(name, "qos_rate_limit")) {
295 config->param.qos_rate_limit = *(SilcUInt32 *)val;
297 else if (!strcmp(name, "qos_bytes_limit")) {
298 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
300 else if (!strcmp(name, "qos_limit_sec")) {
301 config->param.qos_limit_sec = *(SilcUInt32 *)val;
303 else if (!strcmp(name, "qos_limit_usec")) {
304 config->param.qos_limit_usec = *(SilcUInt32 *)val;
306 else if (!strcmp(name, "debug_string")) {
307 CONFIG_IS_DOUBLE(config->debug_string);
308 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
311 return SILC_CONFIG_EINTERNAL;
313 return SILC_CONFIG_OK;
319 SILC_CONFIG_CALLBACK(fetch_cipher)
321 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
323 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
324 type, name, context));
325 if (type == SILC_CONFIG_ARG_BLOCK) {
326 /* check the temporary struct's fields */
327 if (!tmp) /* discard empty sub-blocks */
328 return SILC_CONFIG_OK;
330 got_errno = SILC_CONFIG_EMISSFIELDS;
334 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
336 return SILC_CONFIG_OK;
338 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
340 /* Identify and save this value */
341 if (!strcmp(name, "name")) {
342 CONFIG_IS_DOUBLE(tmp->name);
343 tmp->name = strdup((char *) val);
345 else if (!strcmp(name, "module")) {
346 CONFIG_IS_DOUBLE(tmp->module);
347 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
349 else if (!strcmp(name, "keylength")) {
350 tmp->key_length = *(SilcUInt32 *)val;
352 else if (!strcmp(name, "blocklength")) {
353 tmp->block_length = *(SilcUInt32 *)val;
356 return SILC_CONFIG_EINTERNAL;
357 return SILC_CONFIG_OK;
360 silc_free(tmp->name);
361 silc_free(tmp->module);
367 SILC_CONFIG_CALLBACK(fetch_hash)
369 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
371 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
372 type, name, context));
373 if (type == SILC_CONFIG_ARG_BLOCK) {
374 /* check the temporary struct's fields */
375 if (!tmp) /* discard empty sub-blocks */
376 return SILC_CONFIG_OK;
377 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
378 got_errno = SILC_CONFIG_EMISSFIELDS;
382 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
384 return SILC_CONFIG_OK;
386 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
388 /* Identify and save this value */
389 if (!strcmp(name, "name")) {
390 CONFIG_IS_DOUBLE(tmp->name);
391 tmp->name = strdup((char *) val);
393 else if (!strcmp(name, "module")) {
394 CONFIG_IS_DOUBLE(tmp->module);
395 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
397 else if (!strcmp(name, "blocklength")) {
398 tmp->block_length = *(int *)val;
400 else if (!strcmp(name, "digestlength")) {
401 tmp->digest_length = *(int *)val;
404 return SILC_CONFIG_EINTERNAL;
405 return SILC_CONFIG_OK;
408 silc_free(tmp->name);
409 silc_free(tmp->module);
415 SILC_CONFIG_CALLBACK(fetch_hmac)
417 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
419 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
420 type, name, context));
421 if (type == SILC_CONFIG_ARG_BLOCK) {
422 /* check the temporary struct's fields */
423 if (!tmp) /* discard empty sub-blocks */
424 return SILC_CONFIG_OK;
425 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
426 got_errno = SILC_CONFIG_EMISSFIELDS;
430 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
432 return SILC_CONFIG_OK;
434 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
436 /* Identify and save this value */
437 if (!strcmp(name, "name")) {
438 CONFIG_IS_DOUBLE(tmp->name);
439 tmp->name = strdup((char *) val);
441 else if (!strcmp(name, "hash")) {
442 CONFIG_IS_DOUBLE(tmp->hash);
443 tmp->hash = strdup((char *) val);
445 else if (!strcmp(name, "maclength")) {
446 tmp->mac_length = *(int *)val;
449 return SILC_CONFIG_EINTERNAL;
450 return SILC_CONFIG_OK;
453 silc_free(tmp->name);
454 silc_free(tmp->hash);
460 SILC_CONFIG_CALLBACK(fetch_pkcs)
462 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
464 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
465 type, name, context));
466 if (type == SILC_CONFIG_ARG_BLOCK) {
467 /* Check the temporary struct's fields */
468 if (!tmp) /* discard empty sub-blocks */
469 return SILC_CONFIG_OK;
471 got_errno = SILC_CONFIG_EMISSFIELDS;
475 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
477 return SILC_CONFIG_OK;
479 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
481 /* Identify and save this value */
482 if (!strcmp(name, "name")) {
483 CONFIG_IS_DOUBLE(tmp->name);
484 tmp->name = strdup((char *) val);
487 return SILC_CONFIG_EINTERNAL;
488 return SILC_CONFIG_OK;
491 silc_free(tmp->name);
497 SILC_CONFIG_CALLBACK(fetch_serverinfo)
499 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
500 SilcServerConfigServerInfo *server_info = config->server_info;
502 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
503 type, name, context));
505 /* If there isn't the main struct alloc it */
507 config->server_info = server_info = (SilcServerConfigServerInfo *)
508 silc_calloc(1, sizeof(*server_info));
510 if (type == SILC_CONFIG_ARG_BLOCK) {
511 if (!strcmp(name, "primary")) {
512 if (server_info->primary) {
513 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
514 "Double primary specification."));
515 got_errno = SILC_CONFIG_EPRINTLINE;
518 CONFIG_IS_DOUBLE(server_info->primary);
520 /* now check the temporary struct, don't accept empty block and
521 make sure all fields are there */
522 if (!tmp || !tmp->server_ip || !tmp->port) {
523 got_errno = SILC_CONFIG_EMISSFIELDS;
526 server_info->primary = tmp;
528 return SILC_CONFIG_OK;
529 } else if (!strcmp(name, "secondary")) {
531 return SILC_CONFIG_OK;
532 if (!tmp || !tmp->server_ip || !tmp->port) {
533 got_errno = SILC_CONFIG_EMISSFIELDS;
536 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
538 return SILC_CONFIG_OK;
539 } else if (!server_info->public_key || !server_info->private_key) {
540 got_errno = SILC_CONFIG_EMISSFIELDS;
543 return SILC_CONFIG_OK;
545 if (!strcmp(name, "hostname")) {
546 CONFIG_IS_DOUBLE(server_info->server_name);
547 server_info->server_name = strdup((char *) val);
549 else if (!strcmp(name, "ip")) {
550 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
551 CONFIG_IS_DOUBLE(tmp->server_ip);
552 tmp->server_ip = strdup((char *) val);
554 else if (!strcmp(name, "port")) {
555 int port = *(int *)val;
556 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
557 if ((port <= 0) || (port > 65535)) {
558 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
559 "Invalid port number!"));
560 got_errno = SILC_CONFIG_EPRINTLINE;
563 tmp->port = (SilcUInt16) port;
565 else if (!strcmp(name, "servertype")) {
566 CONFIG_IS_DOUBLE(server_info->server_type);
567 server_info->server_type = strdup((char *) val);
569 else if (!strcmp(name, "admin")) {
570 CONFIG_IS_DOUBLE(server_info->admin);
571 server_info->admin = strdup((char *) val);
573 else if (!strcmp(name, "adminemail")) {
574 CONFIG_IS_DOUBLE(server_info->email);
575 server_info->email = strdup((char *) val);
577 else if (!strcmp(name, "location")) {
578 CONFIG_IS_DOUBLE(server_info->location);
579 server_info->location = strdup((char *) val);
581 else if (!strcmp(name, "user")) {
582 CONFIG_IS_DOUBLE(server_info->user);
583 server_info->user = strdup((char *) val);
585 else if (!strcmp(name, "group")) {
586 CONFIG_IS_DOUBLE(server_info->group);
587 server_info->group = strdup((char *) val);
589 else if (!strcmp(name, "motdfile")) {
590 CONFIG_IS_DOUBLE(server_info->motd_file);
591 server_info->motd_file = strdup((char *) val);
593 else if (!strcmp(name, "pidfile")) {
594 CONFIG_IS_DOUBLE(server_info->pid_file);
595 server_info->pid_file = strdup((char *) val);
597 else if (!strcmp(name, "publickey")) {
598 char *file_tmp = (char *) val;
599 CONFIG_IS_DOUBLE(server_info->public_key);
601 /* Try to load specified file, if fail stop config parsing */
602 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
604 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
605 SILC_PKCS_FILE_BIN)) {
606 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
607 return SILC_CONFIG_EPRINTLINE;
610 else if (!strcmp(name, "privatekey")) {
612 char *file_tmp = (char *) val;
613 CONFIG_IS_DOUBLE(server_info->private_key);
615 /* Check the private key file permissions. */
616 if ((stat(file_tmp, &st)) != -1) {
617 if ((st.st_mode & 0777) != 0600) {
618 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
619 "file \"%s\". The permissions must be "
621 return SILC_CONFIG_ESILENT;
625 /* Try to load specified file, if fail stop config parsing */
626 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
627 "", 0, SILC_PKCS_FILE_BIN))
628 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
629 "", 0, SILC_PKCS_FILE_PEM)) {
630 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
631 return SILC_CONFIG_EPRINTLINE;
635 return SILC_CONFIG_EINTERNAL;
636 return SILC_CONFIG_OK;
639 /* Here we need to check if tmp exists because this function handles
640 * misc data (multiple fields and single-only fields) */
642 silc_free(tmp->server_ip);
649 SILC_CONFIG_CALLBACK(fetch_logging)
651 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
653 if (!strcmp(name, "timestamp")) {
654 config->logging_timestamp = *(bool *)val;
656 else if (!strcmp(name, "quicklogs")) {
657 config->logging_quick = *(bool *)val;
659 else if (!strcmp(name, "flushdelay")) {
660 int flushdelay = *(int *)val;
661 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
662 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
663 "Invalid flushdelay value, use quicklogs if you "
664 "want real-time logging."));
665 return SILC_CONFIG_EPRINTLINE;
667 config->logging_flushdelay = (long) flushdelay;
670 /* The following istances happens only in Logging's sub-blocks, a match
671 for the sub-block name means that you should store the filename/maxsize
672 temporary struct to the proper logging channel.
673 If we get a match for "file" or "maxsize" this means that we are inside
674 a sub-sub-block and it is safe to alloc a new tmp. */
675 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
676 else if (!strcmp(name, __chan__)) { \
677 if (!tmp) return SILC_CONFIG_OK; \
679 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
681 config->__member__ = tmp; \
682 config->tmp = NULL; \
684 FETCH_LOGGING_CHAN("info", logging_info)
685 FETCH_LOGGING_CHAN("warnings", logging_warnings)
686 FETCH_LOGGING_CHAN("errors", logging_errors)
687 FETCH_LOGGING_CHAN("fatals", logging_fatals)
688 #undef FETCH_LOGGING_CHAN
689 else if (!strcmp(name, "file")) {
690 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
691 CONFIG_IS_DOUBLE(tmp->file);
692 tmp->file = strdup((char *) val);
694 else if (!strcmp(name, "size")) {
696 config->tmp = silc_calloc(1, sizeof(*tmp));
697 tmp = (SilcServerConfigLogging *) config->tmp;
699 tmp->maxsize = *(SilcUInt32 *) val;
702 return SILC_CONFIG_EINTERNAL;
703 return SILC_CONFIG_OK;
706 silc_free(tmp->file);
712 SILC_CONFIG_CALLBACK(fetch_connparam)
714 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
716 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
717 type, name, context));
718 if (type == SILC_CONFIG_ARG_BLOCK) {
719 /* check the temporary struct's fields */
720 if (!tmp) /* discard empty sub-blocks */
721 return SILC_CONFIG_OK;
723 got_errno = SILC_CONFIG_EMISSFIELDS;
727 my_set_param_defaults(tmp, &config->param);
729 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
731 return SILC_CONFIG_OK;
733 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
735 if (!strcmp(name, "name")) {
736 CONFIG_IS_DOUBLE(tmp->name);
737 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
739 else if (!strcmp(name, "connections_max")) {
740 tmp->connections_max = *(SilcUInt32 *)val;
742 else if (!strcmp(name, "connections_max_per_host")) {
743 tmp->connections_max_per_host = *(SilcUInt32 *)val;
745 else if (!strcmp(name, "keepalive_secs")) {
746 tmp->keepalive_secs = *(SilcUInt32 *)val;
748 else if (!strcmp(name, "reconnect_count")) {
749 tmp->reconnect_count = *(SilcUInt32 *)val;
751 else if (!strcmp(name, "reconnect_interval")) {
752 tmp->reconnect_interval = *(SilcUInt32 *)val;
754 else if (!strcmp(name, "reconnect_interval_max")) {
755 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
757 else if (!strcmp(name, "reconnect_keep_trying")) {
758 tmp->reconnect_keep_trying = *(bool *)val;
760 else if (!strcmp(name, "key_exchange_rekey")) {
761 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
763 else if (!strcmp(name, "key_exchange_pfs")) {
764 tmp->key_exchange_pfs = *(bool *)val;
766 else if (!strcmp(name, "version_protocol")) {
767 CONFIG_IS_DOUBLE(tmp->version_protocol);
768 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
770 else if (!strcmp(name, "version_software")) {
771 CONFIG_IS_DOUBLE(tmp->version_software);
772 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
774 else if (!strcmp(name, "version_software_vendor")) {
775 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
776 tmp->version_software_vendor =
777 (*(char *)val ? strdup((char *) val) : NULL);
779 else if (!strcmp(name, "anonymous")) {
780 tmp->anonymous = *(bool *)val;
782 else if (!strcmp(name, "qos")) {
783 tmp->qos = *(bool *)val;
785 else if (!strcmp(name, "qos_rate_limit")) {
786 tmp->qos_rate_limit = *(SilcUInt32 *)val;
788 else if (!strcmp(name, "qos_bytes_limit")) {
789 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
791 else if (!strcmp(name, "qos_limit_sec")) {
792 tmp->qos_limit_sec = *(SilcUInt32 *)val;
794 else if (!strcmp(name, "qos_limit_usec")) {
795 tmp->qos_limit_usec = *(SilcUInt32 *)val;
798 return SILC_CONFIG_EINTERNAL;
800 return SILC_CONFIG_OK;
803 silc_free(tmp->name);
809 SILC_CONFIG_CALLBACK(fetch_client)
811 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
813 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
814 type, name, context));
816 /* Alloc before block checking, because empty sub-blocks are welcome here */
817 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
819 if (type == SILC_CONFIG_ARG_BLOCK) {
820 /* empty sub-blocks are welcome */
821 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
823 return SILC_CONFIG_OK;
826 /* Identify and save this value */
827 if (!strcmp(name, "host")) {
828 CONFIG_IS_DOUBLE(tmp->host);
829 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
831 else if (!strcmp(name, "passphrase")) {
832 CONFIG_IS_DOUBLE(tmp->passphrase);
833 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
834 (void **)&tmp->passphrase,
835 &tmp->passphrase_len)) {
836 got_errno = SILC_CONFIG_EPRINTLINE;
840 else if (!strcmp(name, "publickey")) {
841 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
842 (void **)&tmp->publickeys, NULL)) {
843 got_errno = SILC_CONFIG_EPRINTLINE;
847 else if (!strcmp(name, "publickeydir")) {
848 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
849 got_errno = SILC_CONFIG_EPRINTLINE;
853 else if (!strcmp(name, "params")) {
854 CONFIG_IS_DOUBLE(tmp->param);
855 tmp->param = my_find_param(config, (char *) val);
856 if (!tmp->param) { /* error message already output */
857 got_errno = SILC_CONFIG_EPRINTLINE;
862 return SILC_CONFIG_EINTERNAL;
863 return SILC_CONFIG_OK;
866 silc_free(tmp->host);
867 CONFIG_FREE_AUTH(tmp);
873 SILC_CONFIG_CALLBACK(fetch_admin)
875 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
877 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
878 type, name, context));
879 if (type == SILC_CONFIG_ARG_BLOCK) {
880 /* check the temporary struct's fields */
881 if (!tmp) /* discard empty sub-blocks */
882 return SILC_CONFIG_OK;
884 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
886 return SILC_CONFIG_OK;
888 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
890 /* Identify and save this value */
891 if (!strcmp(name, "host")) {
892 CONFIG_IS_DOUBLE(tmp->host);
893 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
895 else if (!strcmp(name, "user")) {
896 CONFIG_IS_DOUBLE(tmp->user);
897 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
899 else if (!strcmp(name, "nick")) {
900 CONFIG_IS_DOUBLE(tmp->nick);
901 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
903 else if (!strcmp(name, "passphrase")) {
904 CONFIG_IS_DOUBLE(tmp->passphrase);
905 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
906 (void **)&tmp->passphrase,
907 &tmp->passphrase_len)) {
908 got_errno = SILC_CONFIG_EPRINTLINE;
912 else if (!strcmp(name, "publickey")) {
913 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
914 (void **)&tmp->publickeys, NULL)) {
915 got_errno = SILC_CONFIG_EPRINTLINE;
919 else if (!strcmp(name, "publickeydir")) {
920 if (!my_parse_publickeydir((char *) val, (void **)&tmp->publickeys)) {
921 got_errno = SILC_CONFIG_EPRINTLINE;
926 return SILC_CONFIG_EINTERNAL;
927 return SILC_CONFIG_OK;
930 silc_free(tmp->host);
931 silc_free(tmp->user);
932 silc_free(tmp->nick);
933 CONFIG_FREE_AUTH(tmp);
939 SILC_CONFIG_CALLBACK(fetch_deny)
941 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
943 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
944 type, name, context));
945 if (type == SILC_CONFIG_ARG_BLOCK) {
946 /* check the temporary struct's fields */
947 if (!tmp) /* discard empty sub-blocks */
948 return SILC_CONFIG_OK;
950 got_errno = SILC_CONFIG_EMISSFIELDS;
954 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
956 return SILC_CONFIG_OK;
958 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
960 /* Identify and save this value */
961 if (!strcmp(name, "host")) {
962 CONFIG_IS_DOUBLE(tmp->host);
963 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
965 else if (!strcmp(name, "reason")) {
966 CONFIG_IS_DOUBLE(tmp->reason);
967 tmp->reason = strdup((char *) val);
970 return SILC_CONFIG_EINTERNAL;
971 return SILC_CONFIG_OK;
974 silc_free(tmp->host);
975 silc_free(tmp->reason);
981 SILC_CONFIG_CALLBACK(fetch_server)
983 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
985 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
986 type, name, context));
987 if (type == SILC_CONFIG_ARG_BLOCK) {
988 /* check the temporary struct's fields */
989 if (!tmp) /* discard empty sub-blocks */
990 return SILC_CONFIG_OK;
992 got_errno = SILC_CONFIG_EMISSFIELDS;
996 /* the temporary struct is ok, append it to the list */
997 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
999 return SILC_CONFIG_OK;
1001 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1003 /* Identify and save this value */
1004 if (!strcmp(name, "host")) {
1005 CONFIG_IS_DOUBLE(tmp->host);
1006 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1008 else if (!strcmp(name, "passphrase")) {
1009 CONFIG_IS_DOUBLE(tmp->passphrase);
1010 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1011 (void **)&tmp->passphrase,
1012 &tmp->passphrase_len)) {
1013 got_errno = SILC_CONFIG_EPRINTLINE;
1017 else if (!strcmp(name, "publickey")) {
1018 CONFIG_IS_DOUBLE(tmp->publickeys);
1019 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1020 (void **)&tmp->publickeys, NULL)) {
1021 got_errno = SILC_CONFIG_EPRINTLINE;
1025 else if (!strcmp(name, "params")) {
1026 CONFIG_IS_DOUBLE(tmp->param);
1027 tmp->param = my_find_param(config, (char *) val);
1028 if (!tmp->param) { /* error message already output */
1029 got_errno = SILC_CONFIG_EPRINTLINE;
1033 else if (!strcmp(name, "backup")) {
1034 tmp->backup_router = *(bool *)val;
1037 return SILC_CONFIG_EINTERNAL;
1039 return SILC_CONFIG_OK;
1042 silc_free(tmp->host);
1043 CONFIG_FREE_AUTH(tmp);
1049 SILC_CONFIG_CALLBACK(fetch_router)
1051 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1053 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1054 type, name, context));
1055 if (type == SILC_CONFIG_ARG_BLOCK) {
1056 if (!tmp) /* discard empty sub-blocks */
1057 return SILC_CONFIG_OK;
1059 got_errno = SILC_CONFIG_EMISSFIELDS;
1063 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1065 return SILC_CONFIG_OK;
1067 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1069 /* Identify and save this value */
1070 if (!strcmp(name, "host")) {
1071 CONFIG_IS_DOUBLE(tmp->host);
1072 tmp->host = strdup((char *) val);
1074 else if (!strcmp(name, "port")) {
1075 int port = *(int *)val;
1076 if ((port <= 0) || (port > 65535)) {
1077 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1078 "Invalid port number!"));
1079 got_errno = SILC_CONFIG_EPRINTLINE;
1082 tmp->port = (SilcUInt16) port;
1084 else if (!strcmp(name, "passphrase")) {
1085 CONFIG_IS_DOUBLE(tmp->passphrase);
1086 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1087 (void **)&tmp->passphrase,
1088 &tmp->passphrase_len)) {
1089 got_errno = SILC_CONFIG_EPRINTLINE;
1093 else if (!strcmp(name, "publickey")) {
1094 CONFIG_IS_DOUBLE(tmp->publickeys);
1095 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1096 (void **)&tmp->publickeys, NULL)) {
1097 got_errno = SILC_CONFIG_EPRINTLINE;
1101 else if (!strcmp(name, "params")) {
1102 CONFIG_IS_DOUBLE(tmp->param);
1103 tmp->param = my_find_param(config, (char *) val);
1104 if (!tmp->param) { /* error message already output */
1105 got_errno = SILC_CONFIG_EPRINTLINE;
1109 else if (!strcmp(name, "initiator")) {
1110 tmp->initiator = *(bool *)val;
1112 else if (!strcmp(name, "backuphost")) {
1113 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1114 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1116 tmp->backup_router = TRUE;
1118 else if (!strcmp(name, "backupport")) {
1119 int port = *(int *)val;
1120 if ((port <= 0) || (port > 65535)) {
1121 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1122 "Invalid port number!"));
1123 got_errno = SILC_CONFIG_EPRINTLINE;
1126 tmp->backup_replace_port = (SilcUInt16) port;
1128 else if (!strcmp(name, "backuplocal")) {
1129 tmp->backup_local = *(bool *)val;
1132 return SILC_CONFIG_EINTERNAL;
1134 return SILC_CONFIG_OK;
1137 silc_free(tmp->host);
1138 silc_free(tmp->backup_replace_ip);
1139 CONFIG_FREE_AUTH(tmp);
1145 /* known config options tables */
1146 static const SilcConfigTable table_general[] = {
1147 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1148 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1149 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1150 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1151 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1152 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1153 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1154 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1155 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1156 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1157 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1158 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1159 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1160 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1161 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1162 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1163 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1164 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1165 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1166 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1167 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1168 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1169 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1170 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1171 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1172 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1176 static const SilcConfigTable table_cipher[] = {
1177 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1178 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1179 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1180 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1184 static const SilcConfigTable table_hash[] = {
1185 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1186 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1187 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1188 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1192 static const SilcConfigTable table_hmac[] = {
1193 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1194 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1195 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1199 static const SilcConfigTable table_pkcs[] = {
1200 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1204 static const SilcConfigTable table_serverinfo_c[] = {
1205 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1206 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1210 static const SilcConfigTable table_serverinfo[] = {
1211 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1212 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1213 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1214 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1215 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1216 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1217 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1218 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1219 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1220 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1221 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1222 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1223 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1227 static const SilcConfigTable table_logging_c[] = {
1228 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1229 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1230 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1234 static const SilcConfigTable table_logging[] = {
1235 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1236 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1237 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1238 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1239 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1240 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1241 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1245 static const SilcConfigTable table_connparam[] = {
1246 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1247 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1248 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1249 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1250 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1251 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1252 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1253 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1254 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1255 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1256 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1257 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1258 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1259 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1260 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1261 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1262 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1263 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1264 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1265 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1269 static const SilcConfigTable table_client[] = {
1270 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1271 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1272 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1273 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1274 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1278 static const SilcConfigTable table_admin[] = {
1279 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1280 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1281 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1282 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1283 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1284 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1285 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1286 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1290 static const SilcConfigTable table_deny[] = {
1291 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1292 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1296 static const SilcConfigTable table_serverconn[] = {
1297 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1298 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1299 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1300 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1301 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1305 static const SilcConfigTable table_routerconn[] = {
1306 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1307 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1308 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1309 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1310 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1311 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1312 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1313 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1314 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1318 static const SilcConfigTable table_main[] = {
1319 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1320 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1321 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1322 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1323 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1324 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1325 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1326 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1327 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1328 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1329 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1330 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1331 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1335 /* Set default values to stuff that was not configured. */
1337 static void silc_server_config_set_defaults(SilcServerConfig config)
1339 my_set_param_defaults(&config->param, NULL);
1341 config->channel_rekey_secs = (config->channel_rekey_secs ?
1342 config->channel_rekey_secs :
1343 SILC_SERVER_CHANNEL_REKEY);
1344 config->key_exchange_timeout = (config->key_exchange_timeout ?
1345 config->key_exchange_timeout :
1346 SILC_SERVER_SKE_TIMEOUT);
1347 config->conn_auth_timeout = (config->conn_auth_timeout ?
1348 config->conn_auth_timeout :
1349 SILC_SERVER_CONNAUTH_TIMEOUT);
1352 /* Check for correctness of the configuration */
1354 static bool silc_server_config_check(SilcServerConfig config)
1357 SilcServerConfigServer *s;
1358 SilcServerConfigRouter *r;
1361 /* ServerConfig is mandatory */
1362 if (!config->server_info) {
1363 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1367 /* RouterConnection sanity checks */
1369 if (config->routers && config->routers->backup_router == TRUE &&
1371 SILC_SERVER_LOG_ERROR((
1372 "\nError: First RouterConnection block must be primary router "
1373 "connection. You have marked it incorrectly as backup router."));
1376 if (config->routers && config->routers->initiator == FALSE &&
1377 config->routers->backup_router == FALSE) {
1378 SILC_SERVER_LOG_ERROR((
1379 "\nError: First RouterConnection block must be primary router "
1380 "connection and it must be marked as Initiator."));
1383 if (config->routers && config->routers->backup_router == TRUE &&
1384 !config->servers && !config->routers->next) {
1385 SILC_SERVER_LOG_ERROR((
1386 "\nError: You have configured backup router but not primary router. "
1387 "If backup router is configured also primary router must be "
1392 /* Backup router sanity checks */
1394 for (r = config->routers; r; r = r->next) {
1395 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1396 SILC_SERVER_LOG_ERROR((
1397 "\nError: Backup router connection incorrectly configured to use "
1398 "primary and backup router as same host `%s'. They must not be "
1399 "same host.", r->host));
1404 /* ServerConnection sanity checks */
1406 for (s = config->servers; s; s = s->next) {
1407 if (s->backup_router) {
1413 for (s = config->servers; s; s = s->next) {
1414 if (!s->backup_router) {
1415 SILC_SERVER_LOG_ERROR((
1416 "\nError: Your server is backup router but not all ServerConnection "
1417 "blocks were marked as backup connections. They all must be "
1418 "marked as backup connections."));
1428 /* Allocates a new configuration object, opens configuration file and
1429 parses it. The parsed data is returned to the newly allocated
1430 configuration object. The SilcServerConfig must be freed by calling
1431 the silc_server_config_destroy function. */
1433 SilcServerConfig silc_server_config_alloc(const char *filename)
1435 SilcServerConfig config_new;
1436 SilcConfigEntity ent;
1437 SilcConfigFile *file;
1439 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1441 /* alloc a config object */
1442 config_new = silc_calloc(1, sizeof(*config_new));
1446 /* general config defaults */
1447 config_new->refcount = 1;
1448 config_new->logging_timestamp = TRUE;
1450 /* obtain a config file object */
1451 file = silc_config_open(filename);
1453 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1458 /* obtain a SilcConfig entity, we can use it to start the parsing */
1459 ent = silc_config_init(file);
1461 /* load the known configuration options, give our empty object as context */
1462 silc_config_register_table(ent, table_main, (void *) config_new);
1464 /* enter the main parsing loop. When this returns, we have the parsing
1465 * result and the object filled (or partially, in case of errors). */
1466 ret = silc_config_main(ent);
1467 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1468 silc_config_strerror(ret)));
1470 /* Check if the parser returned errors */
1472 /* handle this special error return which asks to quietly return */
1473 if (ret != SILC_CONFIG_ESILENT) {
1474 char *linebuf, *filename = silc_config_get_filename(file);
1475 SilcUInt32 line = silc_config_get_line(file);
1476 if (ret != SILC_CONFIG_EPRINTLINE)
1477 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1478 silc_config_strerror(ret)));
1479 linebuf = silc_config_read_line(file, line);
1481 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1486 silc_server_config_destroy(config_new);
1487 silc_config_close(file);
1491 /* close (destroy) the file object */
1492 silc_config_close(file);
1494 /* Check the configuration */
1495 if (!silc_server_config_check(config_new)) {
1496 silc_server_config_destroy(config_new);
1500 /* Set default to configuration parameters */
1501 silc_server_config_set_defaults(config_new);
1506 /* Increments the reference counter of a config object */
1508 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1513 ref->config = config;
1514 ref->ref_ptr = ref_ptr;
1515 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1516 config->refcount - 1, config->refcount));
1520 /* Decrements the reference counter of a config object. If the counter
1521 reaches 0, the config object is destroyed. */
1523 void silc_server_config_unref(SilcServerConfigRef *ref)
1526 silc_server_config_destroy(ref->config);
1529 /* Destroy a config object with all his children lists */
1531 void silc_server_config_destroy(SilcServerConfig config)
1536 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1537 config->refcount + 1, config->refcount));
1538 if (config->refcount > 0)
1541 SILC_LOG_DEBUG(("Freeing config context"));
1543 /* Destroy general config stuff */
1544 silc_free(config->module_path);
1545 silc_free(config->debug_string);
1546 silc_free(config->param.version_protocol);
1547 silc_free(config->param.version_software);
1548 silc_free(config->param.version_software_vendor);
1550 /* Destroy Logging channels */
1551 if (config->logging_info)
1552 silc_free(config->logging_info->file);
1553 if (config->logging_warnings)
1554 silc_free(config->logging_warnings->file);
1555 if (config->logging_errors)
1556 silc_free(config->logging_errors->file);
1557 if (config->logging_fatals)
1558 silc_free(config->logging_fatals->file);
1559 silc_free(config->logging_info);
1560 silc_free(config->logging_warnings);
1561 silc_free(config->logging_errors);
1562 silc_free(config->logging_fatals);
1564 /* Destroy the ServerInfo struct */
1565 if (config->server_info) {
1566 register SilcServerConfigServerInfo *si = config->server_info;
1567 silc_free(si->server_name);
1569 silc_free(si->primary->server_ip);
1570 silc_free(si->primary);
1572 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1574 silc_free(di->server_ip);
1577 silc_free(si->server_type);
1578 silc_free(si->location);
1579 silc_free(si->admin);
1580 silc_free(si->email);
1581 silc_free(si->user);
1582 silc_free(si->group);
1583 silc_free(si->motd_file);
1584 silc_free(si->pid_file);
1585 silc_pkcs_public_key_free(si->public_key);
1586 silc_pkcs_private_key_free(si->private_key);
1590 /* Now let's destroy the lists */
1592 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1594 silc_free(di->name);
1595 silc_free(di->module);
1598 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1599 silc_free(di->name);
1600 silc_free(di->module);
1603 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1604 silc_free(di->name);
1605 silc_free(di->hash);
1608 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1609 silc_free(di->name);
1612 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1613 config->conn_params)
1614 silc_free(di->name);
1615 silc_free(di->version_protocol);
1616 silc_free(di->version_software);
1617 silc_free(di->version_software_vendor);
1620 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1621 silc_free(di->host);
1622 CONFIG_FREE_AUTH(di);
1625 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1626 silc_free(di->host);
1627 silc_free(di->user);
1628 silc_free(di->nick);
1629 CONFIG_FREE_AUTH(di);
1632 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1633 silc_free(di->host);
1634 silc_free(di->reason);
1637 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1639 silc_free(di->host);
1640 CONFIG_FREE_AUTH(di);
1643 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1645 silc_free(di->host);
1646 silc_free(di->backup_replace_ip);
1647 CONFIG_FREE_AUTH(di);
1651 memset(config, 'F', sizeof(*config));
1655 /* Registers configured ciphers. These can then be allocated by the
1656 server when needed. */
1658 bool silc_server_config_register_ciphers(SilcServer server)
1660 SilcServerConfig config = server->config;
1661 SilcServerConfigCipher *cipher = config->cipher;
1662 char *module_path = config->module_path;
1664 SILC_LOG_DEBUG(("Registering configured ciphers"));
1666 if (!cipher) /* any cipher in the config file? */
1670 /* if there isn't a module_path OR there isn't a module sim name try to
1671 * use buil-in functions */
1672 if (!module_path || !cipher->module) {
1674 for (i = 0; silc_default_ciphers[i].name; i++)
1675 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1676 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1679 if (!silc_cipher_is_supported(cipher->name)) {
1680 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1681 silc_server_stop(server);
1686 /* Load (try at least) the crypto SIM module */
1687 char buf[1023], *alg_name;
1688 SilcCipherObject cipher_obj;
1691 memset(&cipher_obj, 0, sizeof(cipher_obj));
1692 cipher_obj.name = cipher->name;
1693 cipher_obj.block_len = cipher->block_length;
1694 cipher_obj.key_len = cipher->key_length * 8;
1696 /* build the libname */
1697 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1699 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1701 alg_name = strdup(cipher->name);
1702 if (strchr(alg_name, '-'))
1703 *strchr(alg_name, '-') = '\0';
1705 if (silc_sim_load(sim)) {
1706 cipher_obj.set_key =
1707 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1708 SILC_CIPHER_SIM_SET_KEY));
1709 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1710 cipher_obj.set_key_with_string =
1711 silc_sim_getsym(sim,
1712 silc_sim_symname(alg_name,
1713 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1714 SILC_LOG_DEBUG(("set_key_with_string=%p",
1715 cipher_obj.set_key_with_string));
1716 cipher_obj.encrypt =
1717 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1718 SILC_CIPHER_SIM_ENCRYPT_CBC));
1719 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1720 cipher_obj.decrypt =
1721 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1722 SILC_CIPHER_SIM_DECRYPT_CBC));
1723 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1724 cipher_obj.context_len =
1725 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1726 SILC_CIPHER_SIM_CONTEXT_LEN));
1727 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1729 /* Put the SIM to the list of all SIM's in server */
1730 silc_dlist_add(server->sim, sim);
1732 silc_free(alg_name);
1734 SILC_LOG_ERROR(("Error configuring ciphers"));
1736 silc_server_stop(server);
1740 /* Register the cipher */
1741 silc_cipher_register(&cipher_obj);
1743 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1744 "can't load modules!"));
1745 silc_server_stop(server);
1749 cipher = cipher->next;
1755 /* Registers configured hash functions. These can then be allocated by the
1756 server when needed. */
1758 bool silc_server_config_register_hashfuncs(SilcServer server)
1760 SilcServerConfig config = server->config;
1761 SilcServerConfigHash *hash = config->hash;
1762 char *module_path = config->module_path;
1764 SILC_LOG_DEBUG(("Registering configured hash functions"));
1766 if (!hash) /* any hash func in the config file? */
1770 /* if there isn't a module_path OR there isn't a module sim name try to
1771 * use buil-in functions */
1772 if (!module_path || !hash->module) {
1774 for (i = 0; silc_default_hash[i].name; i++)
1775 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1776 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1779 if (!silc_hash_is_supported(hash->name)) {
1780 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1781 silc_server_stop(server);
1786 /* Load (try at least) the hash SIM module */
1787 SilcHashObject hash_obj;
1790 memset(&hash_obj, 0, sizeof(hash_obj));
1791 hash_obj.name = hash->name;
1792 hash_obj.block_len = hash->block_length;
1793 hash_obj.hash_len = hash->digest_length;
1795 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1797 if ((silc_sim_load(sim))) {
1799 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1800 SILC_HASH_SIM_INIT));
1801 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1803 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1804 SILC_HASH_SIM_UPDATE));
1805 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1807 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1808 SILC_HASH_SIM_FINAL));
1809 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1810 hash_obj.context_len =
1811 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1812 SILC_HASH_SIM_CONTEXT_LEN));
1813 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1815 /* Put the SIM to the table of all SIM's in server */
1816 silc_dlist_add(server->sim, sim);
1818 SILC_LOG_ERROR(("Error configuring hash functions"));
1820 silc_server_stop(server);
1824 /* Register the hash function */
1825 silc_hash_register(&hash_obj);
1827 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1828 "can't load modules!"));
1829 silc_server_stop(server);
1839 /* Registers configure HMACs. These can then be allocated by the server
1842 bool silc_server_config_register_hmacs(SilcServer server)
1844 SilcServerConfig config = server->config;
1845 SilcServerConfigHmac *hmac = config->hmac;
1847 SILC_LOG_DEBUG(("Registering configured HMACs"));
1853 SilcHmacObject hmac_obj;
1854 if (!silc_hash_is_supported(hmac->hash)) {
1855 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1856 silc_server_stop(server);
1860 /* Register the HMAC */
1861 memset(&hmac_obj, 0, sizeof(hmac_obj));
1862 hmac_obj.name = hmac->name;
1863 hmac_obj.len = hmac->mac_length;
1864 silc_hmac_register(&hmac_obj);
1872 /* Registers configured PKCS's. */
1874 bool silc_server_config_register_pkcs(SilcServer server)
1876 SilcServerConfig config = server->config;
1877 SilcServerConfigPkcs *pkcs = config->pkcs;
1879 SILC_LOG_DEBUG(("Registering configured PKCS"));
1886 for (i = 0; silc_default_pkcs[i].name; i++)
1887 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1888 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1891 if (!silc_pkcs_is_supported(pkcs->name)) {
1892 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1893 silc_server_stop(server);
1902 /* Sets log files where log messages are saved by the server logger. */
1904 void silc_server_config_setlogfiles(SilcServer server)
1906 SilcServerConfig config = server->config;
1907 SilcServerConfigLogging *this;
1909 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1911 silc_log_timestamp = config->logging_timestamp;
1912 silc_log_quick = config->logging_quick;
1913 silc_log_flushdelay = (config->logging_flushdelay ?
1914 config->logging_flushdelay :
1915 SILC_SERVER_LOG_FLUSH_DELAY);
1917 if ((this = config->logging_fatals))
1918 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1920 if ((this = config->logging_errors))
1921 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1923 if ((this = config->logging_warnings))
1924 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1926 if ((this = config->logging_info))
1927 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1931 /* Returns client authentication information from configuration file by host
1934 SilcServerConfigClient *
1935 silc_server_config_find_client(SilcServer server, char *host)
1937 SilcServerConfig config = server->config;
1938 SilcServerConfigClient *client;
1940 if (!config || !host)
1943 for (client = config->clients; client; client = client->next) {
1944 if (client->host && !silc_string_compare(client->host, host))
1949 /* if none matched, then client is already NULL */
1953 /* Returns admin connection configuration by host, username and/or
1956 SilcServerConfigAdmin *
1957 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1960 SilcServerConfig config = server->config;
1961 SilcServerConfigAdmin *admin;
1963 /* make sure we have a value for the matching parameters */
1971 for (admin = config->admins; admin; admin = admin->next) {
1972 if (admin->host && !silc_string_compare(admin->host, host))
1974 if (admin->user && !silc_string_compare(admin->user, user))
1976 if (admin->nick && !silc_string_compare(admin->nick, nick))
1978 /* no checks failed -> this entry matches */
1982 /* if none matched, then admin is already NULL */
1986 /* Returns the denied connection configuration entry by host. */
1988 SilcServerConfigDeny *
1989 silc_server_config_find_denied(SilcServer server, char *host)
1991 SilcServerConfig config = server->config;
1992 SilcServerConfigDeny *deny;
1994 /* make sure we have a value for the matching parameters */
1995 if (!config || !host)
1998 for (deny = config->denied; deny; deny = deny->next) {
1999 if (deny->host && !silc_string_compare(deny->host, host))
2004 /* if none matched, then deny is already NULL */
2008 /* Returns server connection info from server configuartion by host
2011 SilcServerConfigServer *
2012 silc_server_config_find_server_conn(SilcServer server, char *host)
2014 SilcServerConfig config = server->config;
2015 SilcServerConfigServer *serv = NULL;
2020 if (!config->servers)
2023 for (serv = config->servers; serv; serv = serv->next) {
2024 if (!silc_string_compare(serv->host, host))
2032 /* Returns router connection info from server configuration by
2033 host (name or ip). */
2035 SilcServerConfigRouter *
2036 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
2038 SilcServerConfig config = server->config;
2039 SilcServerConfigRouter *serv = NULL;
2044 if (!config->routers)
2047 for (serv = config->routers; serv; serv = serv->next) {
2048 if (!silc_string_compare(serv->host, host))
2050 if (port && serv->port && serv->port != port)
2058 /* Find backup router connection by host (name or ip) */
2060 SilcServerConfigRouter *
2061 silc_server_config_find_backup_conn(SilcServer server, char *host)
2063 SilcServerConfig config = server->config;
2064 SilcServerConfigRouter *serv = NULL;
2069 if (!config->routers)
2072 for (serv = config->routers; serv; serv = serv->next) {
2073 if (!serv->backup_router)
2075 if (!silc_string_compare(serv->host, host))
2083 /* Returns TRUE if configuration for a router connection that we are
2084 initiating exists. */
2086 bool silc_server_config_is_primary_route(SilcServer server)
2088 SilcServerConfig config = server->config;
2089 SilcServerConfigRouter *serv = NULL;
2093 serv = config->routers;
2094 for (i = 0; serv; i++) {
2095 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2106 /* Returns our primary connection configuration or NULL if we do not
2107 have primary router configured. */
2109 SilcServerConfigRouter *
2110 silc_server_config_get_primary_router(SilcServer server)
2112 SilcServerConfig config = server->config;
2113 SilcServerConfigRouter *serv = NULL;
2116 serv = config->routers;
2117 for (i = 0; serv; i++) {
2118 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2126 /* If we have backup router configured that is going to replace us this
2127 function returns it. */
2129 SilcServerConfigRouter *
2130 silc_server_config_get_backup_router(SilcServer server)
2132 SilcServerConfig config = server->config;
2133 SilcServerConfigRouter *serv = NULL;
2136 if (server->server_type != SILC_ROUTER)
2139 serv = config->routers;
2140 for (i = 0; serv; i++) {
2141 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2142 serv->backup_local == TRUE &&
2143 !strcmp(server->config->server_info->primary->server_ip,
2144 serv->backup_replace_ip) &&
2145 server->config->server_info->primary->port ==
2146 serv->backup_replace_port)