5 Author: Giovanni Giacobbi <giovanni@giacobbi.net>
7 Copyright (C) 1997 - 2004 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),
131 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
132 silc_utf8_encode(p, strlen(p), SILC_STRING_LOCALE, *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_LOG_DEBUG(("Adding public key '%s' to authentication cache",
169 public_key->identifier));
170 silc_hash_table_add(*auth_data, public_key, public_key);
178 static bool my_parse_publickeydir(const char *dirname, void **auth_data)
181 struct dirent *get_file;
184 if (!(dp = opendir(dirname))) {
185 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
186 "Could not open directory \"%s\"", dirname));
190 /* errors are not considered fatal */
191 while ((get_file = readdir(dp))) {
192 const char *filename = get_file->d_name;
194 int dirname_len = strlen(dirname), filename_len = strlen(filename);
195 struct stat check_file;
197 /* Ignore "." and "..", and take files only with ".pub" suffix. */
198 if (!strcmp(filename, ".") || !strcmp(filename, "..") ||
199 (filename_len < 5) || strcmp(filename + filename_len - 4, ".pub"))
202 memset(buf, 0, sizeof(buf));
203 snprintf(buf, sizeof(buf) - 1, "%s%s%s", dirname,
204 (dirname[dirname_len - 1] == '/' ? "" : "/"), filename);
206 if (stat(buf, &check_file) < 0) {
207 SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf,
209 } else if (S_ISREG(check_file.st_mode)) {
210 my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL);
215 SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname));
221 SILC_CONFIG_CALLBACK(fetch_generic)
223 SilcServerConfig config = (SilcServerConfig) context;
226 if (!strcmp(name, "module_path")) {
227 CONFIG_IS_DOUBLE(config->module_path);
228 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
230 else if (!strcmp(name, "prefer_passphrase_auth")) {
231 config->prefer_passphrase_auth = *(bool *)val;
233 else if (!strcmp(name, "require_reverse_lookup")) {
234 config->require_reverse_lookup = *(bool *)val;
236 else if (!strcmp(name, "connections_max")) {
237 config->param.connections_max = (SilcUInt32) *(int *)val;
239 else if (!strcmp(name, "connections_max_per_host")) {
240 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
242 else if (!strcmp(name, "keepalive_secs")) {
243 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
245 else if (!strcmp(name, "reconnect_count")) {
246 config->param.reconnect_count = (SilcUInt32) *(int *)val;
248 else if (!strcmp(name, "reconnect_interval")) {
249 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
251 else if (!strcmp(name, "reconnect_interval_max")) {
252 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
254 else if (!strcmp(name, "reconnect_keep_trying")) {
255 config->param.reconnect_keep_trying = *(bool *)val;
257 else if (!strcmp(name, "key_exchange_rekey")) {
258 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
260 else if (!strcmp(name, "key_exchange_pfs")) {
261 config->param.key_exchange_pfs = *(bool *)val;
263 else if (!strcmp(name, "channel_rekey_secs")) {
264 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
266 else if (!strcmp(name, "key_exchange_timeout")) {
267 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
269 else if (!strcmp(name, "conn_auth_timeout")) {
270 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
272 else if (!strcmp(name, "version_protocol")) {
273 CONFIG_IS_DOUBLE(config->param.version_protocol);
274 config->param.version_protocol =
275 (*(char *)val ? strdup((char *) val) : NULL);
277 else if (!strcmp(name, "version_software")) {
278 CONFIG_IS_DOUBLE(config->param.version_software);
279 config->param.version_software =
280 (*(char *)val ? strdup((char *) val) : NULL);
282 else if (!strcmp(name, "version_software_vendor")) {
283 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
284 config->param.version_software_vendor =
285 (*(char *)val ? strdup((char *) val) : NULL);
287 else if (!strcmp(name, "detach_disabled")) {
288 config->detach_disabled = *(bool *)val;
290 else if (!strcmp(name, "detach_timeout")) {
291 config->detach_timeout = (SilcUInt32) *(int *)val;
293 else if (!strcmp(name, "qos")) {
294 config->param.qos = *(bool *)val;
296 else if (!strcmp(name, "qos_rate_limit")) {
297 config->param.qos_rate_limit = *(SilcUInt32 *)val;
299 else if (!strcmp(name, "qos_bytes_limit")) {
300 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
302 else if (!strcmp(name, "qos_limit_sec")) {
303 config->param.qos_limit_sec = *(SilcUInt32 *)val;
305 else if (!strcmp(name, "qos_limit_usec")) {
306 config->param.qos_limit_usec = *(SilcUInt32 *)val;
308 else if (!strcmp(name, "debug_string")) {
309 CONFIG_IS_DOUBLE(config->debug_string);
310 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
313 return SILC_CONFIG_EINTERNAL;
315 return SILC_CONFIG_OK;
321 SILC_CONFIG_CALLBACK(fetch_cipher)
323 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
325 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
326 type, name, context));
327 if (type == SILC_CONFIG_ARG_BLOCK) {
328 /* check the temporary struct's fields */
329 if (!tmp) /* discard empty sub-blocks */
330 return SILC_CONFIG_OK;
332 got_errno = SILC_CONFIG_EMISSFIELDS;
336 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
338 return SILC_CONFIG_OK;
340 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
342 /* Identify and save this value */
343 if (!strcmp(name, "name")) {
344 CONFIG_IS_DOUBLE(tmp->name);
345 tmp->name = strdup((char *) val);
347 else if (!strcmp(name, "module")) {
348 CONFIG_IS_DOUBLE(tmp->module);
349 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
351 else if (!strcmp(name, "keylength")) {
352 tmp->key_length = *(SilcUInt32 *)val;
354 else if (!strcmp(name, "blocklength")) {
355 tmp->block_length = *(SilcUInt32 *)val;
358 return SILC_CONFIG_EINTERNAL;
359 return SILC_CONFIG_OK;
362 silc_free(tmp->name);
363 silc_free(tmp->module);
369 SILC_CONFIG_CALLBACK(fetch_hash)
371 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
373 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
374 type, name, context));
375 if (type == SILC_CONFIG_ARG_BLOCK) {
376 /* check the temporary struct's fields */
377 if (!tmp) /* discard empty sub-blocks */
378 return SILC_CONFIG_OK;
379 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
380 got_errno = SILC_CONFIG_EMISSFIELDS;
384 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
386 return SILC_CONFIG_OK;
388 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
390 /* Identify and save this value */
391 if (!strcmp(name, "name")) {
392 CONFIG_IS_DOUBLE(tmp->name);
393 tmp->name = strdup((char *) val);
395 else if (!strcmp(name, "module")) {
396 CONFIG_IS_DOUBLE(tmp->module);
397 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
399 else if (!strcmp(name, "blocklength")) {
400 tmp->block_length = *(int *)val;
402 else if (!strcmp(name, "digestlength")) {
403 tmp->digest_length = *(int *)val;
406 return SILC_CONFIG_EINTERNAL;
407 return SILC_CONFIG_OK;
410 silc_free(tmp->name);
411 silc_free(tmp->module);
417 SILC_CONFIG_CALLBACK(fetch_hmac)
419 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
421 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
422 type, name, context));
423 if (type == SILC_CONFIG_ARG_BLOCK) {
424 /* check the temporary struct's fields */
425 if (!tmp) /* discard empty sub-blocks */
426 return SILC_CONFIG_OK;
427 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
428 got_errno = SILC_CONFIG_EMISSFIELDS;
432 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
434 return SILC_CONFIG_OK;
436 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
438 /* Identify and save this value */
439 if (!strcmp(name, "name")) {
440 CONFIG_IS_DOUBLE(tmp->name);
441 tmp->name = strdup((char *) val);
443 else if (!strcmp(name, "hash")) {
444 CONFIG_IS_DOUBLE(tmp->hash);
445 tmp->hash = strdup((char *) val);
447 else if (!strcmp(name, "maclength")) {
448 tmp->mac_length = *(int *)val;
451 return SILC_CONFIG_EINTERNAL;
452 return SILC_CONFIG_OK;
455 silc_free(tmp->name);
456 silc_free(tmp->hash);
462 SILC_CONFIG_CALLBACK(fetch_pkcs)
464 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
466 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
467 type, name, context));
468 if (type == SILC_CONFIG_ARG_BLOCK) {
469 /* Check the temporary struct's fields */
470 if (!tmp) /* discard empty sub-blocks */
471 return SILC_CONFIG_OK;
473 got_errno = SILC_CONFIG_EMISSFIELDS;
477 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
479 return SILC_CONFIG_OK;
481 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
483 /* Identify and save this value */
484 if (!strcmp(name, "name")) {
485 CONFIG_IS_DOUBLE(tmp->name);
486 tmp->name = strdup((char *) val);
489 return SILC_CONFIG_EINTERNAL;
490 return SILC_CONFIG_OK;
493 silc_free(tmp->name);
499 SILC_CONFIG_CALLBACK(fetch_serverinfo)
501 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
502 SilcServerConfigServerInfo *server_info = config->server_info;
504 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
505 type, name, context));
507 /* If there isn't the main struct alloc it */
509 config->server_info = server_info = (SilcServerConfigServerInfo *)
510 silc_calloc(1, sizeof(*server_info));
512 if (type == SILC_CONFIG_ARG_BLOCK) {
513 if (!strcmp(name, "primary")) {
514 if (server_info->primary) {
515 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
516 "Double primary specification."));
517 got_errno = SILC_CONFIG_EPRINTLINE;
520 CONFIG_IS_DOUBLE(server_info->primary);
522 /* now check the temporary struct, don't accept empty block and
523 make sure all fields are there */
524 if (!tmp || !tmp->server_ip || !tmp->port) {
525 got_errno = SILC_CONFIG_EMISSFIELDS;
528 server_info->primary = tmp;
530 return SILC_CONFIG_OK;
531 } else if (!strcmp(name, "secondary")) {
533 return SILC_CONFIG_OK;
534 if (!tmp || !tmp->server_ip || !tmp->port) {
535 got_errno = SILC_CONFIG_EMISSFIELDS;
538 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
540 return SILC_CONFIG_OK;
541 } else if (!server_info->public_key || !server_info->private_key) {
542 got_errno = SILC_CONFIG_EMISSFIELDS;
545 return SILC_CONFIG_OK;
547 if (!strcmp(name, "hostname")) {
548 CONFIG_IS_DOUBLE(server_info->server_name);
549 server_info->server_name = strdup((char *) val);
551 else if (!strcmp(name, "ip")) {
552 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
553 CONFIG_IS_DOUBLE(tmp->server_ip);
554 tmp->server_ip = strdup((char *) val);
556 else if (!strcmp(name, "port")) {
557 int port = *(int *)val;
558 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
559 if ((port <= 0) || (port > 65535)) {
560 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
561 "Invalid port number!"));
562 got_errno = SILC_CONFIG_EPRINTLINE;
565 tmp->port = (SilcUInt16) port;
567 else if (!strcmp(name, "servertype")) {
568 CONFIG_IS_DOUBLE(server_info->server_type);
569 server_info->server_type = strdup((char *) val);
571 else if (!strcmp(name, "admin")) {
572 CONFIG_IS_DOUBLE(server_info->admin);
573 server_info->admin = strdup((char *) val);
575 else if (!strcmp(name, "adminemail")) {
576 CONFIG_IS_DOUBLE(server_info->email);
577 server_info->email = strdup((char *) val);
579 else if (!strcmp(name, "location")) {
580 CONFIG_IS_DOUBLE(server_info->location);
581 server_info->location = strdup((char *) val);
583 else if (!strcmp(name, "user")) {
584 CONFIG_IS_DOUBLE(server_info->user);
585 server_info->user = strdup((char *) val);
587 else if (!strcmp(name, "group")) {
588 CONFIG_IS_DOUBLE(server_info->group);
589 server_info->group = strdup((char *) val);
591 else if (!strcmp(name, "motdfile")) {
592 CONFIG_IS_DOUBLE(server_info->motd_file);
593 server_info->motd_file = strdup((char *) val);
595 else if (!strcmp(name, "pidfile")) {
596 CONFIG_IS_DOUBLE(server_info->pid_file);
597 server_info->pid_file = strdup((char *) val);
599 else if (!strcmp(name, "publickey")) {
600 char *file_tmp = (char *) val;
601 CONFIG_IS_DOUBLE(server_info->public_key);
603 /* Try to load specified file, if fail stop config parsing */
604 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
606 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
607 SILC_PKCS_FILE_BIN)) {
608 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
609 return SILC_CONFIG_EPRINTLINE;
612 else if (!strcmp(name, "privatekey")) {
614 char *file_tmp = (char *) val;
615 CONFIG_IS_DOUBLE(server_info->private_key);
617 /* Check the private key file permissions. */
618 if ((stat(file_tmp, &st)) != -1) {
619 if ((st.st_mode & 0777) != 0600) {
620 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
621 "file \"%s\". The permissions must be "
623 return SILC_CONFIG_ESILENT;
627 /* Try to load specified file, if fail stop config parsing */
628 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
629 "", 0, SILC_PKCS_FILE_BIN))
630 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
631 "", 0, SILC_PKCS_FILE_PEM)) {
632 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
633 return SILC_CONFIG_EPRINTLINE;
637 return SILC_CONFIG_EINTERNAL;
638 return SILC_CONFIG_OK;
641 /* Here we need to check if tmp exists because this function handles
642 * misc data (multiple fields and single-only fields) */
644 silc_free(tmp->server_ip);
651 SILC_CONFIG_CALLBACK(fetch_logging)
653 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
655 if (!strcmp(name, "timestamp")) {
656 config->logging_timestamp = *(bool *)val;
658 else if (!strcmp(name, "quicklogs")) {
659 config->logging_quick = *(bool *)val;
661 else if (!strcmp(name, "flushdelay")) {
662 int flushdelay = *(int *)val;
663 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
664 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
665 "Invalid flushdelay value, use quicklogs if you "
666 "want real-time logging."));
667 return SILC_CONFIG_EPRINTLINE;
669 config->logging_flushdelay = (long) flushdelay;
672 /* The following istances happens only in Logging's sub-blocks, a match
673 for the sub-block name means that you should store the filename/maxsize
674 temporary struct to the proper logging channel.
675 If we get a match for "file" or "maxsize" this means that we are inside
676 a sub-sub-block and it is safe to alloc a new tmp. */
677 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
678 else if (!strcmp(name, __chan__)) { \
679 if (!tmp) return SILC_CONFIG_OK; \
681 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
683 config->__member__ = tmp; \
684 config->tmp = NULL; \
686 FETCH_LOGGING_CHAN("info", logging_info)
687 FETCH_LOGGING_CHAN("warnings", logging_warnings)
688 FETCH_LOGGING_CHAN("errors", logging_errors)
689 FETCH_LOGGING_CHAN("fatals", logging_fatals)
690 #undef FETCH_LOGGING_CHAN
691 else if (!strcmp(name, "file")) {
692 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
693 CONFIG_IS_DOUBLE(tmp->file);
694 tmp->file = strdup((char *) val);
696 else if (!strcmp(name, "size")) {
698 config->tmp = silc_calloc(1, sizeof(*tmp));
699 tmp = (SilcServerConfigLogging *) config->tmp;
701 tmp->maxsize = *(SilcUInt32 *) val;
704 return SILC_CONFIG_EINTERNAL;
705 return SILC_CONFIG_OK;
708 silc_free(tmp->file);
714 SILC_CONFIG_CALLBACK(fetch_connparam)
716 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
718 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
719 type, name, context));
720 if (type == SILC_CONFIG_ARG_BLOCK) {
721 /* check the temporary struct's fields */
722 if (!tmp) /* discard empty sub-blocks */
723 return SILC_CONFIG_OK;
725 got_errno = SILC_CONFIG_EMISSFIELDS;
729 my_set_param_defaults(tmp, &config->param);
731 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
733 return SILC_CONFIG_OK;
736 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
737 tmp->reconnect_keep_trying = TRUE;
740 if (!strcmp(name, "name")) {
741 CONFIG_IS_DOUBLE(tmp->name);
742 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
744 else if (!strcmp(name, "connections_max")) {
745 tmp->connections_max = *(SilcUInt32 *)val;
747 else if (!strcmp(name, "connections_max_per_host")) {
748 tmp->connections_max_per_host = *(SilcUInt32 *)val;
750 else if (!strcmp(name, "keepalive_secs")) {
751 tmp->keepalive_secs = *(SilcUInt32 *)val;
753 else if (!strcmp(name, "reconnect_count")) {
754 tmp->reconnect_count = *(SilcUInt32 *)val;
756 else if (!strcmp(name, "reconnect_interval")) {
757 tmp->reconnect_interval = *(SilcUInt32 *)val;
759 else if (!strcmp(name, "reconnect_interval_max")) {
760 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
762 else if (!strcmp(name, "reconnect_keep_trying")) {
763 tmp->reconnect_keep_trying = *(bool *)val;
765 else if (!strcmp(name, "key_exchange_rekey")) {
766 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
768 else if (!strcmp(name, "key_exchange_pfs")) {
769 tmp->key_exchange_pfs = *(bool *)val;
771 else if (!strcmp(name, "version_protocol")) {
772 CONFIG_IS_DOUBLE(tmp->version_protocol);
773 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
775 else if (!strcmp(name, "version_software")) {
776 CONFIG_IS_DOUBLE(tmp->version_software);
777 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
779 else if (!strcmp(name, "version_software_vendor")) {
780 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
781 tmp->version_software_vendor =
782 (*(char *)val ? strdup((char *) val) : NULL);
784 else if (!strcmp(name, "anonymous")) {
785 tmp->anonymous = *(bool *)val;
787 else if (!strcmp(name, "qos")) {
788 tmp->qos = *(bool *)val;
790 else if (!strcmp(name, "qos_rate_limit")) {
791 tmp->qos_rate_limit = *(SilcUInt32 *)val;
793 else if (!strcmp(name, "qos_bytes_limit")) {
794 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
796 else if (!strcmp(name, "qos_limit_sec")) {
797 tmp->qos_limit_sec = *(SilcUInt32 *)val;
799 else if (!strcmp(name, "qos_limit_usec")) {
800 tmp->qos_limit_usec = *(SilcUInt32 *)val;
803 return SILC_CONFIG_EINTERNAL;
805 return SILC_CONFIG_OK;
808 silc_free(tmp->name);
814 SILC_CONFIG_CALLBACK(fetch_client)
816 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
818 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
819 type, name, context));
821 /* Alloc before block checking, because empty sub-blocks are welcome here */
822 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
824 if (type == SILC_CONFIG_ARG_BLOCK) {
825 /* empty sub-blocks are welcome */
826 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
828 return SILC_CONFIG_OK;
831 /* Identify and save this value */
832 if (!strcmp(name, "host")) {
833 CONFIG_IS_DOUBLE(tmp->host);
834 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
836 else if (!strcmp(name, "passphrase")) {
837 CONFIG_IS_DOUBLE(tmp->passphrase);
838 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
839 (void *)&tmp->passphrase,
840 &tmp->passphrase_len)) {
841 got_errno = SILC_CONFIG_EPRINTLINE;
845 else if (!strcmp(name, "publickey")) {
846 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
847 (void *)&tmp->publickeys, NULL)) {
848 got_errno = SILC_CONFIG_EPRINTLINE;
852 else if (!strcmp(name, "publickeydir")) {
853 if (!my_parse_publickeydir((char *) val, (void *)&tmp->publickeys)) {
854 got_errno = SILC_CONFIG_EPRINTLINE;
858 else if (!strcmp(name, "params")) {
859 CONFIG_IS_DOUBLE(tmp->param);
860 tmp->param = my_find_param(config, (char *) val);
861 if (!tmp->param) { /* error message already output */
862 got_errno = SILC_CONFIG_EPRINTLINE;
867 return SILC_CONFIG_EINTERNAL;
868 return SILC_CONFIG_OK;
871 silc_free(tmp->host);
872 CONFIG_FREE_AUTH(tmp);
878 SILC_CONFIG_CALLBACK(fetch_admin)
880 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
882 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
883 type, name, context));
884 if (type == SILC_CONFIG_ARG_BLOCK) {
885 /* check the temporary struct's fields */
886 if (!tmp) /* discard empty sub-blocks */
887 return SILC_CONFIG_OK;
889 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
891 return SILC_CONFIG_OK;
893 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
895 /* Identify and save this value */
896 if (!strcmp(name, "host")) {
897 CONFIG_IS_DOUBLE(tmp->host);
898 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
900 else if (!strcmp(name, "user")) {
901 CONFIG_IS_DOUBLE(tmp->user);
902 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
904 else if (!strcmp(name, "nick")) {
905 CONFIG_IS_DOUBLE(tmp->nick);
906 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
908 else if (!strcmp(name, "passphrase")) {
909 CONFIG_IS_DOUBLE(tmp->passphrase);
910 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
911 (void *)&tmp->passphrase,
912 &tmp->passphrase_len)) {
913 got_errno = SILC_CONFIG_EPRINTLINE;
917 else if (!strcmp(name, "publickey")) {
918 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
919 (void *)&tmp->publickeys, NULL)) {
920 got_errno = SILC_CONFIG_EPRINTLINE;
924 else if (!strcmp(name, "publickeydir")) {
925 if (!my_parse_publickeydir((char *) val, (void *)&tmp->publickeys)) {
926 got_errno = SILC_CONFIG_EPRINTLINE;
931 return SILC_CONFIG_EINTERNAL;
932 return SILC_CONFIG_OK;
935 silc_free(tmp->host);
936 silc_free(tmp->user);
937 silc_free(tmp->nick);
938 CONFIG_FREE_AUTH(tmp);
944 SILC_CONFIG_CALLBACK(fetch_deny)
946 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
948 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
949 type, name, context));
950 if (type == SILC_CONFIG_ARG_BLOCK) {
951 /* check the temporary struct's fields */
952 if (!tmp) /* discard empty sub-blocks */
953 return SILC_CONFIG_OK;
955 got_errno = SILC_CONFIG_EMISSFIELDS;
959 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
961 return SILC_CONFIG_OK;
963 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
965 /* Identify and save this value */
966 if (!strcmp(name, "host")) {
967 CONFIG_IS_DOUBLE(tmp->host);
968 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
970 else if (!strcmp(name, "reason")) {
971 CONFIG_IS_DOUBLE(tmp->reason);
972 tmp->reason = strdup((char *) val);
975 return SILC_CONFIG_EINTERNAL;
976 return SILC_CONFIG_OK;
979 silc_free(tmp->host);
980 silc_free(tmp->reason);
986 SILC_CONFIG_CALLBACK(fetch_server)
988 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
990 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
991 type, name, context));
992 if (type == SILC_CONFIG_ARG_BLOCK) {
993 /* check the temporary struct's fields */
994 if (!tmp) /* discard empty sub-blocks */
995 return SILC_CONFIG_OK;
997 got_errno = SILC_CONFIG_EMISSFIELDS;
1001 /* the temporary struct is ok, append it to the list */
1002 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1004 return SILC_CONFIG_OK;
1006 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1008 /* Identify and save this value */
1009 if (!strcmp(name, "host")) {
1010 CONFIG_IS_DOUBLE(tmp->host);
1011 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1013 else if (!strcmp(name, "passphrase")) {
1014 CONFIG_IS_DOUBLE(tmp->passphrase);
1015 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1016 (void *)&tmp->passphrase,
1017 &tmp->passphrase_len)) {
1018 got_errno = SILC_CONFIG_EPRINTLINE;
1022 else if (!strcmp(name, "publickey")) {
1023 CONFIG_IS_DOUBLE(tmp->publickeys);
1024 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1025 (void *)&tmp->publickeys, NULL)) {
1026 got_errno = SILC_CONFIG_EPRINTLINE;
1030 else if (!strcmp(name, "params")) {
1031 CONFIG_IS_DOUBLE(tmp->param);
1032 tmp->param = my_find_param(config, (char *) val);
1033 if (!tmp->param) { /* error message already output */
1034 got_errno = SILC_CONFIG_EPRINTLINE;
1038 else if (!strcmp(name, "backup")) {
1039 tmp->backup_router = *(bool *)val;
1042 return SILC_CONFIG_EINTERNAL;
1044 return SILC_CONFIG_OK;
1047 silc_free(tmp->host);
1048 CONFIG_FREE_AUTH(tmp);
1054 SILC_CONFIG_CALLBACK(fetch_router)
1056 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1058 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1059 type, name, context));
1060 if (type == SILC_CONFIG_ARG_BLOCK) {
1061 if (!tmp) /* discard empty sub-blocks */
1062 return SILC_CONFIG_OK;
1064 got_errno = SILC_CONFIG_EMISSFIELDS;
1068 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1070 return SILC_CONFIG_OK;
1072 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1074 /* Identify and save this value */
1075 if (!strcmp(name, "host")) {
1076 CONFIG_IS_DOUBLE(tmp->host);
1077 tmp->host = strdup((char *) val);
1079 else if (!strcmp(name, "port")) {
1080 int port = *(int *)val;
1081 if ((port <= 0) || (port > 65535)) {
1082 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1083 "Invalid port number!"));
1084 got_errno = SILC_CONFIG_EPRINTLINE;
1087 tmp->port = (SilcUInt16) port;
1089 else if (!strcmp(name, "passphrase")) {
1090 CONFIG_IS_DOUBLE(tmp->passphrase);
1091 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1092 (void *)&tmp->passphrase,
1093 &tmp->passphrase_len)) {
1094 got_errno = SILC_CONFIG_EPRINTLINE;
1098 else if (!strcmp(name, "publickey")) {
1099 CONFIG_IS_DOUBLE(tmp->publickeys);
1100 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1101 (void *)&tmp->publickeys, NULL)) {
1102 got_errno = SILC_CONFIG_EPRINTLINE;
1106 else if (!strcmp(name, "params")) {
1107 CONFIG_IS_DOUBLE(tmp->param);
1108 tmp->param = my_find_param(config, (char *) val);
1109 if (!tmp->param) { /* error message already output */
1110 got_errno = SILC_CONFIG_EPRINTLINE;
1114 else if (!strcmp(name, "initiator")) {
1115 tmp->initiator = *(bool *)val;
1117 else if (!strcmp(name, "backuphost")) {
1118 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1119 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1121 tmp->backup_router = TRUE;
1123 else if (!strcmp(name, "backupport")) {
1124 int port = *(int *)val;
1125 if ((port <= 0) || (port > 65535)) {
1126 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1127 "Invalid port number!"));
1128 got_errno = SILC_CONFIG_EPRINTLINE;
1131 tmp->backup_replace_port = (SilcUInt16) port;
1133 else if (!strcmp(name, "backuplocal")) {
1134 tmp->backup_local = *(bool *)val;
1137 return SILC_CONFIG_EINTERNAL;
1139 return SILC_CONFIG_OK;
1142 silc_free(tmp->host);
1143 silc_free(tmp->backup_replace_ip);
1144 CONFIG_FREE_AUTH(tmp);
1150 /* known config options tables */
1151 static const SilcConfigTable table_general[] = {
1152 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1153 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1154 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1155 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1156 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1157 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1158 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1159 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1160 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1161 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1162 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1163 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1164 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1165 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1166 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1167 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1168 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1169 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1170 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1171 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1172 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1173 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1174 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1175 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1176 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1177 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1181 static const SilcConfigTable table_cipher[] = {
1182 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1183 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1184 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1185 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1189 static const SilcConfigTable table_hash[] = {
1190 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1191 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1192 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1193 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1197 static const SilcConfigTable table_hmac[] = {
1198 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1199 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1200 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1204 static const SilcConfigTable table_pkcs[] = {
1205 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1209 static const SilcConfigTable table_serverinfo_c[] = {
1210 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1211 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1215 static const SilcConfigTable table_serverinfo[] = {
1216 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1217 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1218 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1219 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1220 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1221 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1222 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1223 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1224 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1225 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1226 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1227 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1228 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1232 static const SilcConfigTable table_logging_c[] = {
1233 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1234 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1235 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1239 static const SilcConfigTable table_logging[] = {
1240 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1241 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1242 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1243 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1244 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1245 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1246 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1250 static const SilcConfigTable table_connparam[] = {
1251 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1252 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1253 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1254 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1255 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1256 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1257 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1258 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1259 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1260 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1261 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1262 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1263 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1264 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1265 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1266 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1267 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1268 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1269 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1270 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1274 static const SilcConfigTable table_client[] = {
1275 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1276 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1277 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1278 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1279 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1283 static const SilcConfigTable table_admin[] = {
1284 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1285 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1286 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1287 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1288 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1289 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1290 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1291 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1295 static const SilcConfigTable table_deny[] = {
1296 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1297 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1301 static const SilcConfigTable table_serverconn[] = {
1302 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1303 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1304 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1305 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1306 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1310 static const SilcConfigTable table_routerconn[] = {
1311 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1312 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1313 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1314 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1315 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1316 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1317 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1318 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1319 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1323 static const SilcConfigTable table_main[] = {
1324 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1325 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1326 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1327 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1328 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1329 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1330 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1331 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1332 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1333 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1334 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1335 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1336 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1340 /* Set default values to stuff that was not configured. */
1342 static void silc_server_config_set_defaults(SilcServerConfig config)
1344 my_set_param_defaults(&config->param, NULL);
1346 config->channel_rekey_secs = (config->channel_rekey_secs ?
1347 config->channel_rekey_secs :
1348 SILC_SERVER_CHANNEL_REKEY);
1349 config->key_exchange_timeout = (config->key_exchange_timeout ?
1350 config->key_exchange_timeout :
1351 SILC_SERVER_SKE_TIMEOUT);
1352 config->conn_auth_timeout = (config->conn_auth_timeout ?
1353 config->conn_auth_timeout :
1354 SILC_SERVER_CONNAUTH_TIMEOUT);
1357 /* Check for correctness of the configuration */
1359 static bool silc_server_config_check(SilcServerConfig config)
1362 SilcServerConfigServer *s;
1363 SilcServerConfigRouter *r;
1366 /* ServerConfig is mandatory */
1367 if (!config->server_info) {
1368 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1372 /* RouterConnection sanity checks */
1374 if (config->routers && config->routers->backup_router == TRUE &&
1376 SILC_SERVER_LOG_ERROR((
1377 "\nError: First RouterConnection block must be primary router "
1378 "connection. You have marked it incorrectly as backup router."));
1382 if (config->routers && config->routers->initiator == FALSE &&
1383 config->routers->backup_router == FALSE) {
1384 SILC_SERVER_LOG_ERROR((
1385 "\nError: First RouterConnection block must be primary router "
1386 "connection and it must be marked as Initiator."));
1390 if (config->routers && config->routers->backup_router == TRUE &&
1391 !config->servers && !config->routers->next) {
1392 SILC_SERVER_LOG_ERROR((
1393 "\nError: You have configured backup router but not primary router. "
1394 "If backup router is configured also primary router must be "
1399 /* Backup router sanity checks */
1401 for (r = config->routers; r; r = r->next) {
1402 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1403 SILC_SERVER_LOG_ERROR((
1404 "\nError: Backup router connection incorrectly configured to use "
1405 "primary and backup router as same host `%s'. They must not be "
1406 "same host.", r->host));
1410 if (r->initiator == FALSE && r->port != 0) {
1411 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1412 "specified. Ignoring Port value."));
1417 /* ServerConnection sanity checks */
1419 for (s = config->servers; s; s = s->next) {
1420 if (s->backup_router) {
1426 for (s = config->servers; s; s = s->next) {
1427 if (!s->backup_router) {
1428 SILC_SERVER_LOG_ERROR((
1429 "\nError: Your server is backup router but not all ServerConnection "
1430 "blocks were marked as backup connections. They all must be "
1431 "marked as backup connections."));
1441 /* Allocates a new configuration object, opens configuration file and
1442 parses it. The parsed data is returned to the newly allocated
1443 configuration object. The SilcServerConfig must be freed by calling
1444 the silc_server_config_destroy function. */
1446 SilcServerConfig silc_server_config_alloc(const char *filename)
1448 SilcServerConfig config_new;
1449 SilcConfigEntity ent;
1450 SilcConfigFile *file;
1452 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1454 /* alloc a config object */
1455 config_new = silc_calloc(1, sizeof(*config_new));
1459 /* general config defaults */
1460 config_new->refcount = 1;
1461 config_new->logging_timestamp = TRUE;
1462 config_new->param.reconnect_keep_trying = TRUE;
1464 /* obtain a config file object */
1465 file = silc_config_open(filename);
1467 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1472 /* obtain a SilcConfig entity, we can use it to start the parsing */
1473 ent = silc_config_init(file);
1475 /* load the known configuration options, give our empty object as context */
1476 silc_config_register_table(ent, table_main, (void *) config_new);
1478 /* enter the main parsing loop. When this returns, we have the parsing
1479 * result and the object filled (or partially, in case of errors). */
1480 ret = silc_config_main(ent);
1481 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1482 silc_config_strerror(ret)));
1484 /* Check if the parser returned errors */
1486 /* handle this special error return which asks to quietly return */
1487 if (ret != SILC_CONFIG_ESILENT) {
1488 char *linebuf, *filename = silc_config_get_filename(file);
1489 SilcUInt32 line = silc_config_get_line(file);
1490 if (ret != SILC_CONFIG_EPRINTLINE)
1491 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1492 silc_config_strerror(ret)));
1493 linebuf = silc_config_read_line(file, line);
1495 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1500 silc_server_config_destroy(config_new);
1501 silc_config_close(file);
1505 /* close (destroy) the file object */
1506 silc_config_close(file);
1508 /* Check the configuration */
1509 if (!silc_server_config_check(config_new)) {
1510 silc_server_config_destroy(config_new);
1514 /* Set default to configuration parameters */
1515 silc_server_config_set_defaults(config_new);
1520 /* Increments the reference counter of a config object */
1522 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1527 ref->config = config;
1528 ref->ref_ptr = ref_ptr;
1529 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1530 config->refcount - 1, config->refcount));
1534 /* Decrements the reference counter of a config object. If the counter
1535 reaches 0, the config object is destroyed. */
1537 void silc_server_config_unref(SilcServerConfigRef *ref)
1540 silc_server_config_destroy(ref->config);
1543 /* Destroy a config object with all his children lists */
1545 void silc_server_config_destroy(SilcServerConfig config)
1550 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1551 config->refcount + 1, config->refcount));
1552 if (config->refcount > 0)
1555 SILC_LOG_DEBUG(("Freeing config context"));
1557 /* Destroy general config stuff */
1558 silc_free(config->module_path);
1559 silc_free(config->debug_string);
1560 silc_free(config->param.version_protocol);
1561 silc_free(config->param.version_software);
1562 silc_free(config->param.version_software_vendor);
1564 /* Destroy Logging channels */
1565 if (config->logging_info)
1566 silc_free(config->logging_info->file);
1567 if (config->logging_warnings)
1568 silc_free(config->logging_warnings->file);
1569 if (config->logging_errors)
1570 silc_free(config->logging_errors->file);
1571 if (config->logging_fatals)
1572 silc_free(config->logging_fatals->file);
1573 silc_free(config->logging_info);
1574 silc_free(config->logging_warnings);
1575 silc_free(config->logging_errors);
1576 silc_free(config->logging_fatals);
1578 /* Destroy the ServerInfo struct */
1579 if (config->server_info) {
1580 register SilcServerConfigServerInfo *si = config->server_info;
1581 silc_free(si->server_name);
1583 silc_free(si->primary->server_ip);
1584 silc_free(si->primary);
1586 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1588 silc_free(di->server_ip);
1591 silc_free(si->server_type);
1592 silc_free(si->location);
1593 silc_free(si->admin);
1594 silc_free(si->email);
1595 silc_free(si->user);
1596 silc_free(si->group);
1597 silc_free(si->motd_file);
1598 silc_free(si->pid_file);
1599 silc_pkcs_public_key_free(si->public_key);
1600 silc_pkcs_private_key_free(si->private_key);
1604 /* Now let's destroy the lists */
1606 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1608 silc_free(di->name);
1609 silc_free(di->module);
1612 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1613 silc_free(di->name);
1614 silc_free(di->module);
1617 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1618 silc_free(di->name);
1619 silc_free(di->hash);
1622 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1623 silc_free(di->name);
1626 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1627 config->conn_params)
1628 silc_free(di->name);
1629 silc_free(di->version_protocol);
1630 silc_free(di->version_software);
1631 silc_free(di->version_software_vendor);
1634 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1635 silc_free(di->host);
1636 CONFIG_FREE_AUTH(di);
1639 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1640 silc_free(di->host);
1641 silc_free(di->user);
1642 silc_free(di->nick);
1643 CONFIG_FREE_AUTH(di);
1646 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1647 silc_free(di->host);
1648 silc_free(di->reason);
1651 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1653 silc_free(di->host);
1654 CONFIG_FREE_AUTH(di);
1657 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1659 silc_free(di->host);
1660 silc_free(di->backup_replace_ip);
1661 CONFIG_FREE_AUTH(di);
1665 memset(config, 'F', sizeof(*config));
1669 /* Registers configured ciphers. These can then be allocated by the
1670 server when needed. */
1672 bool silc_server_config_register_ciphers(SilcServer server)
1674 SilcServerConfig config = server->config;
1675 SilcServerConfigCipher *cipher = config->cipher;
1676 char *module_path = config->module_path;
1678 SILC_LOG_DEBUG(("Registering configured ciphers"));
1680 if (!cipher) /* any cipher in the config file? */
1684 /* if there isn't a module_path OR there isn't a module sim name try to
1685 * use buil-in functions */
1686 if (!module_path || !cipher->module) {
1688 for (i = 0; silc_default_ciphers[i].name; i++)
1689 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1690 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1693 if (!silc_cipher_is_supported(cipher->name)) {
1694 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1695 silc_server_stop(server);
1700 /* Load (try at least) the crypto SIM module */
1701 char buf[1023], *alg_name;
1702 SilcCipherObject cipher_obj;
1705 memset(&cipher_obj, 0, sizeof(cipher_obj));
1706 cipher_obj.name = cipher->name;
1707 cipher_obj.block_len = cipher->block_length;
1708 cipher_obj.key_len = cipher->key_length * 8;
1710 /* build the libname */
1711 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1713 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1715 alg_name = strdup(cipher->name);
1716 if (strchr(alg_name, '-'))
1717 *strchr(alg_name, '-') = '\0';
1719 if (silc_sim_load(sim)) {
1720 cipher_obj.set_key =
1721 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1722 SILC_CIPHER_SIM_SET_KEY));
1723 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1724 cipher_obj.set_key_with_string =
1725 silc_sim_getsym(sim,
1726 silc_sim_symname(alg_name,
1727 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1728 SILC_LOG_DEBUG(("set_key_with_string=%p",
1729 cipher_obj.set_key_with_string));
1730 cipher_obj.encrypt =
1731 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1732 SILC_CIPHER_SIM_ENCRYPT_CBC));
1733 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1734 cipher_obj.decrypt =
1735 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1736 SILC_CIPHER_SIM_DECRYPT_CBC));
1737 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1738 cipher_obj.context_len =
1739 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1740 SILC_CIPHER_SIM_CONTEXT_LEN));
1741 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1743 /* Put the SIM to the list of all SIM's in server */
1744 silc_dlist_add(server->sim, sim);
1746 silc_free(alg_name);
1748 SILC_LOG_ERROR(("Error configuring ciphers"));
1750 silc_server_stop(server);
1754 /* Register the cipher */
1755 silc_cipher_register(&cipher_obj);
1757 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1758 "can't load modules!"));
1759 silc_server_stop(server);
1763 cipher = cipher->next;
1769 /* Registers configured hash functions. These can then be allocated by the
1770 server when needed. */
1772 bool silc_server_config_register_hashfuncs(SilcServer server)
1774 SilcServerConfig config = server->config;
1775 SilcServerConfigHash *hash = config->hash;
1776 char *module_path = config->module_path;
1778 SILC_LOG_DEBUG(("Registering configured hash functions"));
1780 if (!hash) /* any hash func in the config file? */
1784 /* if there isn't a module_path OR there isn't a module sim name try to
1785 * use buil-in functions */
1786 if (!module_path || !hash->module) {
1788 for (i = 0; silc_default_hash[i].name; i++)
1789 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1790 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1793 if (!silc_hash_is_supported(hash->name)) {
1794 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1795 silc_server_stop(server);
1800 /* Load (try at least) the hash SIM module */
1801 SilcHashObject hash_obj;
1804 memset(&hash_obj, 0, sizeof(hash_obj));
1805 hash_obj.name = hash->name;
1806 hash_obj.block_len = hash->block_length;
1807 hash_obj.hash_len = hash->digest_length;
1809 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1811 if ((silc_sim_load(sim))) {
1813 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1814 SILC_HASH_SIM_INIT));
1815 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1817 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1818 SILC_HASH_SIM_UPDATE));
1819 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1821 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1822 SILC_HASH_SIM_FINAL));
1823 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1824 hash_obj.context_len =
1825 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1826 SILC_HASH_SIM_CONTEXT_LEN));
1827 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1829 /* Put the SIM to the table of all SIM's in server */
1830 silc_dlist_add(server->sim, sim);
1832 SILC_LOG_ERROR(("Error configuring hash functions"));
1834 silc_server_stop(server);
1838 /* Register the hash function */
1839 silc_hash_register(&hash_obj);
1841 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1842 "can't load modules!"));
1843 silc_server_stop(server);
1853 /* Registers configure HMACs. These can then be allocated by the server
1856 bool silc_server_config_register_hmacs(SilcServer server)
1858 SilcServerConfig config = server->config;
1859 SilcServerConfigHmac *hmac = config->hmac;
1861 SILC_LOG_DEBUG(("Registering configured HMACs"));
1867 SilcHmacObject hmac_obj;
1868 if (!silc_hash_is_supported(hmac->hash)) {
1869 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1870 silc_server_stop(server);
1874 /* Register the HMAC */
1875 memset(&hmac_obj, 0, sizeof(hmac_obj));
1876 hmac_obj.name = hmac->name;
1877 hmac_obj.len = hmac->mac_length;
1878 silc_hmac_register(&hmac_obj);
1886 /* Registers configured PKCS's. */
1888 bool silc_server_config_register_pkcs(SilcServer server)
1890 SilcServerConfig config = server->config;
1891 SilcServerConfigPkcs *pkcs = config->pkcs;
1893 SILC_LOG_DEBUG(("Registering configured PKCS"));
1900 for (i = 0; silc_default_pkcs[i].name; i++)
1901 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1902 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1905 if (!silc_pkcs_is_supported(pkcs->name)) {
1906 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1907 silc_server_stop(server);
1916 /* Sets log files where log messages are saved by the server logger. */
1918 void silc_server_config_setlogfiles(SilcServer server)
1920 SilcServerConfig config = server->config;
1921 SilcServerConfigLogging *this;
1923 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1925 silc_log_timestamp = config->logging_timestamp;
1926 silc_log_quick = config->logging_quick;
1927 silc_log_flushdelay = (config->logging_flushdelay ?
1928 config->logging_flushdelay :
1929 SILC_SERVER_LOG_FLUSH_DELAY);
1931 if ((this = config->logging_fatals))
1932 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1934 if ((this = config->logging_errors))
1935 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1937 if ((this = config->logging_warnings))
1938 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1940 if ((this = config->logging_info))
1941 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1945 /* Returns client authentication information from configuration file by host
1948 SilcServerConfigClient *
1949 silc_server_config_find_client(SilcServer server, char *host)
1951 SilcServerConfig config = server->config;
1952 SilcServerConfigClient *client;
1954 if (!config || !host)
1957 for (client = config->clients; client; client = client->next) {
1958 if (client->host && !silc_string_compare(client->host, host))
1963 /* if none matched, then client is already NULL */
1967 /* Returns admin connection configuration by host, username and/or
1970 SilcServerConfigAdmin *
1971 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1974 SilcServerConfig config = server->config;
1975 SilcServerConfigAdmin *admin;
1977 /* make sure we have a value for the matching parameters */
1985 for (admin = config->admins; admin; admin = admin->next) {
1986 if (admin->host && !silc_string_compare(admin->host, host))
1988 if (admin->user && !silc_string_compare(admin->user, user))
1990 if (admin->nick && !silc_string_compare(admin->nick, nick))
1992 /* no checks failed -> this entry matches */
1996 /* if none matched, then admin is already NULL */
2000 /* Returns the denied connection configuration entry by host. */
2002 SilcServerConfigDeny *
2003 silc_server_config_find_denied(SilcServer server, char *host)
2005 SilcServerConfig config = server->config;
2006 SilcServerConfigDeny *deny;
2008 /* make sure we have a value for the matching parameters */
2009 if (!config || !host)
2012 for (deny = config->denied; deny; deny = deny->next) {
2013 if (deny->host && !silc_string_compare(deny->host, host))
2018 /* if none matched, then deny is already NULL */
2022 /* Returns server connection info from server configuartion by host
2025 SilcServerConfigServer *
2026 silc_server_config_find_server_conn(SilcServer server, char *host)
2028 SilcServerConfig config = server->config;
2029 SilcServerConfigServer *serv = NULL;
2034 if (!config->servers)
2037 for (serv = config->servers; serv; serv = serv->next) {
2038 if (!silc_string_compare(serv->host, host))
2046 /* Returns router connection info from server configuration by
2047 host (name or ip). */
2049 SilcServerConfigRouter *
2050 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
2052 SilcServerConfig config = server->config;
2053 SilcServerConfigRouter *serv = NULL;
2058 if (!config->routers)
2061 for (serv = config->routers; serv; serv = serv->next) {
2062 if (!silc_string_compare(serv->host, host))
2064 if (port && serv->port && serv->port != port)
2072 /* Find backup router connection by host (name or ip) */
2074 SilcServerConfigRouter *
2075 silc_server_config_find_backup_conn(SilcServer server, char *host)
2077 SilcServerConfig config = server->config;
2078 SilcServerConfigRouter *serv = NULL;
2083 if (!config->routers)
2086 for (serv = config->routers; serv; serv = serv->next) {
2087 if (!serv->backup_router)
2089 if (!silc_string_compare(serv->host, host))
2097 /* Returns TRUE if configuration for a router connection that we are
2098 initiating exists. */
2100 bool silc_server_config_is_primary_route(SilcServer server)
2102 SilcServerConfig config = server->config;
2103 SilcServerConfigRouter *serv = NULL;
2107 serv = config->routers;
2108 for (i = 0; serv; i++) {
2109 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2120 /* Returns our primary connection configuration or NULL if we do not
2121 have primary router configured. */
2123 SilcServerConfigRouter *
2124 silc_server_config_get_primary_router(SilcServer server)
2126 SilcServerConfig config = server->config;
2127 SilcServerConfigRouter *serv = NULL;
2130 serv = config->routers;
2131 for (i = 0; serv; i++) {
2132 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2140 /* If we have backup router configured that is going to replace us this
2141 function returns it. */
2143 SilcServerConfigRouter *
2144 silc_server_config_get_backup_router(SilcServer server)
2146 SilcServerConfig config = server->config;
2147 SilcServerConfigRouter *serv = NULL;
2150 if (server->server_type != SILC_ROUTER)
2153 serv = config->routers;
2154 for (i = 0; serv; i++) {
2155 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2156 serv->backup_local == TRUE &&
2157 !strcmp(server->config->server_info->primary->server_ip,
2158 serv->backup_replace_ip) &&
2159 server->config->server_info->primary->port ==
2160 serv->backup_replace_port)