5 Author: Giovanni Giacobbi <giovanni@giacobbi.net>
7 Copyright (C) 1997 - 2005 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "serverincludes.h"
22 #include "server_internal.h"
26 #define SERVER_CONFIG_DEBUG(fmt) SILC_LOG_DEBUG(fmt)
28 #define SERVER_CONFIG_DEBUG(fmt)
31 /* auto-declare needed variables for the common list parsing */
32 #define SILC_SERVER_CONFIG_SECTION_INIT(__type__) \
33 SilcServerConfig config = (SilcServerConfig) context; \
34 __type__ *findtmp, *tmp = (__type__ *) config->tmp; \
37 /* allocate the tmp field for fetching data */
38 #define SILC_SERVER_CONFIG_ALLOCTMP(__type__) \
40 config->tmp = silc_calloc(1, sizeof(*findtmp)); \
41 tmp = (__type__ *) config->tmp; \
44 /* append the tmp field to the specified list */
45 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
49 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
50 findtmp->next = tmp; \
53 /* loops all elements in a list and provides a di struct pointer of the
54 * specified type containing the current element */
55 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
56 for (tmp = (void *) __list__; tmp;) { \
57 __type__ *di = (__type__ *) tmp; \
58 tmp = (void *) di->next;
60 /* Set EDOUBLE error value and bail out if necessary */
61 #define CONFIG_IS_DOUBLE(__x__) \
63 got_errno = SILC_CONFIG_EDOUBLE; \
67 /* Free the authentication fields in the specified struct
68 * Expands to two instructions */
69 #define CONFIG_FREE_AUTH(__section__) \
70 silc_free(__section__->passphrase); \
71 if (__section__->publickeys) \
72 silc_hash_table_free(__section__->publickeys);
74 static void my_free_public_key(void *key, void *context, void *user_data)
76 silc_pkcs_public_key_free(context);
79 /* Set default values to those parameters that have not been defined */
81 my_set_param_defaults(SilcServerConfigConnParams *params,
82 SilcServerConfigConnParams *defaults)
84 #define SET_PARAM_DEFAULT(p, d) params->p = \
85 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
87 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
88 SET_PARAM_DEFAULT(connections_max_per_host,
89 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
90 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
91 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
92 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
93 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
94 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
95 SET_PARAM_DEFAULT(qos_rate_limit, SILC_SERVER_QOS_RATE_LIMIT);
96 SET_PARAM_DEFAULT(qos_bytes_limit, SILC_SERVER_QOS_BYTES_LIMIT);
97 SET_PARAM_DEFAULT(qos_limit_sec, SILC_SERVER_QOS_LIMIT_SEC);
98 SET_PARAM_DEFAULT(qos_limit_usec, SILC_SERVER_QOS_LIMIT_USEC);
99 SET_PARAM_DEFAULT(chlimit, SILC_SERVER_CH_JOIN_LIMIT);
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, "channel_join_limit")) {
309 config->param.chlimit = *(SilcUInt32 *)val;
311 else if (!strcmp(name, "debug_string")) {
312 CONFIG_IS_DOUBLE(config->debug_string);
313 config->debug_string = (*(char *)val ? strdup((char *) val) : NULL);
316 return SILC_CONFIG_EINTERNAL;
318 return SILC_CONFIG_OK;
324 SILC_CONFIG_CALLBACK(fetch_cipher)
326 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
328 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
329 type, name, context));
330 if (type == SILC_CONFIG_ARG_BLOCK) {
331 /* check the temporary struct's fields */
332 if (!tmp) /* discard empty sub-blocks */
333 return SILC_CONFIG_OK;
335 got_errno = SILC_CONFIG_EMISSFIELDS;
339 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
341 return SILC_CONFIG_OK;
343 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
345 /* Identify and save this value */
346 if (!strcmp(name, "name")) {
347 CONFIG_IS_DOUBLE(tmp->name);
348 tmp->name = strdup((char *) val);
350 else if (!strcmp(name, "module")) {
351 CONFIG_IS_DOUBLE(tmp->module);
352 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
354 else if (!strcmp(name, "keylength")) {
355 tmp->key_length = *(SilcUInt32 *)val;
357 else if (!strcmp(name, "blocklength")) {
358 tmp->block_length = *(SilcUInt32 *)val;
361 return SILC_CONFIG_EINTERNAL;
362 return SILC_CONFIG_OK;
365 silc_free(tmp->name);
366 silc_free(tmp->module);
372 SILC_CONFIG_CALLBACK(fetch_hash)
374 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
376 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
377 type, name, context));
378 if (type == SILC_CONFIG_ARG_BLOCK) {
379 /* check the temporary struct's fields */
380 if (!tmp) /* discard empty sub-blocks */
381 return SILC_CONFIG_OK;
382 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
383 got_errno = SILC_CONFIG_EMISSFIELDS;
387 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
389 return SILC_CONFIG_OK;
391 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
393 /* Identify and save this value */
394 if (!strcmp(name, "name")) {
395 CONFIG_IS_DOUBLE(tmp->name);
396 tmp->name = strdup((char *) val);
398 else if (!strcmp(name, "module")) {
399 CONFIG_IS_DOUBLE(tmp->module);
400 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
402 else if (!strcmp(name, "blocklength")) {
403 tmp->block_length = *(int *)val;
405 else if (!strcmp(name, "digestlength")) {
406 tmp->digest_length = *(int *)val;
409 return SILC_CONFIG_EINTERNAL;
410 return SILC_CONFIG_OK;
413 silc_free(tmp->name);
414 silc_free(tmp->module);
420 SILC_CONFIG_CALLBACK(fetch_hmac)
422 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
424 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
425 type, name, context));
426 if (type == SILC_CONFIG_ARG_BLOCK) {
427 /* check the temporary struct's fields */
428 if (!tmp) /* discard empty sub-blocks */
429 return SILC_CONFIG_OK;
430 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
431 got_errno = SILC_CONFIG_EMISSFIELDS;
435 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
437 return SILC_CONFIG_OK;
439 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
441 /* Identify and save this value */
442 if (!strcmp(name, "name")) {
443 CONFIG_IS_DOUBLE(tmp->name);
444 tmp->name = strdup((char *) val);
446 else if (!strcmp(name, "hash")) {
447 CONFIG_IS_DOUBLE(tmp->hash);
448 tmp->hash = strdup((char *) val);
450 else if (!strcmp(name, "maclength")) {
451 tmp->mac_length = *(int *)val;
454 return SILC_CONFIG_EINTERNAL;
455 return SILC_CONFIG_OK;
458 silc_free(tmp->name);
459 silc_free(tmp->hash);
465 SILC_CONFIG_CALLBACK(fetch_pkcs)
467 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
469 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
470 type, name, context));
471 if (type == SILC_CONFIG_ARG_BLOCK) {
472 /* Check the temporary struct's fields */
473 if (!tmp) /* discard empty sub-blocks */
474 return SILC_CONFIG_OK;
476 got_errno = SILC_CONFIG_EMISSFIELDS;
480 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
482 return SILC_CONFIG_OK;
484 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
486 /* Identify and save this value */
487 if (!strcmp(name, "name")) {
488 CONFIG_IS_DOUBLE(tmp->name);
489 tmp->name = strdup((char *) val);
492 return SILC_CONFIG_EINTERNAL;
493 return SILC_CONFIG_OK;
496 silc_free(tmp->name);
502 SILC_CONFIG_CALLBACK(fetch_serverinfo)
504 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
505 SilcServerConfigServerInfo *server_info = config->server_info;
507 SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)",
508 type, name, context));
510 /* If there isn't the main struct alloc it */
512 config->server_info = server_info = (SilcServerConfigServerInfo *)
513 silc_calloc(1, sizeof(*server_info));
515 if (type == SILC_CONFIG_ARG_BLOCK) {
516 if (!strcmp(name, "primary")) {
517 if (server_info->primary) {
518 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
519 "Double primary specification."));
520 got_errno = SILC_CONFIG_EPRINTLINE;
523 CONFIG_IS_DOUBLE(server_info->primary);
525 /* now check the temporary struct, don't accept empty block and
526 make sure all fields are there */
527 if (!tmp || !tmp->server_ip || !tmp->port) {
528 got_errno = SILC_CONFIG_EMISSFIELDS;
531 server_info->primary = tmp;
533 return SILC_CONFIG_OK;
534 } else if (!strcmp(name, "secondary")) {
536 return SILC_CONFIG_OK;
537 if (!tmp || !tmp->server_ip || !tmp->port) {
538 got_errno = SILC_CONFIG_EMISSFIELDS;
541 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
543 return SILC_CONFIG_OK;
544 } else if (!server_info->public_key || !server_info->private_key) {
545 got_errno = SILC_CONFIG_EMISSFIELDS;
548 return SILC_CONFIG_OK;
550 if (!strcmp(name, "hostname")) {
551 CONFIG_IS_DOUBLE(server_info->server_name);
552 server_info->server_name = strdup((char *) val);
554 else if (!strcmp(name, "ip")) {
555 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
556 CONFIG_IS_DOUBLE(tmp->server_ip);
557 tmp->server_ip = strdup((char *) val);
559 else if (!strcmp(name, "port")) {
560 int port = *(int *)val;
561 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
562 if ((port <= 0) || (port > 65535)) {
563 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
564 "Invalid port number!"));
565 got_errno = SILC_CONFIG_EPRINTLINE;
568 tmp->port = (SilcUInt16) port;
570 else if (!strcmp(name, "servertype")) {
571 CONFIG_IS_DOUBLE(server_info->server_type);
572 server_info->server_type = strdup((char *) val);
574 else if (!strcmp(name, "admin")) {
575 CONFIG_IS_DOUBLE(server_info->admin);
576 server_info->admin = strdup((char *) val);
578 else if (!strcmp(name, "adminemail")) {
579 CONFIG_IS_DOUBLE(server_info->email);
580 server_info->email = strdup((char *) val);
582 else if (!strcmp(name, "location")) {
583 CONFIG_IS_DOUBLE(server_info->location);
584 server_info->location = strdup((char *) val);
586 else if (!strcmp(name, "user")) {
587 CONFIG_IS_DOUBLE(server_info->user);
588 server_info->user = strdup((char *) val);
590 else if (!strcmp(name, "group")) {
591 CONFIG_IS_DOUBLE(server_info->group);
592 server_info->group = strdup((char *) val);
594 else if (!strcmp(name, "motdfile")) {
595 CONFIG_IS_DOUBLE(server_info->motd_file);
596 server_info->motd_file = strdup((char *) val);
598 else if (!strcmp(name, "pidfile")) {
599 CONFIG_IS_DOUBLE(server_info->pid_file);
600 server_info->pid_file = strdup((char *) val);
602 else if (!strcmp(name, "publickey")) {
603 char *file_tmp = (char *) val;
604 CONFIG_IS_DOUBLE(server_info->public_key);
606 /* Try to load specified file, if fail stop config parsing */
607 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
609 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
610 SILC_PKCS_FILE_BIN)) {
611 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
612 return SILC_CONFIG_EPRINTLINE;
615 else if (!strcmp(name, "privatekey")) {
617 char *file_tmp = (char *) val;
618 CONFIG_IS_DOUBLE(server_info->private_key);
620 /* Check the private key file permissions. */
621 if ((stat(file_tmp, &st)) != -1) {
622 if ((st.st_mode & 0777) != 0600) {
623 SILC_SERVER_LOG_ERROR(("Wrong permissions in private key "
624 "file \"%s\". The permissions must be "
626 return SILC_CONFIG_ESILENT;
630 /* Try to load specified file, if fail stop config parsing */
631 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
632 "", 0, SILC_PKCS_FILE_BIN))
633 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
634 "", 0, SILC_PKCS_FILE_PEM)) {
635 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
636 return SILC_CONFIG_EPRINTLINE;
640 return SILC_CONFIG_EINTERNAL;
641 return SILC_CONFIG_OK;
644 /* Here we need to check if tmp exists because this function handles
645 * misc data (multiple fields and single-only fields) */
647 silc_free(tmp->server_ip);
654 SILC_CONFIG_CALLBACK(fetch_logging)
656 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
658 if (!strcmp(name, "timestamp")) {
659 config->logging_timestamp = *(bool *)val;
661 else if (!strcmp(name, "quicklogs")) {
662 config->logging_quick = *(bool *)val;
664 else if (!strcmp(name, "flushdelay")) {
665 int flushdelay = *(int *)val;
666 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
667 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
668 "Invalid flushdelay value, use quicklogs if you "
669 "want real-time logging."));
670 return SILC_CONFIG_EPRINTLINE;
672 config->logging_flushdelay = (long) flushdelay;
675 /* The following istances happens only in Logging's sub-blocks, a match
676 for the sub-block name means that you should store the filename/maxsize
677 temporary struct to the proper logging channel.
678 If we get a match for "file" or "maxsize" this means that we are inside
679 a sub-sub-block and it is safe to alloc a new tmp. */
680 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
681 else if (!strcmp(name, __chan__)) { \
682 if (!tmp) return SILC_CONFIG_OK; \
684 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
686 config->__member__ = tmp; \
687 config->tmp = NULL; \
689 FETCH_LOGGING_CHAN("info", logging_info)
690 FETCH_LOGGING_CHAN("warnings", logging_warnings)
691 FETCH_LOGGING_CHAN("errors", logging_errors)
692 FETCH_LOGGING_CHAN("fatals", logging_fatals)
693 #undef FETCH_LOGGING_CHAN
694 else if (!strcmp(name, "file")) {
695 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
696 CONFIG_IS_DOUBLE(tmp->file);
697 tmp->file = strdup((char *) val);
699 else if (!strcmp(name, "size")) {
701 config->tmp = silc_calloc(1, sizeof(*tmp));
702 tmp = (SilcServerConfigLogging *) config->tmp;
704 tmp->maxsize = *(SilcUInt32 *) val;
707 return SILC_CONFIG_EINTERNAL;
708 return SILC_CONFIG_OK;
711 silc_free(tmp->file);
717 SILC_CONFIG_CALLBACK(fetch_connparam)
719 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
721 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
722 type, name, context));
723 if (type == SILC_CONFIG_ARG_BLOCK) {
724 /* check the temporary struct's fields */
725 if (!tmp) /* discard empty sub-blocks */
726 return SILC_CONFIG_OK;
728 got_errno = SILC_CONFIG_EMISSFIELDS;
732 my_set_param_defaults(tmp, &config->param);
734 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
736 return SILC_CONFIG_OK;
739 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
740 tmp->reconnect_keep_trying = TRUE;
743 if (!strcmp(name, "name")) {
744 CONFIG_IS_DOUBLE(tmp->name);
745 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
747 else if (!strcmp(name, "connections_max")) {
748 tmp->connections_max = *(SilcUInt32 *)val;
750 else if (!strcmp(name, "connections_max_per_host")) {
751 tmp->connections_max_per_host = *(SilcUInt32 *)val;
753 else if (!strcmp(name, "keepalive_secs")) {
754 tmp->keepalive_secs = *(SilcUInt32 *)val;
756 else if (!strcmp(name, "reconnect_count")) {
757 tmp->reconnect_count = *(SilcUInt32 *)val;
759 else if (!strcmp(name, "reconnect_interval")) {
760 tmp->reconnect_interval = *(SilcUInt32 *)val;
762 else if (!strcmp(name, "reconnect_interval_max")) {
763 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
765 else if (!strcmp(name, "reconnect_keep_trying")) {
766 tmp->reconnect_keep_trying = *(bool *)val;
768 else if (!strcmp(name, "key_exchange_rekey")) {
769 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
771 else if (!strcmp(name, "key_exchange_pfs")) {
772 tmp->key_exchange_pfs = *(bool *)val;
774 else if (!strcmp(name, "version_protocol")) {
775 CONFIG_IS_DOUBLE(tmp->version_protocol);
776 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
778 else if (!strcmp(name, "version_software")) {
779 CONFIG_IS_DOUBLE(tmp->version_software);
780 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
782 else if (!strcmp(name, "version_software_vendor")) {
783 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
784 tmp->version_software_vendor =
785 (*(char *)val ? strdup((char *) val) : NULL);
787 else if (!strcmp(name, "anonymous")) {
788 tmp->anonymous = *(bool *)val;
790 else if (!strcmp(name, "qos")) {
791 tmp->qos = *(bool *)val;
793 else if (!strcmp(name, "qos_rate_limit")) {
794 tmp->qos_rate_limit = *(SilcUInt32 *)val;
796 else if (!strcmp(name, "qos_bytes_limit")) {
797 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
799 else if (!strcmp(name, "qos_limit_sec")) {
800 tmp->qos_limit_sec = *(SilcUInt32 *)val;
802 else if (!strcmp(name, "qos_limit_usec")) {
803 tmp->qos_limit_usec = *(SilcUInt32 *)val;
806 return SILC_CONFIG_EINTERNAL;
808 return SILC_CONFIG_OK;
811 silc_free(tmp->name);
817 SILC_CONFIG_CALLBACK(fetch_client)
819 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
821 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
822 type, name, context));
824 /* Alloc before block checking, because empty sub-blocks are welcome here */
825 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
827 if (type == SILC_CONFIG_ARG_BLOCK) {
828 /* empty sub-blocks are welcome */
829 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
831 return SILC_CONFIG_OK;
834 /* Identify and save this value */
835 if (!strcmp(name, "host")) {
836 CONFIG_IS_DOUBLE(tmp->host);
837 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
839 else if (!strcmp(name, "passphrase")) {
840 CONFIG_IS_DOUBLE(tmp->passphrase);
841 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
842 (void *)&tmp->passphrase,
843 &tmp->passphrase_len)) {
844 got_errno = SILC_CONFIG_EPRINTLINE;
848 else if (!strcmp(name, "publickey")) {
849 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
850 (void *)&tmp->publickeys, NULL)) {
851 got_errno = SILC_CONFIG_EPRINTLINE;
855 else if (!strcmp(name, "publickeydir")) {
856 if (!my_parse_publickeydir((char *) val, (void *)&tmp->publickeys)) {
857 got_errno = SILC_CONFIG_EPRINTLINE;
861 else if (!strcmp(name, "params")) {
862 CONFIG_IS_DOUBLE(tmp->param);
863 tmp->param = my_find_param(config, (char *) val);
864 if (!tmp->param) { /* error message already output */
865 got_errno = SILC_CONFIG_EPRINTLINE;
870 return SILC_CONFIG_EINTERNAL;
871 return SILC_CONFIG_OK;
874 silc_free(tmp->host);
875 CONFIG_FREE_AUTH(tmp);
881 SILC_CONFIG_CALLBACK(fetch_admin)
883 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
885 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
886 type, name, context));
887 if (type == SILC_CONFIG_ARG_BLOCK) {
888 /* check the temporary struct's fields */
889 if (!tmp) /* discard empty sub-blocks */
890 return SILC_CONFIG_OK;
892 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
894 return SILC_CONFIG_OK;
896 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
898 /* Identify and save this value */
899 if (!strcmp(name, "host")) {
900 CONFIG_IS_DOUBLE(tmp->host);
901 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
903 else if (!strcmp(name, "user")) {
904 CONFIG_IS_DOUBLE(tmp->user);
905 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
907 else if (!strcmp(name, "nick")) {
908 CONFIG_IS_DOUBLE(tmp->nick);
909 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
911 else if (!strcmp(name, "passphrase")) {
912 CONFIG_IS_DOUBLE(tmp->passphrase);
913 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
914 (void *)&tmp->passphrase,
915 &tmp->passphrase_len)) {
916 got_errno = SILC_CONFIG_EPRINTLINE;
920 else if (!strcmp(name, "publickey")) {
921 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
922 (void *)&tmp->publickeys, NULL)) {
923 got_errno = SILC_CONFIG_EPRINTLINE;
928 return SILC_CONFIG_EINTERNAL;
929 return SILC_CONFIG_OK;
932 silc_free(tmp->host);
933 silc_free(tmp->user);
934 silc_free(tmp->nick);
935 CONFIG_FREE_AUTH(tmp);
941 SILC_CONFIG_CALLBACK(fetch_deny)
943 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
945 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
946 type, name, context));
947 if (type == SILC_CONFIG_ARG_BLOCK) {
948 /* check the temporary struct's fields */
949 if (!tmp) /* discard empty sub-blocks */
950 return SILC_CONFIG_OK;
952 got_errno = SILC_CONFIG_EMISSFIELDS;
956 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
958 return SILC_CONFIG_OK;
960 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
962 /* Identify and save this value */
963 if (!strcmp(name, "host")) {
964 CONFIG_IS_DOUBLE(tmp->host);
965 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
967 else if (!strcmp(name, "reason")) {
968 CONFIG_IS_DOUBLE(tmp->reason);
969 tmp->reason = strdup((char *) val);
972 return SILC_CONFIG_EINTERNAL;
973 return SILC_CONFIG_OK;
976 silc_free(tmp->host);
977 silc_free(tmp->reason);
983 SILC_CONFIG_CALLBACK(fetch_server)
985 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
987 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
988 type, name, context));
989 if (type == SILC_CONFIG_ARG_BLOCK) {
990 /* check the temporary struct's fields */
991 if (!tmp) /* discard empty sub-blocks */
992 return SILC_CONFIG_OK;
994 got_errno = SILC_CONFIG_EMISSFIELDS;
998 /* the temporary struct is ok, append it to the list */
999 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
1001 return SILC_CONFIG_OK;
1003 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1005 /* Identify and save this value */
1006 if (!strcmp(name, "host")) {
1007 CONFIG_IS_DOUBLE(tmp->host);
1008 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1010 else if (!strcmp(name, "passphrase")) {
1011 CONFIG_IS_DOUBLE(tmp->passphrase);
1012 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1013 (void *)&tmp->passphrase,
1014 &tmp->passphrase_len)) {
1015 got_errno = SILC_CONFIG_EPRINTLINE;
1019 else if (!strcmp(name, "publickey")) {
1020 CONFIG_IS_DOUBLE(tmp->publickeys);
1021 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1022 (void *)&tmp->publickeys, NULL)) {
1023 got_errno = SILC_CONFIG_EPRINTLINE;
1027 else if (!strcmp(name, "params")) {
1028 CONFIG_IS_DOUBLE(tmp->param);
1029 tmp->param = my_find_param(config, (char *) val);
1030 if (!tmp->param) { /* error message already output */
1031 got_errno = SILC_CONFIG_EPRINTLINE;
1035 else if (!strcmp(name, "backup")) {
1036 tmp->backup_router = *(bool *)val;
1039 return SILC_CONFIG_EINTERNAL;
1041 return SILC_CONFIG_OK;
1044 silc_free(tmp->host);
1045 CONFIG_FREE_AUTH(tmp);
1051 SILC_CONFIG_CALLBACK(fetch_router)
1053 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1055 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1056 type, name, context));
1057 if (type == SILC_CONFIG_ARG_BLOCK) {
1058 if (!tmp) /* discard empty sub-blocks */
1059 return SILC_CONFIG_OK;
1061 got_errno = SILC_CONFIG_EMISSFIELDS;
1065 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1067 return SILC_CONFIG_OK;
1069 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1071 /* Identify and save this value */
1072 if (!strcmp(name, "host")) {
1073 CONFIG_IS_DOUBLE(tmp->host);
1074 tmp->host = strdup((char *) val);
1076 else if (!strcmp(name, "port")) {
1077 int port = *(int *)val;
1078 if ((port <= 0) || (port > 65535)) {
1079 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1080 "Invalid port number!"));
1081 got_errno = SILC_CONFIG_EPRINTLINE;
1084 tmp->port = (SilcUInt16) port;
1086 else if (!strcmp(name, "passphrase")) {
1087 CONFIG_IS_DOUBLE(tmp->passphrase);
1088 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1089 (void *)&tmp->passphrase,
1090 &tmp->passphrase_len)) {
1091 got_errno = SILC_CONFIG_EPRINTLINE;
1095 else if (!strcmp(name, "publickey")) {
1096 CONFIG_IS_DOUBLE(tmp->publickeys);
1097 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1098 (void *)&tmp->publickeys, NULL)) {
1099 got_errno = SILC_CONFIG_EPRINTLINE;
1103 else if (!strcmp(name, "params")) {
1104 CONFIG_IS_DOUBLE(tmp->param);
1105 tmp->param = my_find_param(config, (char *) val);
1106 if (!tmp->param) { /* error message already output */
1107 got_errno = SILC_CONFIG_EPRINTLINE;
1111 else if (!strcmp(name, "initiator")) {
1112 tmp->initiator = *(bool *)val;
1114 else if (!strcmp(name, "backuphost")) {
1115 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1116 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1118 tmp->backup_router = TRUE;
1120 else if (!strcmp(name, "backupport")) {
1121 int port = *(int *)val;
1122 if ((port <= 0) || (port > 65535)) {
1123 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1124 "Invalid port number!"));
1125 got_errno = SILC_CONFIG_EPRINTLINE;
1128 tmp->backup_replace_port = (SilcUInt16) port;
1130 else if (!strcmp(name, "backuplocal")) {
1131 tmp->backup_local = *(bool *)val;
1134 return SILC_CONFIG_EINTERNAL;
1136 return SILC_CONFIG_OK;
1139 silc_free(tmp->host);
1140 silc_free(tmp->backup_replace_ip);
1141 CONFIG_FREE_AUTH(tmp);
1147 /* known config options tables */
1148 static const SilcConfigTable table_general[] = {
1149 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1150 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1151 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1152 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1153 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1154 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1155 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1156 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1157 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1158 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1159 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1160 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1161 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1162 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1163 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1164 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1165 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1166 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1167 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1168 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1169 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1170 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1171 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1172 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1173 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1174 { "channel_join_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1175 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1179 static const SilcConfigTable table_cipher[] = {
1180 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1181 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1182 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1183 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1187 static const SilcConfigTable table_hash[] = {
1188 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1189 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1190 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1191 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1195 static const SilcConfigTable table_hmac[] = {
1196 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1197 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1198 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1202 static const SilcConfigTable table_pkcs[] = {
1203 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1207 static const SilcConfigTable table_serverinfo_c[] = {
1208 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1209 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1213 static const SilcConfigTable table_serverinfo[] = {
1214 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1215 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1216 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1217 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1218 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1219 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1220 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1221 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1222 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1223 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1224 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1225 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1226 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1230 static const SilcConfigTable table_logging_c[] = {
1231 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1232 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1233 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1237 static const SilcConfigTable table_logging[] = {
1238 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1239 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1240 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1241 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1242 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1243 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1244 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1248 static const SilcConfigTable table_connparam[] = {
1249 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1250 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1251 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1252 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1253 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1254 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1255 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1256 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1257 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1258 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1259 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1260 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1261 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1262 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1263 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1264 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1265 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1266 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1267 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1268 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1272 static const SilcConfigTable table_client[] = {
1273 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1274 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1275 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1276 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1277 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1281 static const SilcConfigTable table_admin[] = {
1282 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1283 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1284 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1285 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1286 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1287 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1288 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1292 static const SilcConfigTable table_deny[] = {
1293 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1294 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1298 static const SilcConfigTable table_serverconn[] = {
1299 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1300 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1301 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1302 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1303 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1307 static const SilcConfigTable table_routerconn[] = {
1308 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1309 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1310 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1311 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1312 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1313 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1314 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1315 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1316 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1320 static const SilcConfigTable table_main[] = {
1321 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1322 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1323 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1324 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1325 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1326 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1327 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1328 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1329 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1330 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1331 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1332 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1333 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1337 /* Set default values to stuff that was not configured. */
1339 static void silc_server_config_set_defaults(SilcServerConfig config)
1341 my_set_param_defaults(&config->param, NULL);
1343 config->channel_rekey_secs = (config->channel_rekey_secs ?
1344 config->channel_rekey_secs :
1345 SILC_SERVER_CHANNEL_REKEY);
1346 config->key_exchange_timeout = (config->key_exchange_timeout ?
1347 config->key_exchange_timeout :
1348 SILC_SERVER_SKE_TIMEOUT);
1349 config->conn_auth_timeout = (config->conn_auth_timeout ?
1350 config->conn_auth_timeout :
1351 SILC_SERVER_CONNAUTH_TIMEOUT);
1354 /* Check for correctness of the configuration */
1356 static bool silc_server_config_check(SilcServerConfig config)
1359 SilcServerConfigServer *s;
1360 SilcServerConfigRouter *r;
1363 /* ServerConfig is mandatory */
1364 if (!config->server_info) {
1365 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1369 /* RouterConnection sanity checks */
1371 if (config->routers && config->routers->backup_router == TRUE &&
1373 SILC_SERVER_LOG_ERROR((
1374 "\nError: First RouterConnection block must be primary router "
1375 "connection. You have marked it incorrectly as backup router."));
1379 if (config->routers && config->routers->initiator == FALSE &&
1380 config->routers->backup_router == FALSE) {
1381 SILC_SERVER_LOG_ERROR((
1382 "\nError: First RouterConnection block must be primary router "
1383 "connection and it must be marked as Initiator."));
1387 if (config->routers && config->routers->backup_router == TRUE &&
1388 !config->servers && !config->routers->next) {
1389 SILC_SERVER_LOG_ERROR((
1390 "\nError: You have configured backup router but not primary router. "
1391 "If backup router is configured also primary router must be "
1396 /* Backup router sanity checks */
1398 for (r = config->routers; r; r = r->next) {
1399 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1400 SILC_SERVER_LOG_ERROR((
1401 "\nError: Backup router connection incorrectly configured to use "
1402 "primary and backup router as same host `%s'. They must not be "
1403 "same host.", r->host));
1407 if (r->initiator == FALSE && r->port != 0) {
1408 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1409 "specified. Ignoring Port value."));
1414 /* ServerConnection sanity checks */
1416 for (s = config->servers; s; s = s->next) {
1417 if (s->backup_router) {
1423 for (s = config->servers; s; s = s->next) {
1424 if (!s->backup_router) {
1425 SILC_SERVER_LOG_ERROR((
1426 "\nError: Your server is backup router but not all ServerConnection "
1427 "blocks were marked as backup connections. They all must be "
1428 "marked as backup connections."));
1438 /* Allocates a new configuration object, opens configuration file and
1439 parses it. The parsed data is returned to the newly allocated
1440 configuration object. The SilcServerConfig must be freed by calling
1441 the silc_server_config_destroy function. */
1443 SilcServerConfig silc_server_config_alloc(const char *filename)
1445 SilcServerConfig config_new;
1446 SilcConfigEntity ent;
1447 SilcConfigFile *file;
1449 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1451 /* alloc a config object */
1452 config_new = silc_calloc(1, sizeof(*config_new));
1456 /* general config defaults */
1457 config_new->refcount = 1;
1458 config_new->logging_timestamp = TRUE;
1459 config_new->param.reconnect_keep_trying = TRUE;
1461 /* obtain a config file object */
1462 file = silc_config_open(filename);
1464 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1469 /* obtain a SilcConfig entity, we can use it to start the parsing */
1470 ent = silc_config_init(file);
1472 /* load the known configuration options, give our empty object as context */
1473 silc_config_register_table(ent, table_main, (void *) config_new);
1475 /* enter the main parsing loop. When this returns, we have the parsing
1476 * result and the object filled (or partially, in case of errors). */
1477 ret = silc_config_main(ent);
1478 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1479 silc_config_strerror(ret)));
1481 /* Check if the parser returned errors */
1483 /* handle this special error return which asks to quietly return */
1484 if (ret != SILC_CONFIG_ESILENT) {
1485 char *linebuf, *filename = silc_config_get_filename(file);
1486 SilcUInt32 line = silc_config_get_line(file);
1487 if (ret != SILC_CONFIG_EPRINTLINE)
1488 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1489 silc_config_strerror(ret)));
1490 linebuf = silc_config_read_line(file, line);
1492 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1497 silc_server_config_destroy(config_new);
1498 silc_config_close(file);
1502 /* close (destroy) the file object */
1503 silc_config_close(file);
1505 /* Check the configuration */
1506 if (!silc_server_config_check(config_new)) {
1507 silc_server_config_destroy(config_new);
1511 /* Set default to configuration parameters */
1512 silc_server_config_set_defaults(config_new);
1517 /* Increments the reference counter of a config object */
1519 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1524 ref->config = config;
1525 ref->ref_ptr = ref_ptr;
1526 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1527 config->refcount - 1, config->refcount));
1531 /* Decrements the reference counter of a config object. If the counter
1532 reaches 0, the config object is destroyed. */
1534 void silc_server_config_unref(SilcServerConfigRef *ref)
1537 silc_server_config_destroy(ref->config);
1540 /* Destroy a config object with all his children lists */
1542 void silc_server_config_destroy(SilcServerConfig config)
1547 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1548 config->refcount + 1, config->refcount));
1549 if (config->refcount > 0)
1552 SILC_LOG_DEBUG(("Freeing config context"));
1554 /* Destroy general config stuff */
1555 silc_free(config->module_path);
1556 silc_free(config->debug_string);
1557 silc_free(config->param.version_protocol);
1558 silc_free(config->param.version_software);
1559 silc_free(config->param.version_software_vendor);
1561 /* Destroy Logging channels */
1562 if (config->logging_info)
1563 silc_free(config->logging_info->file);
1564 if (config->logging_warnings)
1565 silc_free(config->logging_warnings->file);
1566 if (config->logging_errors)
1567 silc_free(config->logging_errors->file);
1568 if (config->logging_fatals)
1569 silc_free(config->logging_fatals->file);
1570 silc_free(config->logging_info);
1571 silc_free(config->logging_warnings);
1572 silc_free(config->logging_errors);
1573 silc_free(config->logging_fatals);
1575 /* Destroy the ServerInfo struct */
1576 if (config->server_info) {
1577 register SilcServerConfigServerInfo *si = config->server_info;
1578 silc_free(si->server_name);
1580 silc_free(si->primary->server_ip);
1581 silc_free(si->primary);
1583 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1585 silc_free(di->server_ip);
1588 silc_free(si->server_type);
1589 silc_free(si->location);
1590 silc_free(si->admin);
1591 silc_free(si->email);
1592 silc_free(si->user);
1593 silc_free(si->group);
1594 silc_free(si->motd_file);
1595 silc_free(si->pid_file);
1596 silc_pkcs_public_key_free(si->public_key);
1597 silc_pkcs_private_key_free(si->private_key);
1601 /* Now let's destroy the lists */
1603 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1605 silc_free(di->name);
1606 silc_free(di->module);
1609 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1610 silc_free(di->name);
1611 silc_free(di->module);
1614 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1615 silc_free(di->name);
1616 silc_free(di->hash);
1619 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1620 silc_free(di->name);
1623 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1624 config->conn_params)
1625 silc_free(di->name);
1626 silc_free(di->version_protocol);
1627 silc_free(di->version_software);
1628 silc_free(di->version_software_vendor);
1631 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1632 silc_free(di->host);
1633 CONFIG_FREE_AUTH(di);
1636 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1637 silc_free(di->host);
1638 silc_free(di->user);
1639 silc_free(di->nick);
1640 CONFIG_FREE_AUTH(di);
1643 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1644 silc_free(di->host);
1645 silc_free(di->reason);
1648 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1650 silc_free(di->host);
1651 CONFIG_FREE_AUTH(di);
1654 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1656 silc_free(di->host);
1657 silc_free(di->backup_replace_ip);
1658 CONFIG_FREE_AUTH(di);
1662 memset(config, 'F', sizeof(*config));
1666 /* Registers configured ciphers. These can then be allocated by the
1667 server when needed. */
1669 bool silc_server_config_register_ciphers(SilcServer server)
1671 SilcServerConfig config = server->config;
1672 SilcServerConfigCipher *cipher = config->cipher;
1673 char *module_path = config->module_path;
1675 SILC_LOG_DEBUG(("Registering configured ciphers"));
1677 if (!cipher) /* any cipher in the config file? */
1681 /* if there isn't a module_path OR there isn't a module sim name try to
1682 * use buil-in functions */
1683 if (!module_path || !cipher->module) {
1685 for (i = 0; silc_default_ciphers[i].name; i++)
1686 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1687 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1690 if (!silc_cipher_is_supported(cipher->name)) {
1691 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1692 silc_server_stop(server);
1697 /* Load (try at least) the crypto SIM module */
1698 char buf[1023], *alg_name;
1699 SilcCipherObject cipher_obj;
1702 memset(&cipher_obj, 0, sizeof(cipher_obj));
1703 cipher_obj.name = cipher->name;
1704 cipher_obj.block_len = cipher->block_length;
1705 cipher_obj.key_len = cipher->key_length * 8;
1707 /* build the libname */
1708 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1710 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1712 alg_name = strdup(cipher->name);
1713 if (strchr(alg_name, '-'))
1714 *strchr(alg_name, '-') = '\0';
1716 if (silc_sim_load(sim)) {
1717 cipher_obj.set_key =
1718 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1719 SILC_CIPHER_SIM_SET_KEY));
1720 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1721 cipher_obj.set_key_with_string =
1722 silc_sim_getsym(sim,
1723 silc_sim_symname(alg_name,
1724 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1725 SILC_LOG_DEBUG(("set_key_with_string=%p",
1726 cipher_obj.set_key_with_string));
1727 cipher_obj.encrypt =
1728 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1729 SILC_CIPHER_SIM_ENCRYPT_CBC));
1730 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1731 cipher_obj.decrypt =
1732 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1733 SILC_CIPHER_SIM_DECRYPT_CBC));
1734 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1735 cipher_obj.context_len =
1736 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1737 SILC_CIPHER_SIM_CONTEXT_LEN));
1738 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1740 /* Put the SIM to the list of all SIM's in server */
1741 silc_dlist_add(server->sim, sim);
1743 silc_free(alg_name);
1745 SILC_LOG_ERROR(("Error configuring ciphers"));
1747 silc_server_stop(server);
1751 /* Register the cipher */
1752 silc_cipher_register(&cipher_obj);
1754 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1755 "can't load modules!"));
1756 silc_server_stop(server);
1760 cipher = cipher->next;
1766 /* Registers configured hash functions. These can then be allocated by the
1767 server when needed. */
1769 bool silc_server_config_register_hashfuncs(SilcServer server)
1771 SilcServerConfig config = server->config;
1772 SilcServerConfigHash *hash = config->hash;
1773 char *module_path = config->module_path;
1775 SILC_LOG_DEBUG(("Registering configured hash functions"));
1777 if (!hash) /* any hash func in the config file? */
1781 /* if there isn't a module_path OR there isn't a module sim name try to
1782 * use buil-in functions */
1783 if (!module_path || !hash->module) {
1785 for (i = 0; silc_default_hash[i].name; i++)
1786 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1787 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1790 if (!silc_hash_is_supported(hash->name)) {
1791 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1792 silc_server_stop(server);
1797 /* Load (try at least) the hash SIM module */
1798 SilcHashObject hash_obj;
1801 memset(&hash_obj, 0, sizeof(hash_obj));
1802 hash_obj.name = hash->name;
1803 hash_obj.block_len = hash->block_length;
1804 hash_obj.hash_len = hash->digest_length;
1806 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1808 if ((silc_sim_load(sim))) {
1810 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1811 SILC_HASH_SIM_INIT));
1812 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1814 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1815 SILC_HASH_SIM_UPDATE));
1816 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1818 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1819 SILC_HASH_SIM_FINAL));
1820 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1821 hash_obj.context_len =
1822 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1823 SILC_HASH_SIM_CONTEXT_LEN));
1824 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1826 /* Put the SIM to the table of all SIM's in server */
1827 silc_dlist_add(server->sim, sim);
1829 SILC_LOG_ERROR(("Error configuring hash functions"));
1831 silc_server_stop(server);
1835 /* Register the hash function */
1836 silc_hash_register(&hash_obj);
1838 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1839 "can't load modules!"));
1840 silc_server_stop(server);
1850 /* Registers configure HMACs. These can then be allocated by the server
1853 bool silc_server_config_register_hmacs(SilcServer server)
1855 SilcServerConfig config = server->config;
1856 SilcServerConfigHmac *hmac = config->hmac;
1858 SILC_LOG_DEBUG(("Registering configured HMACs"));
1864 SilcHmacObject hmac_obj;
1865 if (!silc_hash_is_supported(hmac->hash)) {
1866 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1867 silc_server_stop(server);
1871 /* Register the HMAC */
1872 memset(&hmac_obj, 0, sizeof(hmac_obj));
1873 hmac_obj.name = hmac->name;
1874 hmac_obj.len = hmac->mac_length;
1875 silc_hmac_register(&hmac_obj);
1883 /* Registers configured PKCS's. */
1885 bool silc_server_config_register_pkcs(SilcServer server)
1887 SilcServerConfig config = server->config;
1888 SilcServerConfigPkcs *pkcs = config->pkcs;
1890 SILC_LOG_DEBUG(("Registering configured PKCS"));
1897 for (i = 0; silc_default_pkcs[i].name; i++)
1898 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1899 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1902 if (!silc_pkcs_is_supported(pkcs->name)) {
1903 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1904 silc_server_stop(server);
1913 /* Sets log files where log messages are saved by the server logger. */
1915 void silc_server_config_setlogfiles(SilcServer server)
1917 SilcServerConfig config = server->config;
1918 SilcServerConfigLogging *this;
1920 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1922 silc_log_timestamp(config->logging_timestamp);
1923 silc_log_quick(config->logging_quick);
1924 silc_log_flushdelay(config->logging_flushdelay ?
1925 config->logging_flushdelay :
1926 SILC_SERVER_LOG_FLUSH_DELAY);
1928 if ((this = config->logging_fatals))
1929 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1931 if ((this = config->logging_errors))
1932 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1934 if ((this = config->logging_warnings))
1935 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1937 if ((this = config->logging_info))
1938 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1942 /* Returns client authentication information from configuration file by host
1945 SilcServerConfigClient *
1946 silc_server_config_find_client(SilcServer server, char *host)
1948 SilcServerConfig config = server->config;
1949 SilcServerConfigClient *client;
1951 if (!config || !host)
1954 for (client = config->clients; client; client = client->next) {
1955 if (client->host && !silc_string_compare(client->host, host))
1960 /* if none matched, then client is already NULL */
1964 /* Returns admin connection configuration by host, username and/or
1967 SilcServerConfigAdmin *
1968 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1971 SilcServerConfig config = server->config;
1972 SilcServerConfigAdmin *admin;
1974 /* make sure we have a value for the matching parameters */
1982 for (admin = config->admins; admin; admin = admin->next) {
1983 if (admin->host && !silc_string_compare(admin->host, host))
1985 if (admin->user && !silc_string_compare(admin->user, user))
1987 if (admin->nick && !silc_string_compare(admin->nick, nick))
1989 /* no checks failed -> this entry matches */
1993 /* if none matched, then admin is already NULL */
1997 /* Returns the denied connection configuration entry by host. */
1999 SilcServerConfigDeny *
2000 silc_server_config_find_denied(SilcServer server, char *host)
2002 SilcServerConfig config = server->config;
2003 SilcServerConfigDeny *deny;
2005 /* make sure we have a value for the matching parameters */
2006 if (!config || !host)
2009 for (deny = config->denied; deny; deny = deny->next) {
2010 if (deny->host && !silc_string_compare(deny->host, host))
2015 /* if none matched, then deny is already NULL */
2019 /* Returns server connection info from server configuartion by host
2022 SilcServerConfigServer *
2023 silc_server_config_find_server_conn(SilcServer server, char *host)
2025 SilcServerConfig config = server->config;
2026 SilcServerConfigServer *serv = NULL;
2031 if (!config->servers)
2034 for (serv = config->servers; serv; serv = serv->next) {
2035 if (!silc_string_compare(serv->host, host))
2043 /* Returns router connection info from server configuration by
2044 host (name or ip). */
2046 SilcServerConfigRouter *
2047 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
2049 SilcServerConfig config = server->config;
2050 SilcServerConfigRouter *serv = NULL;
2055 if (!config->routers)
2058 for (serv = config->routers; serv; serv = serv->next) {
2059 if (!silc_string_compare(serv->host, host))
2061 if (port && serv->port && serv->port != port)
2069 /* Find backup router connection by host (name or ip) */
2071 SilcServerConfigRouter *
2072 silc_server_config_find_backup_conn(SilcServer server, char *host)
2074 SilcServerConfig config = server->config;
2075 SilcServerConfigRouter *serv = NULL;
2080 if (!config->routers)
2083 for (serv = config->routers; serv; serv = serv->next) {
2084 if (!serv->backup_router)
2086 if (!silc_string_compare(serv->host, host))
2094 /* Returns TRUE if configuration for a router connection that we are
2095 initiating exists. */
2097 bool silc_server_config_is_primary_route(SilcServer server)
2099 SilcServerConfig config = server->config;
2100 SilcServerConfigRouter *serv = NULL;
2104 serv = config->routers;
2105 for (i = 0; serv; i++) {
2106 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2117 /* Returns our primary connection configuration or NULL if we do not
2118 have primary router configured. */
2120 SilcServerConfigRouter *
2121 silc_server_config_get_primary_router(SilcServer server)
2123 SilcServerConfig config = server->config;
2124 SilcServerConfigRouter *serv = NULL;
2127 serv = config->routers;
2128 for (i = 0; serv; i++) {
2129 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2137 /* If we have backup router configured that is going to replace us this
2138 function returns it. */
2140 SilcServerConfigRouter *
2141 silc_server_config_get_backup_router(SilcServer server)
2143 SilcServerConfig config = server->config;
2144 SilcServerConfigRouter *serv = NULL;
2147 if (server->server_type != SILC_ROUTER)
2150 serv = config->routers;
2151 for (i = 0; serv; i++) {
2152 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2153 serv->backup_local == TRUE &&
2154 !strcmp(server->config->server_info->primary->server_ip,
2155 serv->backup_replace_ip) &&
2156 server->config->server_info->primary->port ==
2157 serv->backup_replace_port)