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) \
78 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
80 params->connections_max =
81 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
82 params->connections_max_per_host =
83 SET_PARAM_DEFAULT(connections_max_per_host,
84 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
85 params->keepalive_secs =
86 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
87 params->reconnect_count =
88 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
89 params->reconnect_interval =
90 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
91 params->reconnect_interval_max =
92 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
93 params->key_exchange_rekey =
94 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
97 /* Find connection parameters by the parameter block name. */
98 static SilcServerConfigConnParams *
99 my_find_param(SilcServerConfig config, const char *name, SilcUInt32 line)
101 SilcServerConfigConnParams *param;
103 for (param = config->conn_params; param; param = param->next) {
104 if (!strcasecmp(param->name, name))
108 fprintf(stderr, "\nError while parsing config file at line %lu: "
109 "Cannot find Param \"%s\".\n", line, name);
114 /* parse an authdata according to its auth method */
115 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p,
116 SilcUInt32 line, void **auth_data,
117 SilcUInt32 *auth_data_len)
119 if (auth_meth == SILC_AUTH_PASSWORD) {
120 /* p is a plain text password */
122 *auth_data = (void *) strdup(p);
124 *auth_data_len = (SilcUInt32) strlen(p);
125 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
126 /* p is a public key file name */
127 SilcPublicKey public_key;
129 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
130 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
131 fprintf(stderr, "\nError while parsing config file at line %lu: "
132 "Could not load public key file!\n", line);
136 /* The auth_data is a pointer to the hash table of public keys. */
138 if (*auth_data == NULL)
139 *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL,
141 my_free_public_key, NULL,
143 silc_hash_table_add(*auth_data, public_key, public_key);
146 fprintf(stderr, "\nError while parsing config file at line %lu: "
147 "Unknown authentication method.\n", line);
155 SILC_CONFIG_CALLBACK(fetch_generic)
157 SilcServerConfig config = (SilcServerConfig) context;
160 if (!strcmp(name, "module_path")) {
161 CONFIG_IS_DOUBLE(config->module_path);
162 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
164 else if (!strcmp(name, "prefer_passphrase_auth")) {
165 config->prefer_passphrase_auth = *(bool *)val;
167 else if (!strcmp(name, "require_reverse_lookup")) {
168 config->require_reverse_lookup = *(bool *)val;
170 else if (!strcmp(name, "connections_max")) {
171 config->param.connections_max = (SilcUInt32) *(int *)val;
173 else if (!strcmp(name, "connections_max_per_host")) {
174 config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
176 else if (!strcmp(name, "keepalive_secs")) {
177 config->param.keepalive_secs = (SilcUInt32) *(int *)val;
179 else if (!strcmp(name, "reconnect_count")) {
180 config->param.reconnect_count = (SilcUInt32) *(int *)val;
182 else if (!strcmp(name, "reconnect_interval")) {
183 config->param.reconnect_interval = (SilcUInt32) *(int *)val;
185 else if (!strcmp(name, "reconnect_interval_max")) {
186 config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
188 else if (!strcmp(name, "reconnect_keep_trying")) {
189 config->param.reconnect_keep_trying = *(bool *)val;
191 else if (!strcmp(name, "key_exchange_rekey")) {
192 config->param.key_exchange_rekey = (SilcUInt32) *(int *)val;
194 else if (!strcmp(name, "key_exchange_pfs")) {
195 config->param.key_exchange_pfs = *(bool *)val;
197 else if (!strcmp(name, "channel_rekey_secs")) {
198 config->channel_rekey_secs = (SilcUInt32) *(int *)val;
200 else if (!strcmp(name, "key_exchange_timeout")) {
201 config->key_exchange_timeout = (SilcUInt32) *(int *)val;
203 else if (!strcmp(name, "conn_auth_timeout")) {
204 config->conn_auth_timeout = (SilcUInt32) *(int *)val;
207 return SILC_CONFIG_EINTERNAL;
209 return SILC_CONFIG_OK;
215 SILC_CONFIG_CALLBACK(fetch_cipher)
217 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
219 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
220 type, name, context));
221 if (type == SILC_CONFIG_ARG_BLOCK) {
222 /* check the temporary struct's fields */
223 if (!tmp) /* empty sub-block? */
224 return SILC_CONFIG_OK;
226 got_errno = SILC_CONFIG_EMISSFIELDS;
229 /* the temporary struct is ok, append it to the list */
230 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
232 return SILC_CONFIG_OK;
234 /* if there isn't a temporary struct alloc one */
236 config->tmp = silc_calloc(1, sizeof(*findtmp));
237 tmp = (SilcServerConfigCipher *) config->tmp;
240 /* Identify and save this value */
241 if (!strcmp(name, "name")) {
242 CONFIG_IS_DOUBLE(tmp->name);
243 tmp->name = strdup((char *) val);
245 else if (!strcmp(name, "module")) {
246 CONFIG_IS_DOUBLE(tmp->module);
247 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
249 else if (!strcmp(name, "keylength")) {
250 tmp->key_length = *(SilcUInt32 *)val;
252 else if (!strcmp(name, "blocklength")) {
253 tmp->block_length = *(SilcUInt32 *)val;
256 return SILC_CONFIG_EINTERNAL;
257 return SILC_CONFIG_OK;
260 silc_free(tmp->name);
261 silc_free(tmp->module);
267 SILC_CONFIG_CALLBACK(fetch_hash)
269 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
271 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
272 type, name, context));
273 if (type == SILC_CONFIG_ARG_BLOCK) {
274 /* check the temporary struct's fields */
275 if (!tmp) /* empty sub-block? */
276 return SILC_CONFIG_OK;
277 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
278 got_errno = SILC_CONFIG_EMISSFIELDS;
281 /* the temporary struct in tmp is ok */
282 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
284 return SILC_CONFIG_OK;
287 /* if there isn't a temporary struct alloc one */
289 config->tmp = silc_calloc(1, sizeof(*findtmp));
290 tmp = (SilcServerConfigHash *) config->tmp;
293 /* Identify and save this value */
294 if (!strcmp(name, "name")) {
295 CONFIG_IS_DOUBLE(tmp->name);
296 tmp->name = strdup((char *) val);
298 else if (!strcmp(name, "module")) {
299 CONFIG_IS_DOUBLE(tmp->module);
300 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
302 else if (!strcmp(name, "blocklength")) {
303 tmp->block_length = *(int *)val;
305 else if (!strcmp(name, "digestlength")) {
306 tmp->digest_length = *(int *)val;
309 return SILC_CONFIG_EINTERNAL;
310 return SILC_CONFIG_OK;
313 silc_free(tmp->name);
314 silc_free(tmp->module);
320 SILC_CONFIG_CALLBACK(fetch_hmac)
322 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
324 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
325 type, name, context));
326 if (type == SILC_CONFIG_ARG_BLOCK) {
327 /* check the temporary struct's fields */
328 if (!tmp) /* empty sub-block? */
329 return SILC_CONFIG_OK;
330 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
331 got_errno = SILC_CONFIG_EMISSFIELDS;
334 /* the temporary struct is ok, append it to the list */
335 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
337 return SILC_CONFIG_OK;
339 /* if there isn't a temporary struct alloc one */
341 config->tmp = silc_calloc(1, sizeof(*findtmp));
342 tmp = (SilcServerConfigHmac *) config->tmp;
345 /* Identify and save this value */
346 if (!strcmp(name, "name")) {
347 CONFIG_IS_DOUBLE(tmp->name);
348 tmp->name = strdup((char *) val);
350 else if (!strcmp(name, "hash")) {
351 CONFIG_IS_DOUBLE(tmp->hash);
352 tmp->hash = strdup((char *) val);
354 else if (!strcmp(name, "maclength")) {
355 tmp->mac_length = *(int *)val;
358 return SILC_CONFIG_EINTERNAL;
359 return SILC_CONFIG_OK;
362 silc_free(tmp->name);
363 silc_free(tmp->hash);
369 SILC_CONFIG_CALLBACK(fetch_pkcs)
371 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
373 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
374 type, name, context));
375 if (type == SILC_CONFIG_ARG_BLOCK) {
376 /* check the temporary struct's fields */
377 if (!tmp) /* empty sub-block? */
378 return SILC_CONFIG_OK;
380 got_errno = SILC_CONFIG_EMISSFIELDS;
383 /* the temporary struct is ok, append it to the list */
384 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
386 return SILC_CONFIG_OK;
388 /* if there isn't a temporary struct alloc one */
390 config->tmp = silc_calloc(1, sizeof(*findtmp));
391 tmp = (SilcServerConfigPkcs *) config->tmp;
394 /* Identify and save this value */
395 if (!strcmp(name, "name")) {
396 CONFIG_IS_DOUBLE(tmp->name);
397 tmp->name = strdup((char *) val);
400 return SILC_CONFIG_EINTERNAL;
401 return SILC_CONFIG_OK;
404 silc_free(tmp->name);
410 SILC_CONFIG_CALLBACK(fetch_serverinfo)
412 SilcServerConfig config = (SilcServerConfig) context;
413 SilcServerConfigServerInfo *server_info = config->server_info;
416 /* if there isn't the struct alloc it */
418 config->server_info = server_info = (SilcServerConfigServerInfo *)
419 silc_calloc(1, sizeof(*server_info));
421 if (type == SILC_CONFIG_ARG_BLOCK) {
422 /* check for mandatory inputs */
423 return SILC_CONFIG_OK;
425 if (!strcmp(name, "hostname")) {
426 CONFIG_IS_DOUBLE(server_info->server_name);
427 server_info->server_name = strdup((char *) val);
429 else if (!strcmp(name, "ip")) {
430 CONFIG_IS_DOUBLE(server_info->server_ip);
431 server_info->server_ip = strdup((char *) val);
433 else if (!strcmp(name, "port")) {
434 int port = *(int *)val;
435 if ((port <= 0) || (port > 65535)) {
436 fprintf(stderr, "Invalid port number!\n");
437 return SILC_CONFIG_ESILENT;
439 server_info->port = (SilcUInt16) port;
441 else if (!strcmp(name, "servertype")) {
442 CONFIG_IS_DOUBLE(server_info->server_type);
443 server_info->server_type = strdup((char *) val);
445 else if (!strcmp(name, "admin")) {
446 CONFIG_IS_DOUBLE(server_info->admin);
447 server_info->admin = strdup((char *) val);
449 else if (!strcmp(name, "adminemail")) {
450 CONFIG_IS_DOUBLE(server_info->email);
451 server_info->email = strdup((char *) val);
453 else if (!strcmp(name, "location")) {
454 CONFIG_IS_DOUBLE(server_info->location);
455 server_info->location = strdup((char *) val);
457 else if (!strcmp(name, "user")) {
458 CONFIG_IS_DOUBLE(server_info->user);
459 server_info->user = strdup((char *) val);
461 else if (!strcmp(name, "group")) {
462 CONFIG_IS_DOUBLE(server_info->group);
463 server_info->group = strdup((char *) val);
465 else if (!strcmp(name, "motdfile")) {
466 CONFIG_IS_DOUBLE(server_info->motd_file);
467 server_info->motd_file = strdup((char *) val);
469 else if (!strcmp(name, "pidfile")) {
470 CONFIG_IS_DOUBLE(server_info->pid_file);
471 server_info->pid_file = strdup((char *) val);
473 else if (!strcmp(name, "publickey")) {
474 char *tmp = (char *) val;
476 /* try to load specified file, if fail stop config parsing */
477 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
479 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
480 SILC_PKCS_FILE_BIN)) {
481 fprintf(stderr, "\nError: Could not load public key file.");
482 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
483 return SILC_CONFIG_ESILENT;
486 else if (!strcmp(name, "privatekey")) {
487 char *tmp = (char *) val;
489 /* try to load specified file, if fail stop config parsing */
490 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
492 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
493 SILC_PKCS_FILE_PEM)) {
494 fprintf(stderr, "\nError: Could not load private key file.");
495 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
496 return SILC_CONFIG_ESILENT;
500 return SILC_CONFIG_EINTERNAL;
501 return SILC_CONFIG_OK;
507 SILC_CONFIG_CALLBACK(fetch_logging)
509 SilcServerConfig config = (SilcServerConfig) context;
510 SilcServerConfigLogging *tmp =
511 (SilcServerConfigLogging *) config->tmp;
514 if (!strcmp(name, "quicklogs")) {
515 silc_log_quick = *(bool *)val;
517 else if (!strcmp(name, "flushdelay")) {
518 int flushdelay = *(int *)val;
519 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
520 fprintf(stderr, "Error: line %lu: invalid flushdelay value, use "
521 "quicklogs if you want real-time logging.\n", line);
522 return SILC_CONFIG_ESILENT;
524 silc_log_flushdelay = (long) flushdelay;
526 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
527 else if (!strcmp(name, __chan__)) { \
528 if (!tmp) return SILC_CONFIG_OK; \
530 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
532 config->__member__ = tmp; \
533 config->tmp = NULL; \
535 FETCH_LOGGING_CHAN("info", logging_info)
536 FETCH_LOGGING_CHAN("warnings", logging_warnings)
537 FETCH_LOGGING_CHAN("errors", logging_errors)
538 FETCH_LOGGING_CHAN("fatals", logging_fatals)
539 #undef FETCH_LOGGING_CHAN
540 else if (!strcmp(name, "file")) {
541 if (!tmp) { /* FIXME: what the fuck is this? */
542 config->tmp = silc_calloc(1, sizeof(*tmp));
543 tmp = (SilcServerConfigLogging *) config->tmp;
546 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
548 tmp->file = strdup((char *) val);
550 else if (!strcmp(name, "size")) {
552 config->tmp = silc_calloc(1, sizeof(*tmp));
553 tmp = (SilcServerConfigLogging *) config->tmp;
555 tmp->maxsize = *(SilcUInt32 *) val;
558 return SILC_CONFIG_EINTERNAL;
559 return SILC_CONFIG_OK;
562 silc_free(tmp->file);
568 SILC_CONFIG_CALLBACK(fetch_connparam)
570 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
572 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
573 type, name, context));
575 if (type == SILC_CONFIG_ARG_BLOCK) {
577 return SILC_CONFIG_OK;
580 got_errno = SILC_CONFIG_EMISSFIELDS;
585 my_set_param_defaults(tmp, &config->param);
587 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
589 return SILC_CONFIG_OK;
592 /* if there isn't a temporary struct alloc one */
594 config->tmp = silc_calloc(1, sizeof(*findtmp));
595 tmp = (SilcServerConfigConnParams *) config->tmp;
598 if (!strcmp(name, "name")) {
599 CONFIG_IS_DOUBLE(tmp->name);
600 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
602 else if (!strcmp(name, "connections_max")) {
603 tmp->connections_max = *(SilcUInt32 *)val;
605 else if (!strcmp(name, "connections_max_per_host")) {
606 tmp->connections_max_per_host = *(SilcUInt32 *)val;
608 else if (!strcmp(name, "keepalive_secs")) {
609 tmp->keepalive_secs = *(SilcUInt32 *)val;
611 else if (!strcmp(name, "reconnect_count")) {
612 tmp->reconnect_count = *(SilcUInt32 *)val;
614 else if (!strcmp(name, "reconnect_interval")) {
615 tmp->reconnect_interval = *(SilcUInt32 *)val;
617 else if (!strcmp(name, "reconnect_interval_max")) {
618 tmp->reconnect_interval_max = *(SilcUInt32 *)val;
620 else if (!strcmp(name, "reconnect_keep_trying")) {
621 tmp->reconnect_keep_trying = *(bool *)val;
623 else if (!strcmp(name, "key_exchange_rekey")) {
624 tmp->key_exchange_rekey = *(SilcUInt32 *)val;
626 else if (!strcmp(name, "key_exchange_pfs")) {
627 tmp->key_exchange_pfs = *(bool *)val;
630 return SILC_CONFIG_EINTERNAL;
632 return SILC_CONFIG_OK;
635 silc_free(tmp->name);
641 SILC_CONFIG_CALLBACK(fetch_client)
643 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
645 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
646 type, name, context));
648 /* alloc tmp before block checking (empty sub-blocks are welcome here) */
650 config->tmp = silc_calloc(1, sizeof(*findtmp));
651 tmp = (SilcServerConfigClient *) config->tmp;
654 if (type == SILC_CONFIG_ARG_BLOCK) {
655 /* closing the block */
656 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
658 return SILC_CONFIG_OK;
661 /* Identify and save this value */
662 if (!strcmp(name, "host")) {
663 CONFIG_IS_DOUBLE(tmp->host);
664 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
666 else if (!strcmp(name, "passphrase")) {
667 CONFIG_IS_DOUBLE(tmp->passphrase);
668 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
669 (void **)&tmp->passphrase,
670 &tmp->passphrase_len)) {
671 got_errno = SILC_CONFIG_ESILENT;
675 else if (!strcmp(name, "publickey")) {
676 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
677 (void **)&tmp->publickeys, NULL)) {
678 got_errno = SILC_CONFIG_ESILENT;
682 else if (!strcmp(name, "params")) {
683 CONFIG_IS_DOUBLE(tmp->param);
684 tmp->param = my_find_param(config, (char *) val, line);
685 if (!tmp->param) { /* error already output */
686 got_errno = SILC_CONFIG_ESILENT;
691 return SILC_CONFIG_EINTERNAL;
692 return SILC_CONFIG_OK;
695 silc_free(tmp->host);
696 CONFIG_FREE_AUTH(tmp);
702 SILC_CONFIG_CALLBACK(fetch_admin)
704 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
706 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
707 type, name, context));
709 if (type == SILC_CONFIG_ARG_BLOCK) {
710 /* check the temporary struct's fields */
711 if (!tmp) /* empty sub-block? */
712 return SILC_CONFIG_OK;
714 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
716 return SILC_CONFIG_OK;
719 /* if there isn't a temporary struct alloc one */
721 config->tmp = silc_calloc(1, sizeof(*findtmp));
722 tmp = (SilcServerConfigAdmin *) config->tmp;
725 /* Identify and save this value */
726 if (!strcmp(name, "host")) {
727 CONFIG_IS_DOUBLE(tmp->host);
728 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
730 else if (!strcmp(name, "user")) {
731 CONFIG_IS_DOUBLE(tmp->user);
732 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
734 else if (!strcmp(name, "nick")) {
735 CONFIG_IS_DOUBLE(tmp->nick);
736 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
738 else if (!strcmp(name, "passphrase")) {
739 CONFIG_IS_DOUBLE(tmp->passphrase);
740 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
741 (void **)&tmp->passphrase,
742 &tmp->passphrase_len)) {
743 got_errno = SILC_CONFIG_ESILENT;
747 else if (!strcmp(name, "publickey")) {
748 CONFIG_IS_DOUBLE(tmp->publickeys);
749 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
750 (void **)&tmp->publickeys, NULL)) {
751 got_errno = SILC_CONFIG_ESILENT;
756 return SILC_CONFIG_EINTERNAL;
757 return SILC_CONFIG_OK;
760 silc_free(tmp->host);
761 silc_free(tmp->user);
762 silc_free(tmp->nick);
763 CONFIG_FREE_AUTH(tmp);
769 SILC_CONFIG_CALLBACK(fetch_deny)
771 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
773 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
774 type, name, context));
775 if (type == SILC_CONFIG_ARG_BLOCK) {
776 /* check the temporary struct's fields */
777 if (!tmp) /* empty sub-block? */
778 return SILC_CONFIG_OK;
780 got_errno = SILC_CONFIG_EMISSFIELDS;
783 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
785 return SILC_CONFIG_OK;
787 /* if there isn't a temporary struct alloc one */
789 config->tmp = silc_calloc(1, sizeof(*findtmp));
790 tmp = (SilcServerConfigDeny *) config->tmp;
793 /* Identify and save this value */
794 if (!strcmp(name, "host")) {
795 CONFIG_IS_DOUBLE(tmp->host);
796 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
798 else if (!strcmp(name, "reason")) {
799 CONFIG_IS_DOUBLE(tmp->reason);
800 tmp->reason = strdup((char *) val);
803 return SILC_CONFIG_EINTERNAL;
804 return SILC_CONFIG_OK;
807 silc_free(tmp->host);
808 silc_free(tmp->reason);
814 SILC_CONFIG_CALLBACK(fetch_server)
816 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
818 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
819 type, name, context));
821 if (type == SILC_CONFIG_ARG_BLOCK) {
822 /* check the temporary struct's fields */
823 if (!tmp) /* empty sub-block? */
824 return SILC_CONFIG_OK;
826 /* the temporary struct is ok, append it to the list */
827 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
829 return SILC_CONFIG_OK;
832 /* if there isn't a temporary struct alloc one */
834 config->tmp = silc_calloc(1, sizeof(*findtmp));
835 tmp = (SilcServerConfigServer *) config->tmp;
838 /* Identify and save this value */
839 if (!strcmp(name, "host")) {
840 CONFIG_IS_DOUBLE(tmp->host);
841 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
843 else if (!strcmp(name, "passphrase")) {
844 CONFIG_IS_DOUBLE(tmp->passphrase);
845 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
846 (void **)&tmp->passphrase,
847 &tmp->passphrase_len)) {
848 got_errno = SILC_CONFIG_ESILENT;
852 else if (!strcmp(name, "publickey")) {
853 CONFIG_IS_DOUBLE(tmp->publickeys);
854 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
855 (void **)&tmp->publickeys, NULL)) {
856 got_errno = SILC_CONFIG_ESILENT;
860 else if (!strcmp(name, "versionid")) {
861 CONFIG_IS_DOUBLE(tmp->version);
862 tmp->version = strdup((char *) val);
864 else if (!strcmp(name, "params")) {
865 CONFIG_IS_DOUBLE(tmp->param);
866 tmp->param = my_find_param(config, (char *) val, line);
867 if (!tmp->param) { /* error already output */
868 got_errno = SILC_CONFIG_ESILENT;
872 else if (!strcmp(name, "backup")) {
873 tmp->backup_router = *(bool *)val;
876 return SILC_CONFIG_EINTERNAL;
878 return SILC_CONFIG_OK;
881 silc_free(tmp->host);
882 silc_free(tmp->version);
883 CONFIG_FREE_AUTH(tmp);
889 SILC_CONFIG_CALLBACK(fetch_router)
891 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
893 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
894 type, name, context));
896 if (type == SILC_CONFIG_ARG_BLOCK) {
897 if (!tmp) /* empty sub-block? */
898 return SILC_CONFIG_OK;
900 /* the temporary struct is ok, append it to the list */
901 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
903 return SILC_CONFIG_OK;
906 /* if there isn't a temporary struct alloc one */
908 config->tmp = silc_calloc(1, sizeof(*findtmp));
909 tmp = (SilcServerConfigRouter *) config->tmp;
912 /* Identify and save this value */
913 if (!strcmp(name, "host")) {
914 CONFIG_IS_DOUBLE(tmp->host);
915 tmp->host = strdup((char *) val);
917 else if (!strcmp(name, "port")) {
918 int port = *(int *)val;
919 if ((port <= 0) || (port > 65535)) {
920 fprintf(stderr, "Invalid port number!\n");
921 return SILC_CONFIG_ESILENT;
923 tmp->port = (SilcUInt16) port;
925 else if (!strcmp(name, "passphrase")) {
926 CONFIG_IS_DOUBLE(tmp->passphrase);
927 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
928 (void **)&tmp->passphrase,
929 &tmp->passphrase_len)) {
930 got_errno = SILC_CONFIG_ESILENT;
934 else if (!strcmp(name, "publickey")) {
935 CONFIG_IS_DOUBLE(tmp->publickeys);
936 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
937 (void **)&tmp->publickeys, NULL)) {
938 got_errno = SILC_CONFIG_ESILENT;
942 else if (!strcmp(name, "versionid")) {
943 CONFIG_IS_DOUBLE(tmp->version);
944 tmp->version = strdup((char *) val);
946 else if (!strcmp(name, "params")) {
947 CONFIG_IS_DOUBLE(tmp->param);
948 tmp->param = my_find_param(config, (char *) val, line);
949 if (!tmp->param) { /* error already output */
950 got_errno = SILC_CONFIG_ESILENT;
954 else if (!strcmp(name, "initiator")) {
955 tmp->initiator = *(bool *)val;
957 else if (!strcmp(name, "backuphost")) {
958 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
959 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
962 else if (!strcmp(name, "backupport")) {
963 int port = *(int *)val;
964 if ((port <= 0) || (port > 65535)) {
965 fprintf(stderr, "Invalid port number!\n");
966 return SILC_CONFIG_ESILENT;
968 tmp->backup_replace_port = (SilcUInt16) port;
970 else if (!strcmp(name, "backuplocal")) {
971 tmp->backup_local = *(bool *)val;
974 return SILC_CONFIG_EINTERNAL;
976 return SILC_CONFIG_OK;
979 silc_free(tmp->host);
980 silc_free(tmp->version);
981 silc_free(tmp->backup_replace_ip);
982 CONFIG_FREE_AUTH(tmp);
988 /* known config options tables */
989 static const SilcConfigTable table_general[] = {
990 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
991 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
992 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
993 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
994 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
995 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
996 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
997 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
998 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
999 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1000 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1001 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
1002 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1003 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1004 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
1008 static const SilcConfigTable table_cipher[] = {
1009 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
1010 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
1011 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1012 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
1016 static const SilcConfigTable table_hash[] = {
1017 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
1018 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
1019 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1020 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1024 static const SilcConfigTable table_hmac[] = {
1025 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1026 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1027 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1031 static const SilcConfigTable table_pkcs[] = {
1032 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1036 static const SilcConfigTable table_serverinfo[] = {
1037 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1038 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1039 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1040 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1041 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1042 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1043 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1044 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1045 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1046 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1047 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1048 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1049 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1053 static const SilcConfigTable table_logging_c[] = {
1054 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1055 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1056 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1060 static const SilcConfigTable table_logging[] = {
1061 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1062 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1063 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1064 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1065 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1066 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1070 static const SilcConfigTable table_connparam[] = {
1071 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1072 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1073 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1074 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1075 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1076 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1077 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1078 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1079 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1080 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1081 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1085 static const SilcConfigTable table_client[] = {
1086 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1087 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1088 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1089 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1093 static const SilcConfigTable table_admin[] = {
1094 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1095 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1096 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1097 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1098 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1099 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1100 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1104 static const SilcConfigTable table_deny[] = {
1105 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1106 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1110 static const SilcConfigTable table_serverconn[] = {
1111 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1112 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1113 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1114 { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1115 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1116 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1120 static const SilcConfigTable table_routerconn[] = {
1121 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1122 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1123 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1124 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1125 { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1126 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1127 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1128 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1129 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1130 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1134 static const SilcConfigTable table_main[] = {
1135 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1136 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1137 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1138 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1139 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1140 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1141 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1142 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1143 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1144 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1145 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1146 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1147 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1151 /* Allocates a new configuration object, opens configuration file and
1152 * parses it. The parsed data is returned to the newly allocated
1153 * configuration object. */
1155 SilcServerConfig silc_server_config_alloc(char *filename)
1157 SilcServerConfig config;
1158 SilcConfigEntity ent;
1159 SilcConfigFile *file;
1161 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1163 /* alloc a config object */
1164 config = (SilcServerConfig) silc_calloc(1, sizeof(*config));
1165 /* obtain a config file object */
1166 file = silc_config_open(filename);
1168 fprintf(stderr, "\nError: can't open config file `%s'\n", filename);
1171 /* obtain a SilcConfig entity, we can use it to start the parsing */
1172 ent = silc_config_init(file);
1173 /* load the known configuration options, give our empty object as context */
1174 silc_config_register_table(ent, table_main, (void *) config);
1175 /* enter the main parsing loop. When this returns, we have the parsing
1176 * result and the object filled (or partially, in case of errors). */
1177 ret = silc_config_main(ent);
1178 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1179 silc_config_strerror(ret)));
1181 /* Check if the parser returned errors */
1183 /* handle this special error return which asks to quietly return */
1184 if (ret != SILC_CONFIG_ESILENT) {
1185 char *linebuf, *filename = silc_config_get_filename(file);
1186 SilcUInt32 line = silc_config_get_line(file);
1187 fprintf(stderr, "\nError while parsing config file: %s.\n",
1188 silc_config_strerror(ret));
1189 linebuf = silc_config_read_line(file, line);
1190 fprintf(stderr, " file %s line %lu: %s\n\n", filename, line, linebuf);
1195 /* close (destroy) the file object */
1196 silc_config_close(file);
1198 /* XXX FIXME: check for missing mandatory fields */
1199 if (!config->server_info) {
1200 fprintf(stderr, "\nError: Missing mandatory block `server_info'\n");
1208 void silc_server_config_destroy(SilcServerConfig config)
1211 silc_free(config->module_path);
1213 /* Destroy Logging channels */
1214 if (config->logging_info)
1215 silc_free(config->logging_info->file);
1216 if (config->logging_warnings)
1217 silc_free(config->logging_warnings->file);
1218 if (config->logging_errors)
1219 silc_free(config->logging_errors->file);
1220 if (config->logging_fatals)
1221 silc_free(config->logging_fatals->file);
1223 /* Destroy the ServerInfo struct */
1224 if (config->server_info) {
1225 register SilcServerConfigServerInfo *si = config->server_info;
1226 silc_free(si->server_name);
1227 silc_free(si->server_ip);
1228 silc_free(si->server_type);
1229 silc_free(si->location);
1230 silc_free(si->admin);
1231 silc_free(si->email);
1232 silc_free(si->user);
1233 silc_free(si->group);
1234 silc_free(si->motd_file);
1235 silc_free(si->pid_file);
1238 /* Now let's destroy the lists */
1240 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1242 silc_free(di->name);
1243 silc_free(di->module);
1246 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1247 silc_free(di->name);
1248 silc_free(di->module);
1251 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1252 silc_free(di->name);
1253 silc_free(di->hash);
1256 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1257 silc_free(di->name);
1260 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient,
1262 silc_free(di->host);
1263 CONFIG_FREE_AUTH(di);
1266 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1267 silc_free(di->host);
1268 silc_free(di->user);
1269 silc_free(di->nick);
1270 CONFIG_FREE_AUTH(di);
1273 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1274 silc_free(di->host);
1275 silc_free(di->reason);
1278 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1280 silc_free(di->host);
1281 silc_free(di->version);
1282 CONFIG_FREE_AUTH(di);
1285 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1287 silc_free(di->host);
1288 silc_free(di->version);
1289 silc_free(di->backup_replace_ip);
1290 CONFIG_FREE_AUTH(di);
1295 /* Registers configured ciphers. These can then be allocated by the
1296 server when needed. */
1298 bool silc_server_config_register_ciphers(SilcServer server)
1300 SilcServerConfig config = server->config;
1301 SilcServerConfigCipher *cipher = config->cipher;
1302 char *module_path = config->module_path;
1304 SILC_LOG_DEBUG(("Registering configured ciphers"));
1306 if (!cipher) /* any cipher in the config file? */
1310 /* if there isn't a module_path OR there isn't a module sim name try to
1311 * use buil-in functions */
1312 if (!module_path || !cipher->module) {
1314 for (i = 0; silc_default_ciphers[i].name; i++)
1315 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1316 silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
1319 if (!silc_cipher_is_supported(cipher->name)) {
1320 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1321 silc_server_stop(server);
1326 /* Load (try at least) the crypto SIM module */
1327 char buf[1023], *alg_name;
1328 SilcCipherObject cipher_obj;
1331 memset(&cipher_obj, 0, sizeof(cipher_obj));
1332 cipher_obj.name = cipher->name;
1333 cipher_obj.block_len = cipher->block_length;
1334 cipher_obj.key_len = cipher->key_length * 8;
1336 /* build the libname */
1337 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1339 sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
1341 alg_name = strdup(cipher->name);
1342 if (strchr(alg_name, '-'))
1343 *strchr(alg_name, '-') = '\0';
1345 if (silc_sim_load(sim)) {
1346 cipher_obj.set_key =
1347 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1348 SILC_CIPHER_SIM_SET_KEY));
1349 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1350 cipher_obj.set_key_with_string =
1351 silc_sim_getsym(sim,
1352 silc_sim_symname(alg_name,
1353 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1354 SILC_LOG_DEBUG(("set_key_with_string=%p",
1355 cipher_obj.set_key_with_string));
1356 cipher_obj.encrypt =
1357 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1358 SILC_CIPHER_SIM_ENCRYPT_CBC));
1359 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1360 cipher_obj.decrypt =
1361 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1362 SILC_CIPHER_SIM_DECRYPT_CBC));
1363 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1364 cipher_obj.context_len =
1365 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1366 SILC_CIPHER_SIM_CONTEXT_LEN));
1367 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1369 /* Put the SIM to the list of all SIM's in server */
1370 silc_dlist_add(server->sim, sim);
1372 silc_free(alg_name);
1374 SILC_LOG_ERROR(("Error configuring ciphers"));
1375 silc_server_stop(server);
1379 /* Register the cipher */
1380 silc_cipher_register(&cipher_obj);
1382 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1383 "can't load modules!"));
1384 silc_server_stop(server);
1388 cipher = cipher->next;
1394 /* Registers configured hash functions. These can then be allocated by the
1395 server when needed. */
1397 bool silc_server_config_register_hashfuncs(SilcServer server)
1399 SilcServerConfig config = server->config;
1400 SilcServerConfigHash *hash = config->hash;
1401 char *module_path = config->module_path;
1403 SILC_LOG_DEBUG(("Registering configured hash functions"));
1405 if (!hash) /* any hash func in the config file? */
1409 /* if there isn't a module_path OR there isn't a module sim name try to
1410 * use buil-in functions */
1411 if (!module_path || !hash->module) {
1413 for (i = 0; silc_default_hash[i].name; i++)
1414 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1415 silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
1418 if (!silc_hash_is_supported(hash->name)) {
1419 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1420 silc_server_stop(server);
1425 /* Load (try at least) the hash SIM module */
1426 SilcHashObject hash_obj;
1429 memset(&hash_obj, 0, sizeof(hash_obj));
1430 hash_obj.name = hash->name;
1431 hash_obj.block_len = hash->block_length;
1432 hash_obj.hash_len = hash->digest_length;
1434 sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
1436 if ((silc_sim_load(sim))) {
1438 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1439 SILC_HASH_SIM_INIT));
1440 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1442 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1443 SILC_HASH_SIM_UPDATE));
1444 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1446 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1447 SILC_HASH_SIM_FINAL));
1448 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1449 hash_obj.context_len =
1450 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1451 SILC_HASH_SIM_CONTEXT_LEN));
1452 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1454 /* Put the SIM to the table of all SIM's in server */
1455 silc_dlist_add(server->sim, sim);
1457 SILC_LOG_ERROR(("Error configuring hash functions"));
1458 silc_server_stop(server);
1462 /* Register the hash function */
1463 silc_hash_register(&hash_obj);
1465 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1466 "can't load modules!"));
1467 silc_server_stop(server);
1477 /* Registers configure HMACs. These can then be allocated by the server
1480 bool silc_server_config_register_hmacs(SilcServer server)
1482 SilcServerConfig config = server->config;
1483 SilcServerConfigHmac *hmac = config->hmac;
1485 SILC_LOG_DEBUG(("Registering configured HMACs"));
1491 SilcHmacObject hmac_obj;
1492 if (!silc_hash_is_supported(hmac->hash)) {
1493 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1494 silc_server_stop(server);
1498 /* Register the HMAC */
1499 memset(&hmac_obj, 0, sizeof(hmac_obj));
1500 hmac_obj.name = hmac->name;
1501 hmac_obj.len = hmac->mac_length;
1502 silc_hmac_register(&hmac_obj);
1510 /* Registers configured PKCS's. */
1512 bool silc_server_config_register_pkcs(SilcServer server)
1514 SilcServerConfig config = server->config;
1515 SilcServerConfigPkcs *pkcs = config->pkcs;
1517 SILC_LOG_DEBUG(("Registering configured PKCS"));
1524 for (i = 0; silc_default_pkcs[i].name; i++)
1525 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1526 silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
1529 if (!silc_pkcs_is_supported(pkcs->name)) {
1530 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1531 silc_server_stop(server);
1540 /* Sets log files where log messages are saved by the server logger. */
1542 void silc_server_config_setlogfiles(SilcServer server)
1544 SilcServerConfig config = server->config;
1545 SilcServerConfigLogging *this;
1547 SILC_LOG_DEBUG(("Setting configured log file names"));
1549 if ((this = config->logging_info))
1550 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1552 if ((this = config->logging_warnings))
1553 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1555 if ((this = config->logging_errors))
1556 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1558 if ((this = config->logging_fatals))
1559 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1563 /* Returns client authentication information from configuration file by host
1566 SilcServerConfigClient *
1567 silc_server_config_find_client(SilcServer server, char *host)
1569 SilcServerConfig config = server->config;
1570 SilcServerConfigClient *client;
1572 if (!config || !host)
1575 for (client = config->clients; client; client = client->next) {
1576 if (client->host && !silc_string_compare(client->host, host))
1581 /* if none matched, then client is already NULL */
1585 /* Returns admin connection configuration by host, username and/or
1588 SilcServerConfigAdmin *
1589 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1592 SilcServerConfig config = server->config;
1593 SilcServerConfigAdmin *admin;
1595 /* make sure we have a value for the matching parameters */
1603 for (admin = config->admins; admin; admin = admin->next) {
1604 if (admin->host && !silc_string_compare(admin->host, host))
1606 if (admin->user && !silc_string_compare(admin->user, user))
1608 if (admin->nick && !silc_string_compare(admin->nick, nick))
1610 /* no checks failed -> this entry matches */
1614 /* if none matched, then admin is already NULL */
1618 /* Returns the denied connection configuration entry by host. */
1620 SilcServerConfigDeny *
1621 silc_server_config_find_denied(SilcServer server, char *host)
1623 SilcServerConfig config = server->config;
1624 SilcServerConfigDeny *deny;
1626 /* make sure we have a value for the matching parameters */
1627 if (!config || !host)
1630 for (deny = config->denied; deny; deny = deny->next) {
1631 if (deny->host && !silc_string_compare(deny->host, host))
1636 /* if none matched, then deny is already NULL */
1640 /* Returns server connection info from server configuartion by host
1643 SilcServerConfigServer *
1644 silc_server_config_find_server_conn(SilcServer server, char *host)
1646 SilcServerConfig config = server->config;
1647 SilcServerConfigServer *serv = NULL;
1652 if (!config->servers)
1655 for (serv = config->servers; serv; serv = serv->next) {
1656 if (!silc_string_compare(serv->host, host))
1664 /* Returns router connection info from server configuration by
1665 host (name or ip). */
1667 SilcServerConfigRouter *
1668 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1670 SilcServerConfig config = server->config;
1671 SilcServerConfigRouter *serv = NULL;
1676 if (!config->routers)
1679 for (serv = config->routers; serv; serv = serv->next) {
1680 if (!silc_string_compare(serv->host, host))
1682 if (port && serv->port && serv->port != port)
1690 /* Returns TRUE if configuration for a router connection that we are
1691 initiating exists. */
1693 bool silc_server_config_is_primary_route(SilcServer server)
1695 SilcServerConfig config = server->config;
1696 SilcServerConfigRouter *serv = NULL;
1700 serv = config->routers;
1701 for (i = 0; serv; i++) {
1702 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1713 /* Returns our primary connection configuration or NULL if we do not
1714 have primary router configured. */
1716 SilcServerConfigRouter *
1717 silc_server_config_get_primary_router(SilcServer server)
1719 SilcServerConfig config = server->config;
1720 SilcServerConfigRouter *serv = NULL;
1723 serv = config->routers;
1724 for (i = 0; serv; i++) {
1725 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1733 /* Set default values to stuff that was not configured. */
1735 bool silc_server_config_set_defaults(SilcServer server)
1737 SilcServerConfig config = server->config;
1739 my_set_param_defaults(&config->param, NULL);
1741 config->channel_rekey_secs = (config->channel_rekey_secs ?
1742 config->channel_rekey_secs :
1743 SILC_SERVER_CHANNEL_REKEY);
1744 config->key_exchange_timeout = (config->key_exchange_timeout ?
1745 config->key_exchange_timeout :
1746 SILC_SERVER_SKE_TIMEOUT);
1747 config->conn_auth_timeout = (config->conn_auth_timeout ?
1748 config->conn_auth_timeout :
1749 SILC_SERVER_CONNAUTH_TIMEOUT);