5 Author: Johnny Mnemonic <johnny@themnemonic.org>
7 Copyright (C) 1997 - 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "serverincludes.h"
23 #include "server_internal.h"
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);
100 #undef SET_PARAM_DEFAULT
103 /* Find connection parameters by the parameter block name. */
104 static SilcServerConfigConnParams *
105 my_find_param(SilcServerConfig config, const char *name)
107 SilcServerConfigConnParams *param;
109 for (param = config->conn_params; param; param = param->next) {
110 if (!strcasecmp(param->name, name))
114 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
115 "Cannot find Params \"%s\".", name));
120 /* parse an authdata according to its auth method */
121 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p,
122 void **auth_data, SilcUInt32 *auth_data_len)
124 if (auth_meth == SILC_AUTH_PASSWORD) {
125 /* p is a plain text password */
126 if (auth_data && auth_data_len) {
127 if (!silc_utf8_valid(p, strlen(p))) {
128 *auth_data_len = silc_utf8_encoded_len(p, strlen(p),
129 SILC_STRING_LANGUAGE);
130 *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char));
131 silc_utf8_encode(p, strlen(p), SILC_STRING_LANGUAGE, *auth_data,
134 *auth_data = (void *) strdup(p);
135 *auth_data_len = (SilcUInt32) strlen(p);
138 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
139 /* p is a public key file name */
140 SilcPublicKey public_key;
142 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
143 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
144 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
145 "Could not load public key file!"));
149 /* The auth_data is a pointer to the hash table of public keys. */
151 if (*auth_data == NULL)
152 *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL,
154 my_free_public_key, NULL,
156 silc_hash_table_add(*auth_data, public_key, public_key);
166 SILC_CONFIG_CALLBACK(fetch_generic)
168 SilcServerConfig config = (SilcServerConfig) context;
171 if (!strcmp(name, "module_path")) {
172 CONFIG_IS_DOUBLE(config->module_path);
173 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
175 else if (!strcmp(name, "prefer_passphrase_auth")) {
176 config->prefer_passphrase_auth = *(bool *)val;
178 else if (!strcmp(name, "require_reverse_lookup")) {
179 config->require_reverse_lookup = *(bool *)val;
181 else if (!strcmp(name, "connections_max")) {
182 config->param.connections_max = (SilcUInt32) *(int *)val;
184 else if (!strcmp(name, "connections_max_per_host")) {
185 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
187 else if (!strcmp(name, "keepalive_secs")) {
188 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
190 else if (!strcmp(name, "reconnect_count")) {
191 config->param.reconnect_count = (SilcUInt32) *(int *)val;
193 else if (!strcmp(name, "reconnect_interval")) {
194 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
196 else if (!strcmp(name, "reconnect_interval_max")) {
197 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
199 else if (!strcmp(name, "reconnect_keep_trying")) {
200 config->param.reconnect_keep_trying = *(bool *)val;
202 else if (!strcmp(name, "key_exchange_rekey")) {
203 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
205 else if (!strcmp(name, "key_exchange_pfs")) {
206 config->param.key_exchange_pfs = *(bool *)val;
208 else if (!strcmp(name, "channel_rekey_secs")) {
209 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
211 else if (!strcmp(name, "key_exchange_timeout")) {
212 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
214 else if (!strcmp(name, "conn_auth_timeout")) {
215 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
217 else if (!strcmp(name, "version_protocol")) {
218 CONFIG_IS_DOUBLE(config->param.version_protocol);
219 config->param.version_protocol =
220 (*(char *)val ? strdup((char *) val) : NULL);
222 else if (!strcmp(name, "version_software")) {
223 CONFIG_IS_DOUBLE(config->param.version_software);
224 config->param.version_software =
225 (*(char *)val ? strdup((char *) val) : NULL);
227 else if (!strcmp(name, "version_software_vendor")) {
228 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
229 config->param.version_software_vendor =
230 (*(char *)val ? strdup((char *) val) : NULL);
232 else if (!strcmp(name, "detach_disabled")) {
233 config->detach_disabled = *(bool *)val;
235 else if (!strcmp(name, "detach_timeout")) {
236 config->detach_timeout = (SilcUInt32) *(int *)val;
238 else if (!strcmp(name, "qos")) {
239 config->param.qos = *(bool *)val;
241 else if (!strcmp(name, "qos_rate_limit")) {
242 config->param.qos_rate_limit = *(SilcUInt32 *)val;
244 else if (!strcmp(name, "qos_bytes_limit")) {
245 config->param.qos_bytes_limit = *(SilcUInt32 *)val;
247 else if (!strcmp(name, "qos_limit_sec")) {
248 config->param.qos_limit_sec = *(SilcUInt32 *)val;
250 else if (!strcmp(name, "qos_limit_usec")) {
251 config->param.qos_limit_usec = *(SilcUInt32 *)val;
254 return SILC_CONFIG_EINTERNAL;
256 return SILC_CONFIG_OK;
262 SILC_CONFIG_CALLBACK(fetch_cipher)
264 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
266 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
267 type, name, context));
268 if (type == SILC_CONFIG_ARG_BLOCK) {
269 /* check the temporary struct's fields */
270 if (!tmp) /* discard empty sub-blocks */
271 return SILC_CONFIG_OK;
273 got_errno = SILC_CONFIG_EMISSFIELDS;
277 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
279 return SILC_CONFIG_OK;
281 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigCipher);
283 /* Identify and save this value */
284 if (!strcmp(name, "name")) {
285 CONFIG_IS_DOUBLE(tmp->name);
286 tmp->name = strdup((char *) val);
288 else if (!strcmp(name, "module")) {
289 CONFIG_IS_DOUBLE(tmp->module);
290 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
292 else if (!strcmp(name, "keylength")) {
293 tmp->key_length = *(SilcUInt32 *)val;
295 else if (!strcmp(name, "blocklength")) {
296 tmp->block_length = *(SilcUInt32 *)val;
299 return SILC_CONFIG_EINTERNAL;
300 return SILC_CONFIG_OK;
303 silc_free(tmp->name);
304 silc_free(tmp->module);
310 SILC_CONFIG_CALLBACK(fetch_hash)
312 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
314 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
315 type, name, context));
316 if (type == SILC_CONFIG_ARG_BLOCK) {
317 /* check the temporary struct's fields */
318 if (!tmp) /* discard empty sub-blocks */
319 return SILC_CONFIG_OK;
320 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
321 got_errno = SILC_CONFIG_EMISSFIELDS;
325 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
327 return SILC_CONFIG_OK;
329 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHash);
331 /* Identify and save this value */
332 if (!strcmp(name, "name")) {
333 CONFIG_IS_DOUBLE(tmp->name);
334 tmp->name = strdup((char *) val);
336 else if (!strcmp(name, "module")) {
337 CONFIG_IS_DOUBLE(tmp->module);
338 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
340 else if (!strcmp(name, "blocklength")) {
341 tmp->block_length = *(int *)val;
343 else if (!strcmp(name, "digestlength")) {
344 tmp->digest_length = *(int *)val;
347 return SILC_CONFIG_EINTERNAL;
348 return SILC_CONFIG_OK;
351 silc_free(tmp->name);
352 silc_free(tmp->module);
358 SILC_CONFIG_CALLBACK(fetch_hmac)
360 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
362 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
363 type, name, context));
364 if (type == SILC_CONFIG_ARG_BLOCK) {
365 /* check the temporary struct's fields */
366 if (!tmp) /* discard empty sub-blocks */
367 return SILC_CONFIG_OK;
368 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
369 got_errno = SILC_CONFIG_EMISSFIELDS;
373 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
375 return SILC_CONFIG_OK;
377 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigHmac);
379 /* Identify and save this value */
380 if (!strcmp(name, "name")) {
381 CONFIG_IS_DOUBLE(tmp->name);
382 tmp->name = strdup((char *) val);
384 else if (!strcmp(name, "hash")) {
385 CONFIG_IS_DOUBLE(tmp->hash);
386 tmp->hash = strdup((char *) val);
388 else if (!strcmp(name, "maclength")) {
389 tmp->mac_length = *(int *)val;
392 return SILC_CONFIG_EINTERNAL;
393 return SILC_CONFIG_OK;
396 silc_free(tmp->name);
397 silc_free(tmp->hash);
403 SILC_CONFIG_CALLBACK(fetch_pkcs)
405 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
407 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
408 type, name, context));
409 if (type == SILC_CONFIG_ARG_BLOCK) {
410 /* check the temporary struct's fields */
411 if (!tmp) /* discard empty sub-blocks */
412 return SILC_CONFIG_OK;
414 got_errno = SILC_CONFIG_EMISSFIELDS;
418 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
420 return SILC_CONFIG_OK;
422 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigPkcs);
424 /* Identify and save this value */
425 if (!strcmp(name, "name")) {
426 CONFIG_IS_DOUBLE(tmp->name);
427 tmp->name = strdup((char *) val);
430 return SILC_CONFIG_EINTERNAL;
431 return SILC_CONFIG_OK;
434 silc_free(tmp->name);
440 SILC_CONFIG_CALLBACK(fetch_serverinfo)
442 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface);
443 SilcServerConfigServerInfo *server_info = config->server_info;
445 /* if there isn't the struct alloc it */
447 config->server_info = server_info = (SilcServerConfigServerInfo *)
448 silc_calloc(1, sizeof(*server_info));
450 if (type == SILC_CONFIG_ARG_BLOCK) {
451 if (!strcmp(name, "primary")) {
452 CONFIG_IS_DOUBLE(server_info->primary);
454 return SILC_CONFIG_OK;
455 server_info->primary = tmp;
457 return SILC_CONFIG_OK;
458 } else if (!strcmp(name, "secondary")) {
460 return SILC_CONFIG_OK;
461 SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary);
463 return SILC_CONFIG_OK;
464 } else if (!server_info->public_key || !server_info->private_key) {
465 got_errno = SILC_CONFIG_EMISSFIELDS;
468 return SILC_CONFIG_OK;
470 if (!strcmp(name, "hostname")) {
471 CONFIG_IS_DOUBLE(server_info->server_name);
472 server_info->server_name = strdup((char *) val);
474 else if (!strcmp(name, "ip")) {
475 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
476 CONFIG_IS_DOUBLE(tmp->server_ip);
477 tmp->server_ip = strdup((char *) val);
479 else if (!strcmp(name, "port")) {
480 int port = *(int *)val;
481 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServerInfoInterface);
482 if ((port <= 0) || (port > 65535)) {
483 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
484 "Invalid port number!"));
485 got_errno = SILC_CONFIG_EPRINTLINE;
488 tmp->port = (SilcUInt16) port;
490 else if (!strcmp(name, "servertype")) {
491 CONFIG_IS_DOUBLE(server_info->server_type);
492 server_info->server_type = strdup((char *) val);
494 else if (!strcmp(name, "admin")) {
495 CONFIG_IS_DOUBLE(server_info->admin);
496 server_info->admin = strdup((char *) val);
498 else if (!strcmp(name, "adminemail")) {
499 CONFIG_IS_DOUBLE(server_info->email);
500 server_info->email = strdup((char *) val);
502 else if (!strcmp(name, "location")) {
503 CONFIG_IS_DOUBLE(server_info->location);
504 server_info->location = strdup((char *) val);
506 else if (!strcmp(name, "user")) {
507 CONFIG_IS_DOUBLE(server_info->user);
508 server_info->user = strdup((char *) val);
510 else if (!strcmp(name, "group")) {
511 CONFIG_IS_DOUBLE(server_info->group);
512 server_info->group = strdup((char *) val);
514 else if (!strcmp(name, "motdfile")) {
515 CONFIG_IS_DOUBLE(server_info->motd_file);
516 server_info->motd_file = strdup((char *) val);
518 else if (!strcmp(name, "pidfile")) {
519 CONFIG_IS_DOUBLE(server_info->pid_file);
520 server_info->pid_file = strdup((char *) val);
522 else if (!strcmp(name, "publickey")) {
523 char *file_tmp = (char *) val;
525 /* try to load specified file, if fail stop config parsing */
526 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
528 if (!silc_pkcs_load_public_key(file_tmp, &server_info->public_key,
529 SILC_PKCS_FILE_BIN)) {
530 SILC_SERVER_LOG_ERROR(("Error: Could not load public key file."));
531 return SILC_CONFIG_EPRINTLINE;
534 else if (!strcmp(name, "privatekey")) {
535 char *file_tmp = (char *) val;
537 /* try to load specified file, if fail stop config parsing */
538 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
540 if (!silc_pkcs_load_private_key(file_tmp, &server_info->private_key,
541 SILC_PKCS_FILE_PEM)) {
542 SILC_SERVER_LOG_ERROR(("Error: Could not load private key file."));
543 return SILC_CONFIG_EPRINTLINE;
547 return SILC_CONFIG_EINTERNAL;
548 return SILC_CONFIG_OK;
552 silc_free(config->tmp);
557 SILC_CONFIG_CALLBACK(fetch_logging)
559 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigLogging);
561 if (!strcmp(name, "timestamp")) {
562 config->logging_timestamp = *(bool *)val;
564 else if (!strcmp(name, "quicklogs")) {
565 config->logging_quick = *(bool *)val;
567 else if (!strcmp(name, "flushdelay")) {
568 int flushdelay = *(int *)val;
569 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
570 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
571 "Invalid flushdelay value, use quicklogs if you "
572 "want real-time logging."));
573 return SILC_CONFIG_EPRINTLINE;
575 config->logging_flushdelay = (long) flushdelay;
578 /* The following istances happens only in Logging's sub-blocks, a match
579 for the sub-block name means that you should store the filename/maxsize
580 temporary struct to the proper logging channel.
581 If we get a match for "file" or "maxsize" this means that we are inside
582 a sub-sub-block and it is safe to alloc a new tmp. */
583 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
584 else if (!strcmp(name, __chan__)) { \
585 if (!tmp) return SILC_CONFIG_OK; \
587 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
589 config->__member__ = tmp; \
590 config->tmp = NULL; \
592 FETCH_LOGGING_CHAN("info", logging_info)
593 FETCH_LOGGING_CHAN("warnings", logging_warnings)
594 FETCH_LOGGING_CHAN("errors", logging_errors)
595 FETCH_LOGGING_CHAN("fatals", logging_fatals)
596 #undef FETCH_LOGGING_CHAN
597 else if (!strcmp(name, "file")) {
598 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigLogging);
599 CONFIG_IS_DOUBLE(tmp->file);
600 tmp->file = strdup((char *) val);
602 else if (!strcmp(name, "size")) {
604 config->tmp = silc_calloc(1, sizeof(*tmp));
605 tmp = (SilcServerConfigLogging *) config->tmp;
607 tmp->maxsize = *(SilcUInt32 *) val;
610 return SILC_CONFIG_EINTERNAL;
611 return SILC_CONFIG_OK;
614 silc_free(tmp->file);
620 SILC_CONFIG_CALLBACK(fetch_connparam)
622 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
624 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
625 type, name, context));
626 if (type == SILC_CONFIG_ARG_BLOCK) {
627 /* check the temporary struct's fields */
628 if (!tmp) /* discard empty sub-blocks */
629 return SILC_CONFIG_OK;
631 got_errno = SILC_CONFIG_EMISSFIELDS;
635 my_set_param_defaults(tmp, &config->param);
637 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
639 return SILC_CONFIG_OK;
641 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigConnParams);
643 if (!strcmp(name, "name")) {
644 CONFIG_IS_DOUBLE(tmp->name);
645 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
647 else if (!strcmp(name, "connections_max")) {
648 tmp->connections_max = *(SilcUInt32 *)val;
650 else if (!strcmp(name, "connections_max_per_host")) {
651 tmp->connections_max_per_host = *(SilcUInt32 *)val;
653 else if (!strcmp(name, "keepalive_secs")) {
654 tmp->keepalive_secs = *(SilcUInt32 *)val;
656 else if (!strcmp(name, "reconnect_count")) {
657 tmp->reconnect_count = *(SilcUInt32 *)val;
659 else if (!strcmp(name, "reconnect_interval")) {
660 tmp->reconnect_interval = *(SilcUInt32 *)val;
662 else if (!strcmp(name, "reconnect_interval_max")) {
663 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
665 else if (!strcmp(name, "reconnect_keep_trying")) {
666 tmp->reconnect_keep_trying = *(bool *)val;
668 else if (!strcmp(name, "key_exchange_rekey")) {
669 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
671 else if (!strcmp(name, "key_exchange_pfs")) {
672 tmp->key_exchange_pfs = *(bool *)val;
674 else if (!strcmp(name, "version_protocol")) {
675 CONFIG_IS_DOUBLE(tmp->version_protocol);
676 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
678 else if (!strcmp(name, "version_software")) {
679 CONFIG_IS_DOUBLE(tmp->version_software);
680 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
682 else if (!strcmp(name, "version_software_vendor")) {
683 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
684 tmp->version_software_vendor =
685 (*(char *)val ? strdup((char *) val) : NULL);
687 else if (!strcmp(name, "anonymous")) {
688 tmp->anonymous = *(bool *)val;
690 else if (!strcmp(name, "qos")) {
691 tmp->qos = *(bool *)val;
693 else if (!strcmp(name, "qos_rate_limit")) {
694 tmp->qos_rate_limit = *(SilcUInt32 *)val;
696 else if (!strcmp(name, "qos_bytes_limit")) {
697 tmp->qos_bytes_limit = *(SilcUInt32 *)val;
699 else if (!strcmp(name, "qos_limit_sec")) {
700 tmp->qos_limit_sec = *(SilcUInt32 *)val;
702 else if (!strcmp(name, "qos_limit_usec")) {
703 tmp->qos_limit_usec = *(SilcUInt32 *)val;
706 return SILC_CONFIG_EINTERNAL;
708 return SILC_CONFIG_OK;
711 silc_free(tmp->name);
717 SILC_CONFIG_CALLBACK(fetch_client)
719 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
721 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
722 type, name, context));
724 /* Alloc before block checking, because empty sub-blocks are welcome here */
725 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigClient);
727 if (type == SILC_CONFIG_ARG_BLOCK) {
728 /* empty sub-blocks are welcome */
729 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
731 return SILC_CONFIG_OK;
734 /* Identify and save this value */
735 if (!strcmp(name, "host")) {
736 CONFIG_IS_DOUBLE(tmp->host);
737 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
739 else if (!strcmp(name, "passphrase")) {
740 CONFIG_IS_DOUBLE(tmp->passphrase);
741 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
742 (void **)&tmp->passphrase,
743 &tmp->passphrase_len)) {
744 got_errno = SILC_CONFIG_EPRINTLINE;
748 else if (!strcmp(name, "publickey")) {
749 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
750 (void **)&tmp->publickeys, NULL)) {
751 got_errno = SILC_CONFIG_EPRINTLINE;
755 else if (!strcmp(name, "params")) {
756 CONFIG_IS_DOUBLE(tmp->param);
757 tmp->param = my_find_param(config, (char *) val);
758 if (!tmp->param) { /* error message already output */
759 got_errno = SILC_CONFIG_EPRINTLINE;
764 return SILC_CONFIG_EINTERNAL;
765 return SILC_CONFIG_OK;
768 silc_free(tmp->host);
769 CONFIG_FREE_AUTH(tmp);
775 SILC_CONFIG_CALLBACK(fetch_admin)
777 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
779 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
780 type, name, context));
781 if (type == SILC_CONFIG_ARG_BLOCK) {
782 /* check the temporary struct's fields */
783 if (!tmp) /* discard empty sub-blocks */
784 return SILC_CONFIG_OK;
786 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
788 return SILC_CONFIG_OK;
790 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigAdmin);
792 /* Identify and save this value */
793 if (!strcmp(name, "host")) {
794 CONFIG_IS_DOUBLE(tmp->host);
795 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
797 else if (!strcmp(name, "user")) {
798 CONFIG_IS_DOUBLE(tmp->user);
799 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
801 else if (!strcmp(name, "nick")) {
802 CONFIG_IS_DOUBLE(tmp->nick);
803 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
805 else if (!strcmp(name, "passphrase")) {
806 CONFIG_IS_DOUBLE(tmp->passphrase);
807 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
808 (void **)&tmp->passphrase,
809 &tmp->passphrase_len)) {
810 got_errno = SILC_CONFIG_EPRINTLINE;
814 else if (!strcmp(name, "publickey")) {
815 CONFIG_IS_DOUBLE(tmp->publickeys);
816 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
817 (void **)&tmp->publickeys, NULL)) {
818 got_errno = SILC_CONFIG_EPRINTLINE;
823 return SILC_CONFIG_EINTERNAL;
824 return SILC_CONFIG_OK;
827 silc_free(tmp->host);
828 silc_free(tmp->user);
829 silc_free(tmp->nick);
830 CONFIG_FREE_AUTH(tmp);
836 SILC_CONFIG_CALLBACK(fetch_deny)
838 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
840 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
841 type, name, context));
842 if (type == SILC_CONFIG_ARG_BLOCK) {
843 /* check the temporary struct's fields */
844 if (!tmp) /* discard empty sub-blocks */
845 return SILC_CONFIG_OK;
847 got_errno = SILC_CONFIG_EMISSFIELDS;
851 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
853 return SILC_CONFIG_OK;
855 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigDeny);
857 /* Identify and save this value */
858 if (!strcmp(name, "host")) {
859 CONFIG_IS_DOUBLE(tmp->host);
860 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
862 else if (!strcmp(name, "reason")) {
863 CONFIG_IS_DOUBLE(tmp->reason);
864 tmp->reason = strdup((char *) val);
867 return SILC_CONFIG_EINTERNAL;
868 return SILC_CONFIG_OK;
871 silc_free(tmp->host);
872 silc_free(tmp->reason);
878 SILC_CONFIG_CALLBACK(fetch_server)
880 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
882 SERVER_CONFIG_DEBUG(("Received SERVER 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 /* the temporary struct is ok, append it to the list */
890 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
892 return SILC_CONFIG_OK;
894 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigServer);
896 /* Identify and save this value */
897 if (!strcmp(name, "host")) {
898 CONFIG_IS_DOUBLE(tmp->host);
899 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
901 else if (!strcmp(name, "passphrase")) {
902 CONFIG_IS_DOUBLE(tmp->passphrase);
903 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
904 (void **)&tmp->passphrase,
905 &tmp->passphrase_len)) {
906 got_errno = SILC_CONFIG_EPRINTLINE;
910 else if (!strcmp(name, "publickey")) {
911 CONFIG_IS_DOUBLE(tmp->publickeys);
912 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
913 (void **)&tmp->publickeys, NULL)) {
914 got_errno = SILC_CONFIG_EPRINTLINE;
918 else if (!strcmp(name, "params")) {
919 CONFIG_IS_DOUBLE(tmp->param);
920 tmp->param = my_find_param(config, (char *) val);
921 if (!tmp->param) { /* error message already output */
922 got_errno = SILC_CONFIG_EPRINTLINE;
926 else if (!strcmp(name, "backup")) {
927 tmp->backup_router = *(bool *)val;
930 return SILC_CONFIG_EINTERNAL;
932 return SILC_CONFIG_OK;
935 silc_free(tmp->host);
936 CONFIG_FREE_AUTH(tmp);
942 SILC_CONFIG_CALLBACK(fetch_router)
944 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
946 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
947 type, name, context));
948 if (type == SILC_CONFIG_ARG_BLOCK) {
949 if (!tmp) /* discard empty sub-blocks */
950 return SILC_CONFIG_OK;
952 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
954 return SILC_CONFIG_OK;
956 SILC_SERVER_CONFIG_ALLOCTMP(SilcServerConfigRouter);
958 /* Identify and save this value */
959 if (!strcmp(name, "host")) {
960 CONFIG_IS_DOUBLE(tmp->host);
961 tmp->host = strdup((char *) val);
963 else if (!strcmp(name, "port")) {
964 int port = *(int *)val;
965 if ((port <= 0) || (port > 65535)) {
966 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
967 "Invalid port number!"));
968 got_errno = SILC_CONFIG_EPRINTLINE;
971 tmp->port = (SilcUInt16) port;
973 else if (!strcmp(name, "passphrase")) {
974 CONFIG_IS_DOUBLE(tmp->passphrase);
975 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val,
976 (void **)&tmp->passphrase,
977 &tmp->passphrase_len)) {
978 got_errno = SILC_CONFIG_EPRINTLINE;
982 else if (!strcmp(name, "publickey")) {
983 CONFIG_IS_DOUBLE(tmp->publickeys);
984 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val,
985 (void **)&tmp->publickeys, NULL)) {
986 got_errno = SILC_CONFIG_EPRINTLINE;
990 else if (!strcmp(name, "params")) {
991 CONFIG_IS_DOUBLE(tmp->param);
992 tmp->param = my_find_param(config, (char *) val);
993 if (!tmp->param) { /* error message already output */
994 got_errno = SILC_CONFIG_EPRINTLINE;
998 else if (!strcmp(name, "initiator")) {
999 tmp->initiator = *(bool *)val;
1001 else if (!strcmp(name, "backuphost")) {
1002 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
1003 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
1005 tmp->backup_router = TRUE;
1007 else if (!strcmp(name, "backupport")) {
1008 int port = *(int *)val;
1009 if ((port <= 0) || (port > 65535)) {
1010 SILC_SERVER_LOG_ERROR(("Error while parsing config file: "
1011 "Invalid port number!"));
1012 got_errno = SILC_CONFIG_EPRINTLINE;
1015 tmp->backup_replace_port = (SilcUInt16) port;
1017 else if (!strcmp(name, "backuplocal")) {
1018 tmp->backup_local = *(bool *)val;
1021 return SILC_CONFIG_EINTERNAL;
1023 return SILC_CONFIG_OK;
1026 silc_free(tmp->host);
1027 silc_free(tmp->backup_replace_ip);
1028 CONFIG_FREE_AUTH(tmp);
1034 /* known config options tables */
1035 static const SilcConfigTable table_general[] = {
1036 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1037 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1038 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1039 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1040 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1041 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1042 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1043 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1044 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1045 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1046 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1047 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1048 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1049 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1050 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1051 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1052 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1053 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1054 { "detach_disabled", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1055 { "detach_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1056 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1057 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1058 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1059 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1060 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1064 static const SilcConfigTable table_cipher[] = {
1065 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1066 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1067 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1068 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1072 static const SilcConfigTable table_hash[] = {
1073 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1074 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1075 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1076 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1080 static const SilcConfigTable table_hmac[] = {
1081 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1082 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1083 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1087 static const SilcConfigTable table_pkcs[] = {
1088 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1092 static const SilcConfigTable table_serverinfo_c[] = {
1093 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1094 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1098 static const SilcConfigTable table_serverinfo[] = {
1099 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1100 { "primary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1101 { "secondary", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo_c},
1102 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1103 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1104 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1105 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1106 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1107 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1108 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1109 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1110 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1111 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1115 static const SilcConfigTable table_logging_c[] = {
1116 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1117 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1118 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1122 static const SilcConfigTable table_logging[] = {
1123 { "timestamp", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1124 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1125 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1126 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1127 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1128 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1129 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1133 static const SilcConfigTable table_connparam[] = {
1134 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1135 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1136 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1137 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1138 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1139 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1140 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1141 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1142 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1143 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1144 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1145 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1146 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1147 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1148 { "anonymous", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1149 { "qos", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1150 { "qos_rate_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1151 { "qos_bytes_limit", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1152 { "qos_limit_sec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1153 { "qos_limit_usec", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1157 static const SilcConfigTable table_client[] = {
1158 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1159 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1160 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1161 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1165 static const SilcConfigTable table_admin[] = {
1166 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1167 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1168 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1169 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1170 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1171 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1172 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1176 static const SilcConfigTable table_deny[] = {
1177 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1178 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1182 static const SilcConfigTable table_serverconn[] = {
1183 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1184 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1185 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1186 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1187 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1191 static const SilcConfigTable table_routerconn[] = {
1192 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1193 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1194 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1195 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1196 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1197 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1198 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1199 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1200 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1204 static const SilcConfigTable table_main[] = {
1205 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1206 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1207 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1208 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1209 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1210 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1211 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1212 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1213 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1214 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1215 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1216 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1217 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1221 /* Set default values to stuff that was not configured. */
1223 static void silc_server_config_set_defaults(SilcServerConfig config)
1225 my_set_param_defaults(&config->param, NULL);
1227 config->channel_rekey_secs = (config->channel_rekey_secs ?
1228 config->channel_rekey_secs :
1229 SILC_SERVER_CHANNEL_REKEY);
1230 config->key_exchange_timeout = (config->key_exchange_timeout ?
1231 config->key_exchange_timeout :
1232 SILC_SERVER_SKE_TIMEOUT);
1233 config->conn_auth_timeout = (config->conn_auth_timeout ?
1234 config->conn_auth_timeout :
1235 SILC_SERVER_CONNAUTH_TIMEOUT);
1238 /* Allocates a new configuration object, opens configuration file and
1239 parses it. The parsed data is returned to the newly allocated
1240 configuration object. The SilcServerConfig must be freed by calling
1241 the silc_server_config_destroy function. */
1243 SilcServerConfig silc_server_config_alloc(const char *filename)
1245 SilcServerConfig config_new;
1246 SilcConfigEntity ent;
1247 SilcConfigFile *file;
1249 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1251 /* alloc a config object */
1252 config_new = silc_calloc(1, sizeof(*config_new));
1253 config_new->refcount = 1;
1257 /* general config defaults */
1258 config_new->logging_timestamp = TRUE;
1260 /* obtain a config file object */
1261 file = silc_config_open(filename);
1263 SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'",
1268 /* obtain a SilcConfig entity, we can use it to start the parsing */
1269 ent = silc_config_init(file);
1271 /* load the known configuration options, give our empty object as context */
1272 silc_config_register_table(ent, table_main, (void *) config_new);
1274 /* enter the main parsing loop. When this returns, we have the parsing
1275 * result and the object filled (or partially, in case of errors). */
1276 ret = silc_config_main(ent);
1277 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1278 silc_config_strerror(ret)));
1280 /* Check if the parser returned errors */
1282 /* handle this special error return which asks to quietly return */
1283 if (ret != SILC_CONFIG_ESILENT) {
1284 char *linebuf, *filename = silc_config_get_filename(file);
1285 SilcUInt32 line = silc_config_get_line(file);
1286 if (ret != SILC_CONFIG_EPRINTLINE)
1287 SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.",
1288 silc_config_strerror(ret)));
1289 linebuf = silc_config_read_line(file, line);
1290 SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
1294 silc_server_config_destroy(config_new);
1298 /* close (destroy) the file object */
1299 silc_config_close(file);
1301 /* If config_new is incomplete, abort the object and return NULL */
1302 if (!config_new->server_info) {
1303 SILC_SERVER_LOG_ERROR(("\nError: Missing mandatory block "
1305 silc_server_config_destroy(config_new);
1309 /* Set default to configuration parameters */
1310 silc_server_config_set_defaults(config_new);
1315 /* Increments the reference counter of a config object */
1317 void silc_server_config_ref(SilcServerConfigRef *ref, SilcServerConfig config,
1322 ref->config = config;
1323 ref->ref_ptr = ref_ptr;
1324 SILC_LOG_DEBUG(("Referencing config [%p] refcnt %d->%d", config,
1325 config->refcount - 1, config->refcount));
1329 /* Decrements the reference counter of a config object. If the counter
1330 reaches 0, the config object is destroyed. */
1332 void silc_server_config_unref(SilcServerConfigRef *ref)
1335 silc_server_config_destroy(ref->config);
1338 /* Destroy a config object with all his children lists */
1340 void silc_server_config_destroy(SilcServerConfig config)
1345 SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %d->%d", config,
1346 config->refcount + 1, config->refcount));
1347 if (config->refcount > 0)
1350 SILC_LOG_DEBUG(("Freeing config context"));
1352 /* Destroy general config stuff */
1353 silc_free(config->module_path);
1354 silc_free(config->param.version_protocol);
1355 silc_free(config->param.version_software);
1356 silc_free(config->param.version_software_vendor);
1358 /* Destroy Logging channels */
1359 if (config->logging_info)
1360 silc_free(config->logging_info->file);
1361 if (config->logging_warnings)
1362 silc_free(config->logging_warnings->file);
1363 if (config->logging_errors)
1364 silc_free(config->logging_errors->file);
1365 if (config->logging_fatals)
1366 silc_free(config->logging_fatals->file);
1367 silc_free(config->logging_info);
1368 silc_free(config->logging_warnings);
1369 silc_free(config->logging_errors);
1370 silc_free(config->logging_fatals);
1372 /* Destroy the ServerInfo struct */
1373 if (config->server_info) {
1374 register SilcServerConfigServerInfo *si = config->server_info;
1375 silc_free(si->server_name);
1377 silc_free(si->primary->server_ip);
1378 silc_free(si->primary);
1380 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServerInfoInterface,
1382 silc_free(di->server_ip);
1385 silc_free(si->server_type);
1386 silc_free(si->location);
1387 silc_free(si->admin);
1388 silc_free(si->email);
1389 silc_free(si->user);
1390 silc_free(si->group);
1391 silc_free(si->motd_file);
1392 silc_free(si->pid_file);
1393 silc_pkcs_public_key_free(si->public_key);
1394 silc_pkcs_private_key_free(si->private_key);
1398 /* Now let's destroy the lists */
1400 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1402 silc_free(di->name);
1403 silc_free(di->module);
1406 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1407 silc_free(di->name);
1408 silc_free(di->module);
1411 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1412 silc_free(di->name);
1413 silc_free(di->hash);
1416 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1417 silc_free(di->name);
1420 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigConnParams,
1421 config->conn_params)
1422 silc_free(di->name);
1423 silc_free(di->version_protocol);
1424 silc_free(di->version_software);
1425 silc_free(di->version_software_vendor);
1428 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients)
1429 silc_free(di->host);
1430 CONFIG_FREE_AUTH(di);
1433 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1434 silc_free(di->host);
1435 silc_free(di->user);
1436 silc_free(di->nick);
1437 CONFIG_FREE_AUTH(di);
1440 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1441 silc_free(di->host);
1442 silc_free(di->reason);
1445 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1447 silc_free(di->host);
1448 CONFIG_FREE_AUTH(di);
1451 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1453 silc_free(di->host);
1454 silc_free(di->backup_replace_ip);
1455 CONFIG_FREE_AUTH(di);
1459 memset(config, 'F', sizeof(*config));
1463 /* Registers configured ciphers. These can then be allocated by the
1464 server when needed. */
1466 bool silc_server_config_register_ciphers(SilcServer server)
1468 SilcServerConfig config = server->config;
1469 SilcServerConfigCipher *cipher = config->cipher;
1470 char *module_path = config->module_path;
1472 SILC_LOG_DEBUG(("Registering configured ciphers"));
1474 if (!cipher) /* any cipher in the config file? */
1478 /* if there isn't a module_path OR there isn't a module sim name try to
1479 * use buil-in functions */
1480 if (!module_path || !cipher->module) {
1482 for (i = 0; silc_default_ciphers[i].name; i++)
1483 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1484 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1487 if (!silc_cipher_is_supported(cipher->name)) {
1488 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1489 silc_server_stop(server);
1494 /* Load (try at least) the crypto SIM module */
1495 char buf[1023], *alg_name;
1496 SilcCipherObject cipher_obj;
1499 memset(&cipher_obj, 0, sizeof(cipher_obj));
1500 cipher_obj.name = cipher->name;
1501 cipher_obj.block_len = cipher->block_length;
1502 cipher_obj.key_len = cipher->key_length * 8;
1504 /* build the libname */
1505 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1507 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1509 alg_name = strdup(cipher->name);
1510 if (strchr(alg_name, '-'))
1511 *strchr(alg_name, '-') = '\0';
1513 if (silc_sim_load(sim)) {
1514 cipher_obj.set_key =
1515 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1516 SILC_CIPHER_SIM_SET_KEY));
1517 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1518 cipher_obj.set_key_with_string =
1519 silc_sim_getsym(sim,
1520 silc_sim_symname(alg_name,
1521 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1522 SILC_LOG_DEBUG(("set_key_with_string=%p",
1523 cipher_obj.set_key_with_string));
1524 cipher_obj.encrypt =
1525 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1526 SILC_CIPHER_SIM_ENCRYPT_CBC));
1527 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1528 cipher_obj.decrypt =
1529 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1530 SILC_CIPHER_SIM_DECRYPT_CBC));
1531 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1532 cipher_obj.context_len =
1533 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1534 SILC_CIPHER_SIM_CONTEXT_LEN));
1535 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1537 /* Put the SIM to the list of all SIM's in server */
1538 silc_dlist_add(server->sim, sim);
1540 silc_free(alg_name);
1542 SILC_LOG_ERROR(("Error configuring ciphers"));
1543 silc_server_stop(server);
1547 /* Register the cipher */
1548 silc_cipher_register(&cipher_obj);
1550 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1551 "can't load modules!"));
1552 silc_server_stop(server);
1556 cipher = cipher->next;
1562 /* Registers configured hash functions. These can then be allocated by the
1563 server when needed. */
1565 bool silc_server_config_register_hashfuncs(SilcServer server)
1567 SilcServerConfig config = server->config;
1568 SilcServerConfigHash *hash = config->hash;
1569 char *module_path = config->module_path;
1571 SILC_LOG_DEBUG(("Registering configured hash functions"));
1573 if (!hash) /* any hash func in the config file? */
1577 /* if there isn't a module_path OR there isn't a module sim name try to
1578 * use buil-in functions */
1579 if (!module_path || !hash->module) {
1581 for (i = 0; silc_default_hash[i].name; i++)
1582 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1583 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1586 if (!silc_hash_is_supported(hash->name)) {
1587 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1588 silc_server_stop(server);
1593 /* Load (try at least) the hash SIM module */
1594 SilcHashObject hash_obj;
1597 memset(&hash_obj, 0, sizeof(hash_obj));
1598 hash_obj.name = hash->name;
1599 hash_obj.block_len = hash->block_length;
1600 hash_obj.hash_len = hash->digest_length;
1602 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1604 if ((silc_sim_load(sim))) {
1606 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1607 SILC_HASH_SIM_INIT));
1608 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1610 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1611 SILC_HASH_SIM_UPDATE));
1612 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1614 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1615 SILC_HASH_SIM_FINAL));
1616 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1617 hash_obj.context_len =
1618 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1619 SILC_HASH_SIM_CONTEXT_LEN));
1620 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1622 /* Put the SIM to the table of all SIM's in server */
1623 silc_dlist_add(server->sim, sim);
1625 SILC_LOG_ERROR(("Error configuring hash functions"));
1626 silc_server_stop(server);
1630 /* Register the hash function */
1631 silc_hash_register(&hash_obj);
1633 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1634 "can't load modules!"));
1635 silc_server_stop(server);
1645 /* Registers configure HMACs. These can then be allocated by the server
1648 bool silc_server_config_register_hmacs(SilcServer server)
1650 SilcServerConfig config = server->config;
1651 SilcServerConfigHmac *hmac = config->hmac;
1653 SILC_LOG_DEBUG(("Registering configured HMACs"));
1659 SilcHmacObject hmac_obj;
1660 if (!silc_hash_is_supported(hmac->hash)) {
1661 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1662 silc_server_stop(server);
1666 /* Register the HMAC */
1667 memset(&hmac_obj, 0, sizeof(hmac_obj));
1668 hmac_obj.name = hmac->name;
1669 hmac_obj.len = hmac->mac_length;
1670 silc_hmac_register(&hmac_obj);
1678 /* Registers configured PKCS's. */
1680 bool silc_server_config_register_pkcs(SilcServer server)
1682 SilcServerConfig config = server->config;
1683 SilcServerConfigPkcs *pkcs = config->pkcs;
1685 SILC_LOG_DEBUG(("Registering configured PKCS"));
1692 for (i = 0; silc_default_pkcs[i].name; i++)
1693 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1694 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1697 if (!silc_pkcs_is_supported(pkcs->name)) {
1698 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1699 silc_server_stop(server);
1708 /* Sets log files where log messages are saved by the server logger. */
1710 void silc_server_config_setlogfiles(SilcServer server)
1712 SilcServerConfig config = server->config;
1713 SilcServerConfigLogging *this;
1715 SILC_LOG_DEBUG(("Setting configured log file names and options"));
1717 silc_log_timestamp = config->logging_timestamp;
1718 silc_log_quick = config->logging_quick;
1719 silc_log_flushdelay = (config->logging_flushdelay ?
1720 config->logging_flushdelay :
1721 SILC_SERVER_LOG_FLUSH_DELAY);
1723 if ((this = config->logging_fatals))
1724 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1726 if ((this = config->logging_errors))
1727 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1729 if ((this = config->logging_warnings))
1730 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1732 if ((this = config->logging_info))
1733 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1737 /* Returns client authentication information from configuration file by host
1740 SilcServerConfigClient *
1741 silc_server_config_find_client(SilcServer server, char *host)
1743 SilcServerConfig config = server->config;
1744 SilcServerConfigClient *client;
1746 if (!config || !host)
1749 for (client = config->clients; client; client = client->next) {
1750 if (client->host && !silc_string_compare(client->host, host))
1755 /* if none matched, then client is already NULL */
1759 /* Returns admin connection configuration by host, username and/or
1762 SilcServerConfigAdmin *
1763 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1766 SilcServerConfig config = server->config;
1767 SilcServerConfigAdmin *admin;
1769 /* make sure we have a value for the matching parameters */
1777 for (admin = config->admins; admin; admin = admin->next) {
1778 if (admin->host && !silc_string_compare(admin->host, host))
1780 if (admin->user && !silc_string_compare(admin->user, user))
1782 if (admin->nick && !silc_string_compare(admin->nick, nick))
1784 /* no checks failed -> this entry matches */
1788 /* if none matched, then admin is already NULL */
1792 /* Returns the denied connection configuration entry by host. */
1794 SilcServerConfigDeny *
1795 silc_server_config_find_denied(SilcServer server, char *host)
1797 SilcServerConfig config = server->config;
1798 SilcServerConfigDeny *deny;
1800 /* make sure we have a value for the matching parameters */
1801 if (!config || !host)
1804 for (deny = config->denied; deny; deny = deny->next) {
1805 if (deny->host && !silc_string_compare(deny->host, host))
1810 /* if none matched, then deny is already NULL */
1814 /* Returns server connection info from server configuartion by host
1817 SilcServerConfigServer *
1818 silc_server_config_find_server_conn(SilcServer server, char *host)
1820 SilcServerConfig config = server->config;
1821 SilcServerConfigServer *serv = NULL;
1826 if (!config->servers)
1829 for (serv = config->servers; serv; serv = serv->next) {
1830 if (!silc_string_compare(serv->host, host))
1838 /* Returns router connection info from server configuration by
1839 host (name or ip). */
1841 SilcServerConfigRouter *
1842 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1844 SilcServerConfig config = server->config;
1845 SilcServerConfigRouter *serv = NULL;
1850 if (!config->routers)
1853 for (serv = config->routers; serv; serv = serv->next) {
1854 if (!silc_string_compare(serv->host, host))
1856 if (port && serv->port && serv->port != port)
1864 /* Find backup router connection by host (name or ip) */
1866 SilcServerConfigRouter *
1867 silc_server_config_find_backup_conn(SilcServer server, char *host)
1869 SilcServerConfig config = server->config;
1870 SilcServerConfigRouter *serv = NULL;
1875 if (!config->routers)
1878 for (serv = config->routers; serv; serv = serv->next) {
1879 if (!serv->backup_router)
1881 if (!silc_string_compare(serv->host, host))
1889 /* Returns TRUE if configuration for a router connection that we are
1890 initiating exists. */
1892 bool silc_server_config_is_primary_route(SilcServer server)
1894 SilcServerConfig config = server->config;
1895 SilcServerConfigRouter *serv = NULL;
1899 serv = config->routers;
1900 for (i = 0; serv; i++) {
1901 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1912 /* Returns our primary connection configuration or NULL if we do not
1913 have primary router configured. */
1915 SilcServerConfigRouter *
1916 silc_server_config_get_primary_router(SilcServer server)
1918 SilcServerConfig config = server->config;
1919 SilcServerConfigRouter *serv = NULL;
1922 serv = config->routers;
1923 for (i = 0; serv; i++) {
1924 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1932 /* If we have backup router configured that is going to replace us this
1933 function returns it. */
1935 SilcServerConfigRouter *
1936 silc_server_config_get_backup_router(SilcServer server)
1938 SilcServerConfig config = server->config;
1939 SilcServerConfigRouter *serv = NULL;
1942 if (server->server_type != SILC_ROUTER)
1945 serv = config->routers;
1946 for (i = 0; serv; i++) {
1947 if (serv->initiator == FALSE && serv->backup_router == TRUE &&
1948 serv->backup_local == TRUE &&
1949 !strcmp(server->config->server_info->primary->server_ip,
1950 serv->backup_replace_ip) &&
1951 server->config->server_info->primary->port ==
1952 serv->backup_replace_port)