5 Author: Johnny Mnemonic <johnny@themnemonic.org>
7 Copyright (C) 1997 - 2002 Johnny Mnemonic
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 /* append the tmp field to the specified list */
38 #define SILC_SERVER_CONFIG_LIST_APPENDTMP(__list__) \
42 for (findtmp = __list__; findtmp->next; findtmp = findtmp->next); \
43 findtmp->next = tmp; \
46 /* loops all elements in a list and provides a di struct pointer of the
47 * specified type containing the current element */
48 #define SILC_SERVER_CONFIG_LIST_DESTROY(__type__, __list__) \
49 for (tmp = (void *) __list__; tmp;) { \
50 __type__ *di = (__type__ *) tmp; \
51 tmp = (void *) di->next;
53 /* Set EDOUBLE error value and bail out if necessary */
54 #define CONFIG_IS_DOUBLE(__x__) \
56 got_errno = SILC_CONFIG_EDOUBLE; \
60 /* Free the authentication fields in the specified struct
61 * Expands to two instructions */
62 #define CONFIG_FREE_AUTH(__section__) \
63 silc_free(__section__->passphrase); \
64 if (__section__->publickeys) \
65 silc_hash_table_free(__section__->publickeys);
67 static void my_free_public_key(void *key, void *context, void *user_data)
69 silc_pkcs_public_key_free(context);
72 /* Set default values to those parameters that have not been defined */
74 my_set_param_defaults(SilcServerConfigConnParams *params,
75 SilcServerConfigConnParams *defaults)
77 #define SET_PARAM_DEFAULT(p, d) params->p = \
78 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
80 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
81 SET_PARAM_DEFAULT(connections_max_per_host,
82 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
83 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
84 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
85 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
86 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
87 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
90 /* Find connection parameters by the parameter block name. */
91 static SilcServerConfigConnParams *
92 my_find_param(SilcServerConfig config, const char *name, SilcUInt32 line)
94 SilcServerConfigConnParams *param;
96 for (param = config->conn_params; param; param = param->next) {
97 if (!strcasecmp(param->name, name))
101 fprintf(stderr, "\nError while parsing config file at line %lu: "
102 "Cannot find Param \"%s\".\n", line, name);
107 /* parse an authdata according to its auth method */
108 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p,
109 SilcUInt32 line, void **auth_data,
110 SilcUInt32 *auth_data_len)
112 if (auth_meth == SILC_AUTH_PASSWORD) {
113 /* p is a plain text password */
115 *auth_data = (void *) strdup(p);
117 *auth_data_len = (SilcUInt32) strlen(p);
118 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
119 /* p is a public key file name */
120 SilcPublicKey public_key;
122 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
123 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
124 fprintf(stderr, "\nError while parsing config file at line %lu: "
125 "Could not load public key file!\n", line);
129 /* The auth_data is a pointer to the hash table of public keys. */
131 if (*auth_data == NULL)
132 *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL,
134 my_free_public_key, NULL,
136 silc_hash_table_add(*auth_data, public_key, public_key);
139 fprintf(stderr, "\nError while parsing config file at line %lu: "
140 "Unknown authentication method.\n", line);
148 SILC_CONFIG_CALLBACK(fetch_generic)
150 SilcServerConfig config = (SilcServerConfig) context;
153 if (!strcmp(name, "module_path")) {
154 CONFIG_IS_DOUBLE(config->module_path);
155 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
157 else if (!strcmp(name, "prefer_passphrase_auth")) {
158 config->prefer_passphrase_auth = *(bool *)val;
160 else if (!strcmp(name, "require_reverse_lookup")) {
161 config->require_reverse_lookup = *(bool *)val;
163 else if (!strcmp(name, "connections_max")) {
164 config->param.connections_max = (SilcUInt32) *(int *)val;
166 else if (!strcmp(name, "connections_max_per_host")) {
167 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
169 else if (!strcmp(name, "keepalive_secs")) {
170 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
172 else if (!strcmp(name, "reconnect_count")) {
173 config->param.reconnect_count = (SilcUInt32) *(int *)val;
175 else if (!strcmp(name, "reconnect_interval")) {
176 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
178 else if (!strcmp(name, "reconnect_interval_max")) {
179 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
181 else if (!strcmp(name, "reconnect_keep_trying")) {
182 config->param.reconnect_keep_trying = *(bool *)val;
184 else if (!strcmp(name, "key_exchange_rekey")) {
185 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
187 else if (!strcmp(name, "key_exchange_pfs")) {
188 config->param.key_exchange_pfs = *(bool *)val;
190 else if (!strcmp(name, "channel_rekey_secs")) {
191 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
193 else if (!strcmp(name, "key_exchange_timeout")) {
194 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
196 else if (!strcmp(name, "conn_auth_timeout")) {
197 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
199 else if (!strcmp(name, "version_protocol")) {
200 CONFIG_IS_DOUBLE(config->param.version_protocol);
201 config->param.version_protocol =
202 (*(char *)val ? strdup((char *) val) : NULL);
204 else if (!strcmp(name, "version_software")) {
205 CONFIG_IS_DOUBLE(config->param.version_software);
206 config->param.version_software =
207 (*(char *)val ? strdup((char *) val) : NULL);
209 else if (!strcmp(name, "version_software_vendor")) {
210 CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
211 config->param.version_software_vendor =
212 (*(char *)val ? strdup((char *) val) : NULL);
215 return SILC_CONFIG_EINTERNAL;
217 return SILC_CONFIG_OK;
223 SILC_CONFIG_CALLBACK(fetch_cipher)
225 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
227 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
228 type, name, context));
229 if (type == SILC_CONFIG_ARG_BLOCK) {
230 /* check the temporary struct's fields */
231 if (!tmp) /* empty sub-block? */
232 return SILC_CONFIG_OK;
234 got_errno = SILC_CONFIG_EMISSFIELDS;
237 /* the temporary struct is ok, append it to the list */
238 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
240 return SILC_CONFIG_OK;
242 /* if there isn't a temporary struct alloc one */
244 config->tmp = silc_calloc(1, sizeof(*findtmp));
245 tmp = (SilcServerConfigCipher *) config->tmp;
248 /* Identify and save this value */
249 if (!strcmp(name, "name")) {
250 CONFIG_IS_DOUBLE(tmp->name);
251 tmp->name = strdup((char *) val);
253 else if (!strcmp(name, "module")) {
254 CONFIG_IS_DOUBLE(tmp->module);
255 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
257 else if (!strcmp(name, "keylength")) {
258 tmp->key_length = *(SilcUInt32 *)val;
260 else if (!strcmp(name, "blocklength")) {
261 tmp->block_length = *(SilcUInt32 *)val;
264 return SILC_CONFIG_EINTERNAL;
265 return SILC_CONFIG_OK;
268 silc_free(tmp->name);
269 silc_free(tmp->module);
275 SILC_CONFIG_CALLBACK(fetch_hash)
277 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
279 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
280 type, name, context));
281 if (type == SILC_CONFIG_ARG_BLOCK) {
282 /* check the temporary struct's fields */
283 if (!tmp) /* empty sub-block? */
284 return SILC_CONFIG_OK;
285 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
286 got_errno = SILC_CONFIG_EMISSFIELDS;
289 /* the temporary struct in tmp is ok */
290 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
292 return SILC_CONFIG_OK;
295 /* if there isn't a temporary struct alloc one */
297 config->tmp = silc_calloc(1, sizeof(*findtmp));
298 tmp = (SilcServerConfigHash *) config->tmp;
301 /* Identify and save this value */
302 if (!strcmp(name, "name")) {
303 CONFIG_IS_DOUBLE(tmp->name);
304 tmp->name = strdup((char *) val);
306 else if (!strcmp(name, "module")) {
307 CONFIG_IS_DOUBLE(tmp->module);
308 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
310 else if (!strcmp(name, "blocklength")) {
311 tmp->block_length = *(int *)val;
313 else if (!strcmp(name, "digestlength")) {
314 tmp->digest_length = *(int *)val;
317 return SILC_CONFIG_EINTERNAL;
318 return SILC_CONFIG_OK;
321 silc_free(tmp->name);
322 silc_free(tmp->module);
328 SILC_CONFIG_CALLBACK(fetch_hmac)
330 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
332 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
333 type, name, context));
334 if (type == SILC_CONFIG_ARG_BLOCK) {
335 /* check the temporary struct's fields */
336 if (!tmp) /* empty sub-block? */
337 return SILC_CONFIG_OK;
338 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
339 got_errno = SILC_CONFIG_EMISSFIELDS;
342 /* the temporary struct is ok, append it to the list */
343 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
345 return SILC_CONFIG_OK;
347 /* if there isn't a temporary struct alloc one */
349 config->tmp = silc_calloc(1, sizeof(*findtmp));
350 tmp = (SilcServerConfigHmac *) config->tmp;
353 /* Identify and save this value */
354 if (!strcmp(name, "name")) {
355 CONFIG_IS_DOUBLE(tmp->name);
356 tmp->name = strdup((char *) val);
358 else if (!strcmp(name, "hash")) {
359 CONFIG_IS_DOUBLE(tmp->hash);
360 tmp->hash = strdup((char *) val);
362 else if (!strcmp(name, "maclength")) {
363 tmp->mac_length = *(int *)val;
366 return SILC_CONFIG_EINTERNAL;
367 return SILC_CONFIG_OK;
370 silc_free(tmp->name);
371 silc_free(tmp->hash);
377 SILC_CONFIG_CALLBACK(fetch_pkcs)
379 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
381 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
382 type, name, context));
383 if (type == SILC_CONFIG_ARG_BLOCK) {
384 /* check the temporary struct's fields */
385 if (!tmp) /* empty sub-block? */
386 return SILC_CONFIG_OK;
388 got_errno = SILC_CONFIG_EMISSFIELDS;
391 /* the temporary struct is ok, append it to the list */
392 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
394 return SILC_CONFIG_OK;
396 /* if there isn't a temporary struct alloc one */
398 config->tmp = silc_calloc(1, sizeof(*findtmp));
399 tmp = (SilcServerConfigPkcs *) config->tmp;
402 /* Identify and save this value */
403 if (!strcmp(name, "name")) {
404 CONFIG_IS_DOUBLE(tmp->name);
405 tmp->name = strdup((char *) val);
408 return SILC_CONFIG_EINTERNAL;
409 return SILC_CONFIG_OK;
412 silc_free(tmp->name);
418 SILC_CONFIG_CALLBACK(fetch_serverinfo)
420 SilcServerConfig config = (SilcServerConfig) context;
421 SilcServerConfigServerInfo *server_info = config->server_info;
424 /* if there isn't the struct alloc it */
426 config->server_info = server_info = (SilcServerConfigServerInfo *)
427 silc_calloc(1, sizeof(*server_info));
429 if (type == SILC_CONFIG_ARG_BLOCK) {
430 /* check for mandatory inputs */
431 return SILC_CONFIG_OK;
433 if (!strcmp(name, "hostname")) {
434 CONFIG_IS_DOUBLE(server_info->server_name);
435 server_info->server_name = strdup((char *) val);
437 else if (!strcmp(name, "ip")) {
438 CONFIG_IS_DOUBLE(server_info->server_ip);
439 server_info->server_ip = strdup((char *) val);
441 else if (!strcmp(name, "port")) {
442 int port = *(int *)val;
443 if ((port <= 0) || (port > 65535)) {
444 fprintf(stderr, "Invalid port number!\n");
445 return SILC_CONFIG_ESILENT;
447 server_info->port = (SilcUInt16) port;
449 else if (!strcmp(name, "servertype")) {
450 CONFIG_IS_DOUBLE(server_info->server_type);
451 server_info->server_type = strdup((char *) val);
453 else if (!strcmp(name, "admin")) {
454 CONFIG_IS_DOUBLE(server_info->admin);
455 server_info->admin = strdup((char *) val);
457 else if (!strcmp(name, "adminemail")) {
458 CONFIG_IS_DOUBLE(server_info->email);
459 server_info->email = strdup((char *) val);
461 else if (!strcmp(name, "location")) {
462 CONFIG_IS_DOUBLE(server_info->location);
463 server_info->location = strdup((char *) val);
465 else if (!strcmp(name, "user")) {
466 CONFIG_IS_DOUBLE(server_info->user);
467 server_info->user = strdup((char *) val);
469 else if (!strcmp(name, "group")) {
470 CONFIG_IS_DOUBLE(server_info->group);
471 server_info->group = strdup((char *) val);
473 else if (!strcmp(name, "motdfile")) {
474 CONFIG_IS_DOUBLE(server_info->motd_file);
475 server_info->motd_file = strdup((char *) val);
477 else if (!strcmp(name, "pidfile")) {
478 CONFIG_IS_DOUBLE(server_info->pid_file);
479 server_info->pid_file = strdup((char *) val);
481 else if (!strcmp(name, "publickey")) {
482 char *tmp = (char *) val;
484 /* try to load specified file, if fail stop config parsing */
485 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
487 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
488 SILC_PKCS_FILE_BIN)) {
489 fprintf(stderr, "\nError: Could not load public key file.");
490 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
491 return SILC_CONFIG_ESILENT;
494 else if (!strcmp(name, "privatekey")) {
495 char *tmp = (char *) val;
497 /* try to load specified file, if fail stop config parsing */
498 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
500 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
501 SILC_PKCS_FILE_PEM)) {
502 fprintf(stderr, "\nError: Could not load private key file.");
503 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
504 return SILC_CONFIG_ESILENT;
508 return SILC_CONFIG_EINTERNAL;
509 return SILC_CONFIG_OK;
515 SILC_CONFIG_CALLBACK(fetch_logging)
517 SilcServerConfig config = (SilcServerConfig) context;
518 SilcServerConfigLogging *tmp =
519 (SilcServerConfigLogging *) config->tmp;
522 if (!strcmp(name, "quicklogs")) {
523 silc_log_quick = *(bool *)val;
525 else if (!strcmp(name, "flushdelay")) {
526 int flushdelay = *(int *)val;
527 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
528 fprintf(stderr, "Error: line %lu: invalid flushdelay value, use "
529 "quicklogs if you want real-time logging.\n", line);
530 return SILC_CONFIG_ESILENT;
532 silc_log_flushdelay = (long) flushdelay;
534 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
535 else if (!strcmp(name, __chan__)) { \
536 if (!tmp) return SILC_CONFIG_OK; \
538 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
540 config->__member__ = tmp; \
541 config->tmp = NULL; \
543 FETCH_LOGGING_CHAN("info", logging_info)
544 FETCH_LOGGING_CHAN("warnings", logging_warnings)
545 FETCH_LOGGING_CHAN("errors", logging_errors)
546 FETCH_LOGGING_CHAN("fatals", logging_fatals)
547 #undef FETCH_LOGGING_CHAN
548 else if (!strcmp(name, "file")) {
549 if (!tmp) { /* FIXME: what the fuck is this? */
550 config->tmp = silc_calloc(1, sizeof(*tmp));
551 tmp = (SilcServerConfigLogging *) config->tmp;
554 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
556 tmp->file = strdup((char *) val);
558 else if (!strcmp(name, "size")) {
560 config->tmp = silc_calloc(1, sizeof(*tmp));
561 tmp = (SilcServerConfigLogging *) config->tmp;
563 tmp->maxsize = *(SilcUInt32 *) val;
566 return SILC_CONFIG_EINTERNAL;
567 return SILC_CONFIG_OK;
570 silc_free(tmp->file);
576 SILC_CONFIG_CALLBACK(fetch_connparam)
578 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
580 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
581 type, name, context));
583 if (type == SILC_CONFIG_ARG_BLOCK) {
585 return SILC_CONFIG_OK;
588 got_errno = SILC_CONFIG_EMISSFIELDS;
593 my_set_param_defaults(tmp, &config->param);
595 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
597 return SILC_CONFIG_OK;
600 /* if there isn't a temporary struct alloc one */
602 config->tmp = silc_calloc(1, sizeof(*findtmp));
603 tmp = (SilcServerConfigConnParams *) config->tmp;
606 if (!strcmp(name, "name")) {
607 CONFIG_IS_DOUBLE(tmp->name);
608 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
610 else if (!strcmp(name, "connections_max")) {
611 tmp->connections_max = *(SilcUInt32 *)val;
613 else if (!strcmp(name, "connections_max_per_host")) {
614 tmp->connections_max_per_host = *(SilcUInt32 *)val;
616 else if (!strcmp(name, "keepalive_secs")) {
617 tmp->keepalive_secs = *(SilcUInt32 *)val;
619 else if (!strcmp(name, "reconnect_count")) {
620 tmp->reconnect_count = *(SilcUInt32 *)val;
622 else if (!strcmp(name, "reconnect_interval")) {
623 tmp->reconnect_interval = *(SilcUInt32 *)val;
625 else if (!strcmp(name, "reconnect_interval_max")) {
626 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
628 else if (!strcmp(name, "reconnect_keep_trying")) {
629 tmp->reconnect_keep_trying = *(bool *)val;
631 else if (!strcmp(name, "key_exchange_rekey")) {
632 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
634 else if (!strcmp(name, "key_exchange_pfs")) {
635 tmp->key_exchange_pfs = *(bool *)val;
637 else if (!strcmp(name, "version_protocol")) {
638 CONFIG_IS_DOUBLE(tmp->version_protocol);
639 tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
641 else if (!strcmp(name, "version_software")) {
642 CONFIG_IS_DOUBLE(tmp->version_software);
643 tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
645 else if (!strcmp(name, "version_software_vendor")) {
646 CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
647 tmp->version_software_vendor =
648 (*(char *)val ? strdup((char *) val) : NULL);
651 return SILC_CONFIG_EINTERNAL;
653 return SILC_CONFIG_OK;
656 silc_free(tmp->name);
662 SILC_CONFIG_CALLBACK(fetch_client)
664 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
666 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
667 type, name, context));
669 /* alloc tmp before block checking (empty sub-blocks are welcome here) */
671 config->tmp = silc_calloc(1, sizeof(*findtmp));
672 tmp = (SilcServerConfigClient *) config->tmp;
675 if (type == SILC_CONFIG_ARG_BLOCK) {
676 /* closing the block */
677 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
679 return SILC_CONFIG_OK;
682 /* Identify and save this value */
683 if (!strcmp(name, "host")) {
684 CONFIG_IS_DOUBLE(tmp->host);
685 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
687 else if (!strcmp(name, "passphrase")) {
688 CONFIG_IS_DOUBLE(tmp->passphrase);
689 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
690 (void **)&tmp->passphrase,
691 &tmp->passphrase_len)) {
692 got_errno = SILC_CONFIG_ESILENT;
696 else if (!strcmp(name, "publickey")) {
697 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
698 (void **)&tmp->publickeys, NULL)) {
699 got_errno = SILC_CONFIG_ESILENT;
703 else if (!strcmp(name, "params")) {
704 CONFIG_IS_DOUBLE(tmp->param);
705 tmp->param = my_find_param(config, (char *) val, line);
706 if (!tmp->param) { /* error already output */
707 got_errno = SILC_CONFIG_ESILENT;
712 return SILC_CONFIG_EINTERNAL;
713 return SILC_CONFIG_OK;
716 silc_free(tmp->host);
717 CONFIG_FREE_AUTH(tmp);
723 SILC_CONFIG_CALLBACK(fetch_admin)
725 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
727 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
728 type, name, context));
730 if (type == SILC_CONFIG_ARG_BLOCK) {
731 /* check the temporary struct's fields */
732 if (!tmp) /* empty sub-block? */
733 return SILC_CONFIG_OK;
735 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
737 return SILC_CONFIG_OK;
740 /* if there isn't a temporary struct alloc one */
742 config->tmp = silc_calloc(1, sizeof(*findtmp));
743 tmp = (SilcServerConfigAdmin *) config->tmp;
746 /* Identify and save this value */
747 if (!strcmp(name, "host")) {
748 CONFIG_IS_DOUBLE(tmp->host);
749 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
751 else if (!strcmp(name, "user")) {
752 CONFIG_IS_DOUBLE(tmp->user);
753 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
755 else if (!strcmp(name, "nick")) {
756 CONFIG_IS_DOUBLE(tmp->nick);
757 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
759 else if (!strcmp(name, "passphrase")) {
760 CONFIG_IS_DOUBLE(tmp->passphrase);
761 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
762 (void **)&tmp->passphrase,
763 &tmp->passphrase_len)) {
764 got_errno = SILC_CONFIG_ESILENT;
768 else if (!strcmp(name, "publickey")) {
769 CONFIG_IS_DOUBLE(tmp->publickeys);
770 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
771 (void **)&tmp->publickeys, NULL)) {
772 got_errno = SILC_CONFIG_ESILENT;
777 return SILC_CONFIG_EINTERNAL;
778 return SILC_CONFIG_OK;
781 silc_free(tmp->host);
782 silc_free(tmp->user);
783 silc_free(tmp->nick);
784 CONFIG_FREE_AUTH(tmp);
790 SILC_CONFIG_CALLBACK(fetch_deny)
792 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
794 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
795 type, name, context));
796 if (type == SILC_CONFIG_ARG_BLOCK) {
797 /* check the temporary struct's fields */
798 if (!tmp) /* empty sub-block? */
799 return SILC_CONFIG_OK;
801 got_errno = SILC_CONFIG_EMISSFIELDS;
804 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
806 return SILC_CONFIG_OK;
808 /* if there isn't a temporary struct alloc one */
810 config->tmp = silc_calloc(1, sizeof(*findtmp));
811 tmp = (SilcServerConfigDeny *) config->tmp;
814 /* Identify and save this value */
815 if (!strcmp(name, "host")) {
816 CONFIG_IS_DOUBLE(tmp->host);
817 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
819 else if (!strcmp(name, "reason")) {
820 CONFIG_IS_DOUBLE(tmp->reason);
821 tmp->reason = strdup((char *) val);
824 return SILC_CONFIG_EINTERNAL;
825 return SILC_CONFIG_OK;
828 silc_free(tmp->host);
829 silc_free(tmp->reason);
835 SILC_CONFIG_CALLBACK(fetch_server)
837 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
839 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
840 type, name, context));
842 if (type == SILC_CONFIG_ARG_BLOCK) {
843 /* check the temporary struct's fields */
844 if (!tmp) /* empty sub-block? */
845 return SILC_CONFIG_OK;
847 /* the temporary struct is ok, append it to the list */
848 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
850 return SILC_CONFIG_OK;
853 /* if there isn't a temporary struct alloc one */
855 config->tmp = silc_calloc(1, sizeof(*findtmp));
856 tmp = (SilcServerConfigServer *) config->tmp;
859 /* Identify and save this value */
860 if (!strcmp(name, "host")) {
861 CONFIG_IS_DOUBLE(tmp->host);
862 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
864 else if (!strcmp(name, "passphrase")) {
865 CONFIG_IS_DOUBLE(tmp->passphrase);
866 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
867 (void **)&tmp->passphrase,
868 &tmp->passphrase_len)) {
869 got_errno = SILC_CONFIG_ESILENT;
873 else if (!strcmp(name, "publickey")) {
874 CONFIG_IS_DOUBLE(tmp->publickeys);
875 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
876 (void **)&tmp->publickeys, NULL)) {
877 got_errno = SILC_CONFIG_ESILENT;
881 else if (!strcmp(name, "versionid")) {
882 CONFIG_IS_DOUBLE(tmp->version);
883 tmp->version = strdup((char *) val);
885 else if (!strcmp(name, "params")) {
886 CONFIG_IS_DOUBLE(tmp->param);
887 tmp->param = my_find_param(config, (char *) val, line);
888 if (!tmp->param) { /* error already output */
889 got_errno = SILC_CONFIG_ESILENT;
893 else if (!strcmp(name, "backup")) {
894 tmp->backup_router = *(bool *)val;
897 return SILC_CONFIG_EINTERNAL;
899 return SILC_CONFIG_OK;
902 silc_free(tmp->host);
903 silc_free(tmp->version);
904 CONFIG_FREE_AUTH(tmp);
910 SILC_CONFIG_CALLBACK(fetch_router)
912 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
914 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
915 type, name, context));
917 if (type == SILC_CONFIG_ARG_BLOCK) {
918 if (!tmp) /* empty sub-block? */
919 return SILC_CONFIG_OK;
921 /* the temporary struct is ok, append it to the list */
922 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
924 return SILC_CONFIG_OK;
927 /* if there isn't a temporary struct alloc one */
929 config->tmp = silc_calloc(1, sizeof(*findtmp));
930 tmp = (SilcServerConfigRouter *) config->tmp;
933 /* Identify and save this value */
934 if (!strcmp(name, "host")) {
935 CONFIG_IS_DOUBLE(tmp->host);
936 tmp->host = strdup((char *) val);
938 else if (!strcmp(name, "port")) {
939 int port = *(int *)val;
940 if ((port <= 0) || (port > 65535)) {
941 fprintf(stderr, "Invalid port number!\n");
942 return SILC_CONFIG_ESILENT;
944 tmp->port = (SilcUInt16) port;
946 else if (!strcmp(name, "passphrase")) {
947 CONFIG_IS_DOUBLE(tmp->passphrase);
948 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
949 (void **)&tmp->passphrase,
950 &tmp->passphrase_len)) {
951 got_errno = SILC_CONFIG_ESILENT;
955 else if (!strcmp(name, "publickey")) {
956 CONFIG_IS_DOUBLE(tmp->publickeys);
957 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
958 (void **)&tmp->publickeys, NULL)) {
959 got_errno = SILC_CONFIG_ESILENT;
963 else if (!strcmp(name, "versionid")) {
964 CONFIG_IS_DOUBLE(tmp->version);
965 tmp->version = strdup((char *) val);
967 else if (!strcmp(name, "params")) {
968 CONFIG_IS_DOUBLE(tmp->param);
969 tmp->param = my_find_param(config, (char *) val, line);
970 if (!tmp->param) { /* error already output */
971 got_errno = SILC_CONFIG_ESILENT;
975 else if (!strcmp(name, "initiator")) {
976 tmp->initiator = *(bool *)val;
978 else if (!strcmp(name, "backuphost")) {
979 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
980 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
983 else if (!strcmp(name, "backupport")) {
984 int port = *(int *)val;
985 if ((port <= 0) || (port > 65535)) {
986 fprintf(stderr, "Invalid port number!\n");
987 return SILC_CONFIG_ESILENT;
989 tmp->backup_replace_port = (SilcUInt16) port;
991 else if (!strcmp(name, "backuplocal")) {
992 tmp->backup_local = *(bool *)val;
995 return SILC_CONFIG_EINTERNAL;
997 return SILC_CONFIG_OK;
1000 silc_free(tmp->host);
1001 silc_free(tmp->version);
1002 silc_free(tmp->backup_replace_ip);
1003 CONFIG_FREE_AUTH(tmp);
1009 /* known config options tables */
1010 static const SilcConfigTable table_general[] = {
1011 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
1012 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1013 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1014 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1015 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1016 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1017 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1018 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1019 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1020 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1021 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1022 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1023 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1024 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1025 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1026 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1027 { "version_software", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1028 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_generic, NULL },
1032 static const SilcConfigTable table_cipher[] = {
1033 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1034 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1035 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1036 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1040 static const SilcConfigTable table_hash[] = {
1041 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1042 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1043 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1044 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1048 static const SilcConfigTable table_hmac[] = {
1049 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1050 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1051 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1055 static const SilcConfigTable table_pkcs[] = {
1056 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1060 static const SilcConfigTable table_serverinfo[] = {
1061 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1062 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1063 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1064 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1065 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1066 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1067 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1068 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1069 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1070 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1071 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1072 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1073 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1077 static const SilcConfigTable table_logging_c[] = {
1078 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1079 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1080 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1084 static const SilcConfigTable table_logging[] = {
1085 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1086 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1087 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1088 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1089 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1090 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1094 static const SilcConfigTable table_connparam[] = {
1095 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1096 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1097 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1098 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1099 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1100 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1101 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1102 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1103 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1104 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1105 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1106 { "version_protocol", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1107 { "version_software", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1108 { "version_software_vendor", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1112 static const SilcConfigTable table_client[] = {
1113 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1114 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1115 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1116 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1120 static const SilcConfigTable table_admin[] = {
1121 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1122 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1123 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1124 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1125 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1126 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1127 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1131 static const SilcConfigTable table_deny[] = {
1132 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1133 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1137 static const SilcConfigTable table_serverconn[] = {
1138 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1139 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1140 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1141 { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1142 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1143 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1147 static const SilcConfigTable table_routerconn[] = {
1148 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1149 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1150 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1151 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1152 { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1153 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1154 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1155 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1156 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1157 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1161 static const SilcConfigTable table_main[] = {
1162 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1163 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1164 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1165 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1166 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1167 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1168 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1169 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1170 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1171 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1172 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1173 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1174 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1178 /* Allocates a new configuration object, opens configuration file and
1179 * parses it. The parsed data is returned to the newly allocated
1180 * configuration object. */
1182 SilcServerConfig silc_server_config_alloc(char *filename)
1184 SilcServerConfig config;
1185 SilcConfigEntity ent;
1186 SilcConfigFile *file;
1188 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1190 /* alloc a config object */
1191 config = (SilcServerConfig) silc_calloc(1, sizeof(*config));
1192 /* obtain a config file object */
1193 file = silc_config_open(filename);
1195 fprintf(stderr, "\nError: can't open config file `%s'\n", filename);
1198 /* obtain a SilcConfig entity, we can use it to start the parsing */
1199 ent = silc_config_init(file);
1200 /* load the known configuration options, give our empty object as context */
1201 silc_config_register_table(ent, table_main, (void *) config);
1202 /* enter the main parsing loop. When this returns, we have the parsing
1203 * result and the object filled (or partially, in case of errors). */
1204 ret = silc_config_main(ent);
1205 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1206 silc_config_strerror(ret)));
1208 /* Check if the parser returned errors */
1210 /* handle this special error return which asks to quietly return */
1211 if (ret != SILC_CONFIG_ESILENT) {
1212 char *linebuf, *filename = silc_config_get_filename(file);
1213 SilcUInt32 line = silc_config_get_line(file);
1214 fprintf(stderr, "\nError while parsing config file: %s.\n",
1215 silc_config_strerror(ret));
1216 linebuf = silc_config_read_line(file, line);
1217 fprintf(stderr, " file %s line %lu: %s\n\n", filename, line, linebuf);
1222 /* close (destroy) the file object */
1223 silc_config_close(file);
1225 /* XXX FIXME: check for missing mandatory fields */
1226 if (!config->server_info) {
1227 fprintf(stderr, "\nError: Missing mandatory block `server_info'\n");
1235 void silc_server_config_destroy(SilcServerConfig config)
1238 silc_free(config->module_path);
1240 /* Destroy Logging channels */
1241 if (config->logging_info)
1242 silc_free(config->logging_info->file);
1243 if (config->logging_warnings)
1244 silc_free(config->logging_warnings->file);
1245 if (config->logging_errors)
1246 silc_free(config->logging_errors->file);
1247 if (config->logging_fatals)
1248 silc_free(config->logging_fatals->file);
1250 /* Destroy the ServerInfo struct */
1251 if (config->server_info) {
1252 register SilcServerConfigServerInfo *si = config->server_info;
1253 silc_free(si->server_name);
1254 silc_free(si->server_ip);
1255 silc_free(si->server_type);
1256 silc_free(si->location);
1257 silc_free(si->admin);
1258 silc_free(si->email);
1259 silc_free(si->user);
1260 silc_free(si->group);
1261 silc_free(si->motd_file);
1262 silc_free(si->pid_file);
1265 /* Now let's destroy the lists */
1267 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1269 silc_free(di->name);
1270 silc_free(di->module);
1273 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1274 silc_free(di->name);
1275 silc_free(di->module);
1278 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1279 silc_free(di->name);
1280 silc_free(di->hash);
1283 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1284 silc_free(di->name);
1287 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient,
1289 silc_free(di->host);
1290 CONFIG_FREE_AUTH(di);
1293 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1294 silc_free(di->host);
1295 silc_free(di->user);
1296 silc_free(di->nick);
1297 CONFIG_FREE_AUTH(di);
1300 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1301 silc_free(di->host);
1302 silc_free(di->reason);
1305 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1307 silc_free(di->host);
1308 silc_free(di->version);
1309 CONFIG_FREE_AUTH(di);
1312 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1314 silc_free(di->host);
1315 silc_free(di->version);
1316 silc_free(di->backup_replace_ip);
1317 CONFIG_FREE_AUTH(di);
1322 /* Registers configured ciphers. These can then be allocated by the
1323 server when needed. */
1325 bool silc_server_config_register_ciphers(SilcServer server)
1327 SilcServerConfig config = server->config;
1328 SilcServerConfigCipher *cipher = config->cipher;
1329 char *module_path = config->module_path;
1331 SILC_LOG_DEBUG(("Registering configured ciphers"));
1333 if (!cipher) /* any cipher in the config file? */
1337 /* if there isn't a module_path OR there isn't a module sim name try to
1338 * use buil-in functions */
1339 if (!module_path || !cipher->module) {
1341 for (i = 0; silc_default_ciphers[i].name; i++)
1342 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1343 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1346 if (!silc_cipher_is_supported(cipher->name)) {
1347 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1348 silc_server_stop(server);
1353 /* Load (try at least) the crypto SIM module */
1354 char buf[1023], *alg_name;
1355 SilcCipherObject cipher_obj;
1358 memset(&cipher_obj, 0, sizeof(cipher_obj));
1359 cipher_obj.name = cipher->name;
1360 cipher_obj.block_len = cipher->block_length;
1361 cipher_obj.key_len = cipher->key_length * 8;
1363 /* build the libname */
1364 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1366 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1368 alg_name = strdup(cipher->name);
1369 if (strchr(alg_name, '-'))
1370 *strchr(alg_name, '-') = '\0';
1372 if (silc_sim_load(sim)) {
1373 cipher_obj.set_key =
1374 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1375 SILC_CIPHER_SIM_SET_KEY));
1376 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1377 cipher_obj.set_key_with_string =
1378 silc_sim_getsym(sim,
1379 silc_sim_symname(alg_name,
1380 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1381 SILC_LOG_DEBUG(("set_key_with_string=%p",
1382 cipher_obj.set_key_with_string));
1383 cipher_obj.encrypt =
1384 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1385 SILC_CIPHER_SIM_ENCRYPT_CBC));
1386 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1387 cipher_obj.decrypt =
1388 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1389 SILC_CIPHER_SIM_DECRYPT_CBC));
1390 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1391 cipher_obj.context_len =
1392 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1393 SILC_CIPHER_SIM_CONTEXT_LEN));
1394 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1396 /* Put the SIM to the list of all SIM's in server */
1397 silc_dlist_add(server->sim, sim);
1399 silc_free(alg_name);
1401 SILC_LOG_ERROR(("Error configuring ciphers"));
1402 silc_server_stop(server);
1406 /* Register the cipher */
1407 silc_cipher_register(&cipher_obj);
1409 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1410 "can't load modules!"));
1411 silc_server_stop(server);
1415 cipher = cipher->next;
1421 /* Registers configured hash functions. These can then be allocated by the
1422 server when needed. */
1424 bool silc_server_config_register_hashfuncs(SilcServer server)
1426 SilcServerConfig config = server->config;
1427 SilcServerConfigHash *hash = config->hash;
1428 char *module_path = config->module_path;
1430 SILC_LOG_DEBUG(("Registering configured hash functions"));
1432 if (!hash) /* any hash func in the config file? */
1436 /* if there isn't a module_path OR there isn't a module sim name try to
1437 * use buil-in functions */
1438 if (!module_path || !hash->module) {
1440 for (i = 0; silc_default_hash[i].name; i++)
1441 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1442 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1445 if (!silc_hash_is_supported(hash->name)) {
1446 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1447 silc_server_stop(server);
1452 /* Load (try at least) the hash SIM module */
1453 SilcHashObject hash_obj;
1456 memset(&hash_obj, 0, sizeof(hash_obj));
1457 hash_obj.name = hash->name;
1458 hash_obj.block_len = hash->block_length;
1459 hash_obj.hash_len = hash->digest_length;
1461 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1463 if ((silc_sim_load(sim))) {
1465 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1466 SILC_HASH_SIM_INIT));
1467 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1469 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1470 SILC_HASH_SIM_UPDATE));
1471 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1473 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1474 SILC_HASH_SIM_FINAL));
1475 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1476 hash_obj.context_len =
1477 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1478 SILC_HASH_SIM_CONTEXT_LEN));
1479 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1481 /* Put the SIM to the table of all SIM's in server */
1482 silc_dlist_add(server->sim, sim);
1484 SILC_LOG_ERROR(("Error configuring hash functions"));
1485 silc_server_stop(server);
1489 /* Register the hash function */
1490 silc_hash_register(&hash_obj);
1492 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1493 "can't load modules!"));
1494 silc_server_stop(server);
1504 /* Registers configure HMACs. These can then be allocated by the server
1507 bool silc_server_config_register_hmacs(SilcServer server)
1509 SilcServerConfig config = server->config;
1510 SilcServerConfigHmac *hmac = config->hmac;
1512 SILC_LOG_DEBUG(("Registering configured HMACs"));
1518 SilcHmacObject hmac_obj;
1519 if (!silc_hash_is_supported(hmac->hash)) {
1520 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1521 silc_server_stop(server);
1525 /* Register the HMAC */
1526 memset(&hmac_obj, 0, sizeof(hmac_obj));
1527 hmac_obj.name = hmac->name;
1528 hmac_obj.len = hmac->mac_length;
1529 silc_hmac_register(&hmac_obj);
1537 /* Registers configured PKCS's. */
1539 bool silc_server_config_register_pkcs(SilcServer server)
1541 SilcServerConfig config = server->config;
1542 SilcServerConfigPkcs *pkcs = config->pkcs;
1544 SILC_LOG_DEBUG(("Registering configured PKCS"));
1551 for (i = 0; silc_default_pkcs[i].name; i++)
1552 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1553 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1556 if (!silc_pkcs_is_supported(pkcs->name)) {
1557 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1558 silc_server_stop(server);
1567 /* Sets log files where log messages are saved by the server logger. */
1569 void silc_server_config_setlogfiles(SilcServer server)
1571 SilcServerConfig config = server->config;
1572 SilcServerConfigLogging *this;
1574 SILC_LOG_DEBUG(("Setting configured log file names"));
1576 if ((this = config->logging_info))
1577 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1579 if ((this = config->logging_warnings))
1580 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1582 if ((this = config->logging_errors))
1583 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1585 if ((this = config->logging_fatals))
1586 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1590 /* Returns client authentication information from configuration file by host
1593 SilcServerConfigClient *
1594 silc_server_config_find_client(SilcServer server, char *host)
1596 SilcServerConfig config = server->config;
1597 SilcServerConfigClient *client;
1599 if (!config || !host)
1602 for (client = config->clients; client; client = client->next) {
1603 if (client->host && !silc_string_compare(client->host, host))
1608 /* if none matched, then client is already NULL */
1612 /* Returns admin connection configuration by host, username and/or
1615 SilcServerConfigAdmin *
1616 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1619 SilcServerConfig config = server->config;
1620 SilcServerConfigAdmin *admin;
1622 /* make sure we have a value for the matching parameters */
1630 for (admin = config->admins; admin; admin = admin->next) {
1631 if (admin->host && !silc_string_compare(admin->host, host))
1633 if (admin->user && !silc_string_compare(admin->user, user))
1635 if (admin->nick && !silc_string_compare(admin->nick, nick))
1637 /* no checks failed -> this entry matches */
1641 /* if none matched, then admin is already NULL */
1645 /* Returns the denied connection configuration entry by host. */
1647 SilcServerConfigDeny *
1648 silc_server_config_find_denied(SilcServer server, char *host)
1650 SilcServerConfig config = server->config;
1651 SilcServerConfigDeny *deny;
1653 /* make sure we have a value for the matching parameters */
1654 if (!config || !host)
1657 for (deny = config->denied; deny; deny = deny->next) {
1658 if (deny->host && !silc_string_compare(deny->host, host))
1663 /* if none matched, then deny is already NULL */
1667 /* Returns server connection info from server configuartion by host
1670 SilcServerConfigServer *
1671 silc_server_config_find_server_conn(SilcServer server, char *host)
1673 SilcServerConfig config = server->config;
1674 SilcServerConfigServer *serv = NULL;
1679 if (!config->servers)
1682 for (serv = config->servers; serv; serv = serv->next) {
1683 if (!silc_string_compare(serv->host, host))
1691 /* Returns router connection info from server configuration by
1692 host (name or ip). */
1694 SilcServerConfigRouter *
1695 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1697 SilcServerConfig config = server->config;
1698 SilcServerConfigRouter *serv = NULL;
1703 if (!config->routers)
1706 for (serv = config->routers; serv; serv = serv->next) {
1707 if (!silc_string_compare(serv->host, host))
1709 if (port && serv->port && serv->port != port)
1717 /* Returns TRUE if configuration for a router connection that we are
1718 initiating exists. */
1720 bool silc_server_config_is_primary_route(SilcServer server)
1722 SilcServerConfig config = server->config;
1723 SilcServerConfigRouter *serv = NULL;
1727 serv = config->routers;
1728 for (i = 0; serv; i++) {
1729 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1740 /* Returns our primary connection configuration or NULL if we do not
1741 have primary router configured. */
1743 SilcServerConfigRouter *
1744 silc_server_config_get_primary_router(SilcServer server)
1746 SilcServerConfig config = server->config;
1747 SilcServerConfigRouter *serv = NULL;
1750 serv = config->routers;
1751 for (i = 0; serv; i++) {
1752 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1760 /* Set default values to stuff that was not configured. */
1762 bool silc_server_config_set_defaults(SilcServer server)
1764 SilcServerConfig config = server->config;
1766 my_set_param_defaults(&config->param, NULL);
1768 config->channel_rekey_secs = (config->channel_rekey_secs ?
1769 config->channel_rekey_secs :
1770 SILC_SERVER_CHANNEL_REKEY);
1771 config->key_exchange_timeout = (config->key_exchange_timeout ?
1772 config->key_exchange_timeout :
1773 SILC_SERVER_SKE_TIMEOUT);
1774 config->conn_auth_timeout = (config->conn_auth_timeout ?
1775 config->conn_auth_timeout :
1776 SILC_SERVER_CONNAUTH_TIMEOUT);