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;
925 return SILC_CONFIG_EINTERNAL;
926 return SILC_CONFIG_OK;
929 silc_free(tmp->host);
930 silc_free(tmp->user);
931 silc_free(tmp->nick);
932 CONFIG_FREE_AUTH(tmp);
938 SILC_CONFIG_CALLBACK(fetch_deny)
940 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
942 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
943 type, name, context));
944 if (type == SILC_CONFIG_ARG_BLOCK) {
945 /* check the temporary struct's fields */
946 if (!tmp) /* discard empty sub-blocks */
947 return SILC_CONFIG_OK;
949 got_errno = SILC_CONFIG_EMISSFIELDS;
953 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
955 return SILC_CONFIG_OK;
957 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
959 /* Identify and save this value */
960 if (!strcmp(name, "host")) {
961 CONFIG_IS_DOUBLE(tmp->host);
962 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
964 else if (!strcmp(name, "reason")) {
965 CONFIG_IS_DOUBLE(tmp->reason);
966 tmp->reason = strdup((char *) val);
969 return SILC_CONFIG_EINTERNAL;
970 return SILC_CONFIG_OK;
973 silc_free(tmp->host);
974 silc_free(tmp->reason);
980 SILC_CONFIG_CALLBACK(fetch_server)
982 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
984 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
985 type, name, context));
986 if (type == SILC_CONFIG_ARG_BLOCK) {
987 /* check the temporary struct's fields */
988 if (!tmp) /* discard empty sub-blocks */
989 return SILC_CONFIG_OK;
991 got_errno = SILC_CONFIG_EMISSFIELDS;
995 /* the temporary struct is ok, append it to the list */
996 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
998 return SILC_CONFIG_OK;
1000 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
1002 /* Identify and save this value */
1003 if (!strcmp(name, "host")) {
1004 CONFIG_IS_DOUBLE(tmp->host);
1005 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
1007 else if (!strcmp(name, "passphrase")) {
1008 CONFIG_IS_DOUBLE(tmp->passphrase);
1009 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1010 (void *)&tmp->passphrase,
1011 &tmp->passphrase_len)) {
1012 got_errno = SILC_CONFIG_EPRINTLINE;
1016 else if (!strcmp(name, "publickey")) {
1017 CONFIG_IS_DOUBLE(tmp->publickeys);
1018 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1019 (void *)&tmp->publickeys, NULL)) {
1020 got_errno = SILC_CONFIG_EPRINTLINE;
1024 else if (!strcmp(name, "params")) {
1025 CONFIG_IS_DOUBLE(tmp->param);
1026 tmp->param = my_find_param(config, (char *) val);
1027 if (!tmp->param) { /* error message already output */
1028 got_errno = SILC_CONFIG_EPRINTLINE;
1032 else if (!strcmp(name, "backup")) {
1033 tmp->backup_router = *(bool *)val;
1036 return SILC_CONFIG_EINTERNAL;
1038 return SILC_CONFIG_OK;
1041 silc_free(tmp->host);
1042 CONFIG_FREE_AUTH(tmp);
1048 SILC_CONFIG_CALLBACK(fetch_router)
1050 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
1052 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
1053 type, name, context));
1054 if (type == SILC_CONFIG_ARG_BLOCK) {
1055 if (!tmp) /* discard empty sub-blocks */
1056 return SILC_CONFIG_OK;
1058 got_errno = SILC_CONFIG_EMISSFIELDS;
1062 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
1064 return SILC_CONFIG_OK;
1066 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
1068 /* Identify and save this value */
1069 if (!strcmp(name, "host")) {
1070 CONFIG_IS_DOUBLE(tmp->host);
1071 tmp->host = strdup((char *) val);
1073 else if (!strcmp(name, "port")) {
1074 int port = *(int *)val;
1075 if ((port <= 0) || (port > 65535)) {
1076 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1077 "Invalid port number!"));
1078 got_errno = SILC_CONFIG_EPRINTLINE;
1081 tmp->port = (SilcUInt16) port;
1083 else if (!strcmp(name, "passphrase")) {
1084 CONFIG_IS_DOUBLE(tmp->passphrase);
1085 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
1086 (void *)&tmp->passphrase,
1087 &tmp->passphrase_len)) {
1088 got_errno = SILC_CONFIG_EPRINTLINE;
1092 else if (!strcmp(name, "publickey")) {
1093 CONFIG_IS_DOUBLE(tmp->publickeys);
1094 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
1095 (void *)&tmp->publickeys, NULL)) {
1096 got_errno = SILC_CONFIG_EPRINTLINE;
1100 else if (!strcmp(name, "params")) {
1101 CONFIG_IS_DOUBLE(tmp->param);
1102 tmp->param = my_find_param(config, (char *) val);
1103 if (!tmp->param) { /* error message already output */
1104 got_errno = SILC_CONFIG_EPRINTLINE;
1108 else if (!strcmp(name, "initiator")) {
1109 tmp->initiator = *(bool *)val;
1111 else if (!strcmp(name, "backuphost")) {
1112 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1113 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1115 tmp->backup_router = TRUE;
1117 else if (!strcmp(name, "backupport")) {
1118 int port = *(int *)val;
1119 if ((port <= 0) || (port > 65535)) {
1120 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1121 "Invalid port number!"));
1122 got_errno = SILC_CONFIG_EPRINTLINE;
1125 tmp->backup_replace_port = (SilcUInt16) port;
1127 else if (!strcmp(name, "backuplocal")) {
1128 tmp->backup_local = *(bool *)val;
1131 return SILC_CONFIG_EINTERNAL;
1133 return SILC_CONFIG_OK;
1136 silc_free(tmp->host);
1137 silc_free(tmp->backup_replace_ip);
1138 CONFIG_FREE_AUTH(tmp);
1144 /* known config options tables */
1145 static const SilcConfigTable table_general[] = {
1146 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1147 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1148 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1149 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1150 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1151 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1152 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1153 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1154 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1155 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1156 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1157 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1158 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1159 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1160 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1161 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1162 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1163 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1164 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1165 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1166 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1167 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1168 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1169 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1170 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1171 { "debug_string", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1175 static const SilcConfigTable table_cipher[] = {
1176 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1177 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1178 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1179 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1183 static const SilcConfigTable table_hash[] = {
1184 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1185 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1186 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1187 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1191 static const SilcConfigTable table_hmac[] = {
1192 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1193 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1194 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1198 static const SilcConfigTable table_pkcs[] = {
1199 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1203 static const SilcConfigTable table_serverinfo_c[] = {
1204 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1205 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1209 static const SilcConfigTable table_serverinfo[] = {
1210 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1211 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1212 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1213 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1214 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1215 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1216 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1217 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1218 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1219 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1220 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1221 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1222 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1226 static const SilcConfigTable table_logging_c[] = {
1227 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1228 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1229 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1233 static const SilcConfigTable table_logging[] = {
1234 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1235 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1236 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1237 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1238 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1239 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1240 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1244 static const SilcConfigTable table_connparam[] = {
1245 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1246 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1247 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1248 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1249 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1250 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1251 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1252 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1253 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1254 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1255 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1256 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1257 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1258 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1259 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1260 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1261 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1262 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1263 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1264 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1268 static const SilcConfigTable table_client[] = {
1269 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1270 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1271 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1272 { "publickeydir", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1273 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1277 static const SilcConfigTable table_admin[] = {
1278 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1279 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1280 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1281 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1282 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1283 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1284 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1288 static const SilcConfigTable table_deny[] = {
1289 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1290 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1294 static const SilcConfigTable table_serverconn[] = {
1295 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1296 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1297 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1298 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1299 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1303 static const SilcConfigTable table_routerconn[] = {
1304 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1305 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1306 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1307 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1308 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1309 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1310 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1311 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1312 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1316 static const SilcConfigTable table_main[] = {
1317 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1318 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1319 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1320 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1321 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1322 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1323 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1324 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1325 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1326 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1327 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1328 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1329 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1333 /* Set default values to stuff that was not configured. */
1335 static void silc_server_config_set_defaults(SilcServerConfig config)
1337 my_set_param_defaults(&config->param, NULL);
1339 config->channel_rekey_secs = (config->channel_rekey_secs ?
1340 config->channel_rekey_secs :
1341 SILC_SERVER_CHANNEL_REKEY);
1342 config->key_exchange_timeout = (config->key_exchange_timeout ?
1343 config->key_exchange_timeout :
1344 SILC_SERVER_SKE_TIMEOUT);
1345 config->conn_auth_timeout = (config->conn_auth_timeout ?
1346 config->conn_auth_timeout :
1347 SILC_SERVER_CONNAUTH_TIMEOUT);
1350 /* Check for correctness of the configuration */
1352 static bool silc_server_config_check(SilcServerConfig config)
1355 SilcServerConfigServer *s;
1356 SilcServerConfigRouter *r;
1359 /* ServerConfig is mandatory */
1360 if (!config->server_info) {
1361 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block `ServerInfo'"));
1365 /* RouterConnection sanity checks */
1367 if (config->routers && config->routers->backup_router == TRUE &&
1369 SILC_SERVER_LOG_ERROR((
1370 "\nError: First RouterConnection block must be primary router "
1371 "connection. You have marked it incorrectly as backup router."));
1375 if (config->routers && config->routers->initiator == FALSE &&
1376 config->routers->backup_router == FALSE) {
1377 SILC_SERVER_LOG_ERROR((
1378 "\nError: First RouterConnection block must be primary router "
1379 "connection and it must be marked as Initiator."));
1383 if (config->routers && config->routers->backup_router == TRUE &&
1384 !config->servers && !config->routers->next) {
1385 SILC_SERVER_LOG_ERROR((
1386 "\nError: You have configured backup router but not primary router. "
1387 "If backup router is configured also primary router must be "
1392 /* Backup router sanity checks */
1394 for (r = config->routers; r; r = r->next) {
1395 if (r->backup_router && !strcmp(r->host, r->backup_replace_ip)) {
1396 SILC_SERVER_LOG_ERROR((
1397 "\nError: Backup router connection incorrectly configured to use "
1398 "primary and backup router as same host `%s'. They must not be "
1399 "same host.", r->host));
1403 if (r->initiator == FALSE && r->port != 0) {
1404 SILC_SERVER_LOG_WARNING(("\nWarning: Initiator is FALSE and Port is "
1405 "specified. Ignoring Port value."));
1410 /* ServerConnection sanity checks */
1412 for (s = config->servers; s; s = s->next) {
1413 if (s->backup_router) {
1419 for (s = config->servers; s; s = s->next) {
1420 if (!s->backup_router) {
1421 SILC_SERVER_LOG_ERROR((
1422 "\nError: Your server is backup router but not all ServerConnection "
1423 "blocks were marked as backup connections. They all must be "
1424 "marked as backup connections."));
1434 /* Allocates a new configuration object, opens configuration file and
1435 parses it. The parsed data is returned to the newly allocated
1436 configuration object. The SilcServerConfig must be freed by calling
1437 the silc_server_config_destroy function. */
1439 SilcServerConfig silc_server_config_alloc(const char *filename)
1441 SilcServerConfig config_new;
1442 SilcConfigEntity ent;
1443 SilcConfigFile *file;
1445 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1447 /* alloc a config object */
1448 config_new = silc_calloc(1, sizeof(*config_new));
1452 /* general config defaults */
1453 config_new->refcount = 1;
1454 config_new->logging_timestamp = TRUE;
1455 config_new->param.reconnect_keep_trying = TRUE;
1457 /* obtain a config file object */
1458 file = silc_config_open(filename);
1460 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1465 /* obtain a SilcConfig entity, we can use it to start the parsing */
1466 ent = silc_config_init(file);
1468 /* load the known configuration options, give our empty object as context */
1469 silc_config_register_table(ent, table_main, (void *) config_new);
1471 /* enter the main parsing loop. When this returns, we have the parsing
1472 * result and the object filled (or partially, in case of errors). */
1473 ret = silc_config_main(ent);
1474 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1475 silc_config_strerror(ret)));
1477 /* Check if the parser returned errors */
1479 /* handle this special error return which asks to quietly return */
1480 if (ret != SILC_CONFIG_ESILENT) {
1481 char *linebuf, *filename = silc_config_get_filename(file);
1482 SilcUInt32 line = silc_config_get_line(file);
1483 if (ret != SILC_CONFIG_EPRINTLINE)
1484 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1485 silc_config_strerror(ret)));
1486 linebuf = silc_config_read_line(file, line);
1488 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1493 silc_server_config_destroy(config_new);
1494 silc_config_close(file);
1498 /* close (destroy) the file object */
1499 silc_config_close(file);
1501 /* Check the configuration */
1502 if (!silc_server_config_check(config_new)) {
1503 silc_server_config_destroy(config_new);
1507 /* Set default to configuration parameters */
1508 silc_server_config_set_defaults(config_new);
1513 /* Increments the reference counter of a config object */
1515 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1520 ref->config = config;
1521 ref->ref_ptr = ref_ptr;
1522 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1523 config->refcount - 1, config->refcount));
1527 /* Decrements the reference counter of a config object. If the counter
1528 reaches 0, the config object is destroyed. */
1530 void silc_server_config_unref(SilcServerConfigRef *ref)
1533 silc_server_config_destroy(ref->config);
1536 /* Destroy a config object with all his children lists */
1538 void silc_server_config_destroy(SilcServerConfig config)
1543 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1544 config->refcount + 1, config->refcount));
1545 if (config->refcount > 0)
1548 SILC_LOG_DEBUG(("Freeing config context"));
1550 /* Destroy general config stuff */
1551 silc_free(config->module_path);
1552 silc_free(config->debug_string);
1553 silc_free(config->param.version_protocol);
1554 silc_free(config->param.version_software);
1555 silc_free(config->param.version_software_vendor);
1557 /* Destroy Logging channels */
1558 if (config->logging_info)
1559 silc_free(config->logging_info->file);
1560 if (config->logging_warnings)
1561 silc_free(config->logging_warnings->file);
1562 if (config->logging_errors)
1563 silc_free(config->logging_errors->file);
1564 if (config->logging_fatals)
1565 silc_free(config->logging_fatals->file);
1566 silc_free(config->logging_info);
1567 silc_free(config->logging_warnings);
1568 silc_free(config->logging_errors);
1569 silc_free(config->logging_fatals);
1571 /* Destroy the ServerInfo struct */
1572 if (config->server_info) {
1573 register SilcServerConfigServerInfo *si = config->server_info;
1574 silc_free(si->server_name);
1576 silc_free(si->primary->server_ip);
1577 silc_free(si->primary);
1579 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1581 silc_free(di->server_ip);
1584 silc_free(si->server_type);
1585 silc_free(si->location);
1586 silc_free(si->admin);
1587 silc_free(si->email);
1588 silc_free(si->user);
1589 silc_free(si->group);
1590 silc_free(si->motd_file);
1591 silc_free(si->pid_file);
1592 silc_pkcs_public_key_free(si->public_key);
1593 silc_pkcs_private_key_free(si->private_key);
1597 /* Now let's destroy the lists */
1599 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1601 silc_free(di->name);
1602 silc_free(di->module);
1605 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1606 silc_free(di->name);
1607 silc_free(di->module);
1610 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1611 silc_free(di->name);
1612 silc_free(di->hash);
1615 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1616 silc_free(di->name);
1619 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1620 config->conn_params)
1621 silc_free(di->name);
1622 silc_free(di->version_protocol);
1623 silc_free(di->version_software);
1624 silc_free(di->version_software_vendor);
1627 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1628 silc_free(di->host);
1629 CONFIG_FREE_AUTH(di);
1632 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1633 silc_free(di->host);
1634 silc_free(di->user);
1635 silc_free(di->nick);
1636 CONFIG_FREE_AUTH(di);
1639 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1640 silc_free(di->host);
1641 silc_free(di->reason);
1644 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1646 silc_free(di->host);
1647 CONFIG_FREE_AUTH(di);
1650 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1652 silc_free(di->host);
1653 silc_free(di->backup_replace_ip);
1654 CONFIG_FREE_AUTH(di);
1658 memset(config, 'F', sizeof(*config));
1662 /* Registers configured ciphers. These can then be allocated by the
1663 server when needed. */
1665 bool silc_server_config_register_ciphers(SilcServer server)
1667 SilcServerConfig config = server->config;
1668 SilcServerConfigCipher *cipher = config->cipher;
1669 char *module_path = config->module_path;
1671 SILC_LOG_DEBUG(("Registering configured ciphers"));
1673 if (!cipher) /* any cipher in the config file? */
1677 /* if there isn't a module_path OR there isn't a module sim name try to
1678 * use buil-in functions */
1679 if (!module_path || !cipher->module) {
1681 for (i = 0; silc_default_ciphers[i].name; i++)
1682 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1683 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1686 if (!silc_cipher_is_supported(cipher->name)) {
1687 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1688 silc_server_stop(server);
1693 /* Load (try at least) the crypto SIM module */
1694 char buf[1023], *alg_name;
1695 SilcCipherObject cipher_obj;
1698 memset(&cipher_obj, 0, sizeof(cipher_obj));
1699 cipher_obj.name = cipher->name;
1700 cipher_obj.block_len = cipher->block_length;
1701 cipher_obj.key_len = cipher->key_length * 8;
1703 /* build the libname */
1704 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1706 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1708 alg_name = strdup(cipher->name);
1709 if (strchr(alg_name, '-'))
1710 *strchr(alg_name, '-') = '\0';
1712 if (silc_sim_load(sim)) {
1713 cipher_obj.set_key =
1714 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1715 SILC_CIPHER_SIM_SET_KEY));
1716 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1717 cipher_obj.set_key_with_string =
1718 silc_sim_getsym(sim,
1719 silc_sim_symname(alg_name,
1720 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1721 SILC_LOG_DEBUG(("set_key_with_string=%p",
1722 cipher_obj.set_key_with_string));
1723 cipher_obj.encrypt =
1724 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1725 SILC_CIPHER_SIM_ENCRYPT_CBC));
1726 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1727 cipher_obj.decrypt =
1728 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1729 SILC_CIPHER_SIM_DECRYPT_CBC));
1730 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1731 cipher_obj.context_len =
1732 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1733 SILC_CIPHER_SIM_CONTEXT_LEN));
1734 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1736 /* Put the SIM to the list of all SIM's in server */
1737 silc_dlist_add(server->sim, sim);
1739 silc_free(alg_name);
1741 SILC_LOG_ERROR(("Error configuring ciphers"));
1743 silc_server_stop(server);
1747 /* Register the cipher */
1748 silc_cipher_register(&cipher_obj);
1750 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1751 "can't load modules!"));
1752 silc_server_stop(server);
1756 cipher = cipher->next;
1762 /* Registers configured hash functions. These can then be allocated by the
1763 server when needed. */
1765 bool silc_server_config_register_hashfuncs(SilcServer server)
1767 SilcServerConfig config = server->config;
1768 SilcServerConfigHash *hash = config->hash;
1769 char *module_path = config->module_path;
1771 SILC_LOG_DEBUG(("Registering configured hash functions"));
1773 if (!hash) /* any hash func in the config file? */
1777 /* if there isn't a module_path OR there isn't a module sim name try to
1778 * use buil-in functions */
1779 if (!module_path || !hash->module) {
1781 for (i = 0; silc_default_hash[i].name; i++)
1782 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1783 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1786 if (!silc_hash_is_supported(hash->name)) {
1787 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1788 silc_server_stop(server);
1793 /* Load (try at least) the hash SIM module */
1794 SilcHashObject hash_obj;
1797 memset(&hash_obj, 0, sizeof(hash_obj));
1798 hash_obj.name = hash->name;
1799 hash_obj.block_len = hash->block_length;
1800 hash_obj.hash_len = hash->digest_length;
1802 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1804 if ((silc_sim_load(sim))) {
1806 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1807 SILC_HASH_SIM_INIT));
1808 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1810 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1811 SILC_HASH_SIM_UPDATE));
1812 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1814 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1815 SILC_HASH_SIM_FINAL));
1816 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1817 hash_obj.context_len =
1818 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1819 SILC_HASH_SIM_CONTEXT_LEN));
1820 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1822 /* Put the SIM to the table of all SIM's in server */
1823 silc_dlist_add(server->sim, sim);
1825 SILC_LOG_ERROR(("Error configuring hash functions"));
1827 silc_server_stop(server);
1831 /* Register the hash function */
1832 silc_hash_register(&hash_obj);
1834 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1835 "can't load modules!"));
1836 silc_server_stop(server);
1846 /* Registers configure HMACs. These can then be allocated by the server
1849 bool silc_server_config_register_hmacs(SilcServer server)
1851 SilcServerConfig config = server->config;
1852 SilcServerConfigHmac *hmac = config->hmac;
1854 SILC_LOG_DEBUG(("Registering configured HMACs"));
1860 SilcHmacObject hmac_obj;
1861 if (!silc_hash_is_supported(hmac->hash)) {
1862 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1863 silc_server_stop(server);
1867 /* Register the HMAC */
1868 memset(&hmac_obj, 0, sizeof(hmac_obj));
1869 hmac_obj.name = hmac->name;
1870 hmac_obj.len = hmac->mac_length;
1871 silc_hmac_register(&hmac_obj);
1879 /* Registers configured PKCS's. */
1881 bool silc_server_config_register_pkcs(SilcServer server)
1883 SilcServerConfig config = server->config;
1884 SilcServerConfigPkcs *pkcs = config->pkcs;
1886 SILC_LOG_DEBUG(("Registering configured PKCS"));
1893 for (i = 0; silc_default_pkcs[i].name; i++)
1894 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1895 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1898 if (!silc_pkcs_is_supported(pkcs->name)) {
1899 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1900 silc_server_stop(server);
1909 /* Sets log files where log messages are saved by the server logger. */
1911 void silc_server_config_setlogfiles(SilcServer server)
1913 SilcServerConfig config = server->config;
1914 SilcServerConfigLogging *this;
1916 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1918 silc_log_timestamp = config->logging_timestamp;
1919 silc_log_quick = config->logging_quick;
1920 silc_log_flushdelay = (config->logging_flushdelay ?
1921 config->logging_flushdelay :
1922 SILC_SERVER_LOG_FLUSH_DELAY);
1924 if ((this = config->logging_fatals))
1925 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1927 if ((this = config->logging_errors))
1928 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1930 if ((this = config->logging_warnings))
1931 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1933 if ((this = config->logging_info))
1934 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1938 /* Returns client authentication information from configuration file by host
1941 SilcServerConfigClient *
1942 silc_server_config_find_client(SilcServer server, char *host)
1944 SilcServerConfig config = server->config;
1945 SilcServerConfigClient *client;
1947 if (!config || !host)
1950 for (client = config->clients; client; client = client->next) {
1951 if (client->host && !silc_string_compare(client->host, host))
1956 /* if none matched, then client is already NULL */
1960 /* Returns admin connection configuration by host, username and/or
1963 SilcServerConfigAdmin *
1964 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1967 SilcServerConfig config = server->config;
1968 SilcServerConfigAdmin *admin;
1970 /* make sure we have a value for the matching parameters */
1978 for (admin = config->admins; admin; admin = admin->next) {
1979 if (admin->host && !silc_string_compare(admin->host, host))
1981 if (admin->user && !silc_string_compare(admin->user, user))
1983 if (admin->nick && !silc_string_compare(admin->nick, nick))
1985 /* no checks failed -> this entry matches */
1989 /* if none matched, then admin is already NULL */
1993 /* Returns the denied connection configuration entry by host. */
1995 SilcServerConfigDeny *
1996 silc_server_config_find_denied(SilcServer server, char *host)
1998 SilcServerConfig config = server->config;
1999 SilcServerConfigDeny *deny;
2001 /* make sure we have a value for the matching parameters */
2002 if (!config || !host)
2005 for (deny = config->denied; deny; deny = deny->next) {
2006 if (deny->host && !silc_string_compare(deny->host, host))
2011 /* if none matched, then deny is already NULL */
2015 /* Returns server connection info from server configuartion by host
2018 SilcServerConfigServer *
2019 silc_server_config_find_server_conn(SilcServer server, char *host)
2021 SilcServerConfig config = server->config;
2022 SilcServerConfigServer *serv = NULL;
2027 if (!config->servers)
2030 for (serv = config->servers; serv; serv = serv->next) {
2031 if (!silc_string_compare(serv->host, host))
2039 /* Returns router connection info from server configuration by
2040 host (name or ip). */
2042 SilcServerConfigRouter *
2043 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
2045 SilcServerConfig config = server->config;
2046 SilcServerConfigRouter *serv = NULL;
2051 if (!config->routers)
2054 for (serv = config->routers; serv; serv = serv->next) {
2055 if (!silc_string_compare(serv->host, host))
2057 if (port && serv->port && serv->port != port)
2065 /* Find backup router connection by host (name or ip) */
2067 SilcServerConfigRouter *
2068 silc_server_config_find_backup_conn(SilcServer server, char *host)
2070 SilcServerConfig config = server->config;
2071 SilcServerConfigRouter *serv = NULL;
2076 if (!config->routers)
2079 for (serv = config->routers; serv; serv = serv->next) {
2080 if (!serv->backup_router)
2082 if (!silc_string_compare(serv->host, host))
2090 /* Returns TRUE if configuration for a router connection that we are
2091 initiating exists. */
2093 bool silc_server_config_is_primary_route(SilcServer server)
2095 SilcServerConfig config = server->config;
2096 SilcServerConfigRouter *serv = NULL;
2100 serv = config->routers;
2101 for (i = 0; serv; i++) {
2102 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
2113 /* Returns our primary connection configuration or NULL if we do not
2114 have primary router configured. */
2116 SilcServerConfigRouter *
2117 silc_server_config_get_primary_router(SilcServer server)
2119 SilcServerConfig config = server->config;
2120 SilcServerConfigRouter *serv = NULL;
2123 serv = config->routers;
2124 for (i = 0; serv; i++) {
2125 if (serv->initiator == TRUE && serv->backup_router == FALSE)
2133 /* If we have backup router configured that is going to replace us this
2134 function returns it. */
2136 SilcServerConfigRouter *
2137 silc_server_config_get_backup_router(SilcServer server)
2139 SilcServerConfig config = server->config;
2140 SilcServerConfigRouter *serv = NULL;
2143 if (server->server_type != SILC_ROUTER)
2146 serv = config->routers;
2147 for (i = 0; serv; i++) {
2148 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
2149 serv->backup_local == TRUE &&
2150 !strcmp(server->config->server_info->primary->server_ip,
2151 serv->backup_replace_ip) &&
2152 server->config->server_info->primary->port ==
2153 serv->backup_replace_port)