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 silc_pkcs_public_key_free(__section__->publickey)
66 /* Set default values to those parameters that have not been defined */
68 my_set_param_defaults(SilcServerConfigConnParams *params,
69 SilcServerConfigConnParams *defaults)
71 #define SET_PARAM_DEFAULT(p, d) \
72 (params->p ? params->p : (defaults && defaults->p ? defaults->p : d))
74 params->connections_max =
75 SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
76 params->connections_max_per_host =
77 SET_PARAM_DEFAULT(connections_max_per_host,
78 SILC_SERVER_MAX_CONNECTIONS_SINGLE);
79 params->keepalive_secs =
80 SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
81 params->reconnect_count =
82 SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
83 params->reconnect_interval =
84 SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
85 params->reconnect_interval_max =
86 SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
87 params->key_exchange_rekey =
88 SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
91 /* Find connection parameters by the parameter block name. */
92 static SilcServerConfigConnParams *
93 my_find_param(SilcServerConfig config, const char *name, uint32 line)
95 SilcServerConfigConnParams *param;
97 for (param = config->conn_params; param; param = param->next) {
98 if (!strcasecmp(param->name, name))
102 fprintf(stderr, "\nError while parsing config file at line %lu: "
103 "Cannot find Param \"%s\".\n", line, name);
108 /* parse an authdata according to its auth method */
109 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line,
110 void **auth_data, uint32 *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 = (uint32) strlen(p);
118 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
119 /* p is a public key */
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 *auth_data = (void *) public_key;
133 fprintf(stderr, "\nError while parsing config file at line %lu: "
134 "Unknown authentication method.\n", line);
142 SILC_CONFIG_CALLBACK(fetch_generic)
144 SilcServerConfig config = (SilcServerConfig) context;
147 if (!strcmp(name, "module_path")) {
148 CONFIG_IS_DOUBLE(config->module_path);
149 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
151 else if (!strcmp(name, "prefer_passphrase_auth")) {
152 config->prefer_passphrase_auth = *(bool *)val;
154 else if (!strcmp(name, "require_reverse_lookup")) {
155 config->require_reverse_lookup = *(bool *)val;
157 else if (!strcmp(name, "connections_max")) {
158 config->param.connections_max = (uint32) *(int *)val;
160 else if (!strcmp(name, "connections_max_per_host")) {
161 config->param.connections_max_per_host = (uint32) *(int *)val;
163 else if (!strcmp(name, "keepalive_secs")) {
164 config->param.keepalive_secs = (uint32) *(int *)val;
166 else if (!strcmp(name, "reconnect_count")) {
167 config->param.reconnect_count = (uint32) *(int *)val;
169 else if (!strcmp(name, "reconnect_interval")) {
170 config->param.reconnect_interval = (uint32) *(int *)val;
172 else if (!strcmp(name, "reconnect_interval_max")) {
173 config->param.reconnect_interval_max = (uint32) *(int *)val;
175 else if (!strcmp(name, "reconnect_keep_trying")) {
176 config->param.reconnect_keep_trying = *(bool *)val;
178 else if (!strcmp(name, "key_exchange_rekey")) {
179 config->param.key_exchange_rekey = (uint32) *(int *)val;
181 else if (!strcmp(name, "key_exchange_pfs")) {
182 config->param.key_exchange_pfs = *(bool *)val;
184 else if (!strcmp(name, "channel_rekey_secs")) {
185 config->channel_rekey_secs = (uint32) *(int *)val;
187 else if (!strcmp(name, "key_exchange_timeout")) {
188 config->key_exchange_timeout = (uint32) *(int *)val;
190 else if (!strcmp(name, "conn_auth_timeout")) {
191 config->conn_auth_timeout = (uint32) *(int *)val;
194 return SILC_CONFIG_EINTERNAL;
196 return SILC_CONFIG_OK;
202 SILC_CONFIG_CALLBACK(fetch_cipher)
204 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher);
206 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
207 type, name, context));
208 if (type == SILC_CONFIG_ARG_BLOCK) {
209 /* check the temporary struct's fields */
210 if (!tmp) /* empty sub-block? */
211 return SILC_CONFIG_OK;
213 got_errno = SILC_CONFIG_EMISSFIELDS;
216 /* the temporary struct is ok, append it to the list */
217 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
219 return SILC_CONFIG_OK;
221 /* if there isn't a temporary struct alloc one */
223 config->tmp = silc_calloc(1, sizeof(*findtmp));
224 tmp = (SilcServerConfigCipher *) config->tmp;
227 /* Identify and save this value */
228 if (!strcmp(name, "name")) {
229 CONFIG_IS_DOUBLE(tmp->name);
230 tmp->name = strdup((char *) val);
232 else if (!strcmp(name, "module")) {
233 CONFIG_IS_DOUBLE(tmp->module);
234 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
236 else if (!strcmp(name, "keylength")) {
237 tmp->key_length = *(uint32 *)val;
239 else if (!strcmp(name, "blocklength")) {
240 tmp->block_length = *(uint32 *)val;
243 return SILC_CONFIG_EINTERNAL;
244 return SILC_CONFIG_OK;
247 silc_free(tmp->name);
248 silc_free(tmp->module);
254 SILC_CONFIG_CALLBACK(fetch_hash)
256 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash);
258 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
259 type, name, context));
260 if (type == SILC_CONFIG_ARG_BLOCK) {
261 /* check the temporary struct's fields */
262 if (!tmp) /* empty sub-block? */
263 return SILC_CONFIG_OK;
264 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
265 got_errno = SILC_CONFIG_EMISSFIELDS;
268 /* the temporary struct in tmp is ok */
269 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
271 return SILC_CONFIG_OK;
274 /* if there isn't a temporary struct alloc one */
276 config->tmp = silc_calloc(1, sizeof(*findtmp));
277 tmp = (SilcServerConfigHash *) config->tmp;
280 /* Identify and save this value */
281 if (!strcmp(name, "name")) {
282 CONFIG_IS_DOUBLE(tmp->name);
283 tmp->name = strdup((char *) val);
285 else if (!strcmp(name, "module")) {
286 CONFIG_IS_DOUBLE(tmp->module);
287 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
289 else if (!strcmp(name, "blocklength")) {
290 tmp->block_length = *(int *)val;
292 else if (!strcmp(name, "digestlength")) {
293 tmp->digest_length = *(int *)val;
296 return SILC_CONFIG_EINTERNAL;
297 return SILC_CONFIG_OK;
300 silc_free(tmp->name);
301 silc_free(tmp->module);
307 SILC_CONFIG_CALLBACK(fetch_hmac)
309 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac);
311 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
312 type, name, context));
313 if (type == SILC_CONFIG_ARG_BLOCK) {
314 /* check the temporary struct's fields */
315 if (!tmp) /* empty sub-block? */
316 return SILC_CONFIG_OK;
317 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
318 got_errno = SILC_CONFIG_EMISSFIELDS;
321 /* the temporary struct is ok, append it to the list */
322 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
324 return SILC_CONFIG_OK;
326 /* if there isn't a temporary struct alloc one */
328 config->tmp = silc_calloc(1, sizeof(*findtmp));
329 tmp = (SilcServerConfigHmac *) config->tmp;
332 /* Identify and save this value */
333 if (!strcmp(name, "name")) {
334 CONFIG_IS_DOUBLE(tmp->name);
335 tmp->name = strdup((char *) val);
337 else if (!strcmp(name, "hash")) {
338 CONFIG_IS_DOUBLE(tmp->hash);
339 tmp->hash = strdup((char *) val);
341 else if (!strcmp(name, "maclength")) {
342 tmp->mac_length = *(int *)val;
345 return SILC_CONFIG_EINTERNAL;
346 return SILC_CONFIG_OK;
349 silc_free(tmp->name);
350 silc_free(tmp->hash);
356 SILC_CONFIG_CALLBACK(fetch_pkcs)
358 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs);
360 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
361 type, name, context));
362 if (type == SILC_CONFIG_ARG_BLOCK) {
363 /* check the temporary struct's fields */
364 if (!tmp) /* empty sub-block? */
365 return SILC_CONFIG_OK;
367 got_errno = SILC_CONFIG_EMISSFIELDS;
370 /* the temporary struct is ok, append it to the list */
371 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
373 return SILC_CONFIG_OK;
375 /* if there isn't a temporary struct alloc one */
377 config->tmp = silc_calloc(1, sizeof(*findtmp));
378 tmp = (SilcServerConfigPkcs *) config->tmp;
381 /* Identify and save this value */
382 if (!strcmp(name, "name")) {
383 CONFIG_IS_DOUBLE(tmp->name);
384 tmp->name = strdup((char *) val);
387 return SILC_CONFIG_EINTERNAL;
388 return SILC_CONFIG_OK;
391 silc_free(tmp->name);
397 SILC_CONFIG_CALLBACK(fetch_serverinfo)
399 SilcServerConfig config = (SilcServerConfig) context;
400 SilcServerConfigServerInfo *server_info = config->server_info;
403 /* if there isn't the struct alloc it */
405 config->server_info = server_info = (SilcServerConfigServerInfo *)
406 silc_calloc(1, sizeof(*server_info));
408 if (type == SILC_CONFIG_ARG_BLOCK) {
409 /* check for mandatory inputs */
410 return SILC_CONFIG_OK;
412 if (!strcmp(name, "hostname")) {
413 CONFIG_IS_DOUBLE(server_info->server_name);
414 server_info->server_name = strdup((char *) val);
416 else if (!strcmp(name, "ip")) {
417 CONFIG_IS_DOUBLE(server_info->server_ip);
418 server_info->server_ip = strdup((char *) val);
420 else if (!strcmp(name, "port")) {
421 int port = *(int *)val;
422 if ((port <= 0) || (port > 65535)) {
423 fprintf(stderr, "Invalid port number!\n");
424 return SILC_CONFIG_ESILENT;
426 server_info->port = (uint16) port;
428 else if (!strcmp(name, "servertype")) {
429 CONFIG_IS_DOUBLE(server_info->server_type);
430 server_info->server_type = strdup((char *) val);
432 else if (!strcmp(name, "admin")) {
433 CONFIG_IS_DOUBLE(server_info->admin);
434 server_info->admin = strdup((char *) val);
436 else if (!strcmp(name, "adminemail")) {
437 CONFIG_IS_DOUBLE(server_info->email);
438 server_info->email = strdup((char *) val);
440 else if (!strcmp(name, "location")) {
441 CONFIG_IS_DOUBLE(server_info->location);
442 server_info->location = strdup((char *) val);
444 else if (!strcmp(name, "user")) {
445 CONFIG_IS_DOUBLE(server_info->user);
446 server_info->user = strdup((char *) val);
448 else if (!strcmp(name, "group")) {
449 CONFIG_IS_DOUBLE(server_info->group);
450 server_info->group = strdup((char *) val);
452 else if (!strcmp(name, "motdfile")) {
453 CONFIG_IS_DOUBLE(server_info->motd_file);
454 server_info->motd_file = strdup((char *) val);
456 else if (!strcmp(name, "pidfile")) {
457 CONFIG_IS_DOUBLE(server_info->pid_file);
458 server_info->pid_file = strdup((char *) val);
460 else if (!strcmp(name, "publickey")) {
461 char *tmp = (char *) val;
463 /* try to load specified file, if fail stop config parsing */
464 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
466 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
467 SILC_PKCS_FILE_BIN)) {
468 fprintf(stderr, "\nError: Could not load public key file.");
469 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
470 return SILC_CONFIG_ESILENT;
473 else if (!strcmp(name, "privatekey")) {
474 char *tmp = (char *) val;
476 /* try to load specified file, if fail stop config parsing */
477 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
479 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
480 SILC_PKCS_FILE_PEM)) {
481 fprintf(stderr, "\nError: Could not load private key file.");
482 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
483 return SILC_CONFIG_ESILENT;
487 return SILC_CONFIG_EINTERNAL;
488 return SILC_CONFIG_OK;
494 SILC_CONFIG_CALLBACK(fetch_logging)
496 SilcServerConfig config = (SilcServerConfig) context;
497 SilcServerConfigLogging *tmp =
498 (SilcServerConfigLogging *) config->tmp;
501 if (!strcmp(name, "quicklogs")) {
502 silc_log_quick = *(bool *)val;
504 else if (!strcmp(name, "flushdelay")) {
505 int flushdelay = *(int *)val;
506 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
507 fprintf(stderr, "Error: line %lu: invalid flushdelay value, use "
508 "quicklogs if you want real-time logging.\n", line);
509 return SILC_CONFIG_ESILENT;
511 silc_log_flushdelay = (long) flushdelay;
513 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
514 else if (!strcmp(name, __chan__)) { \
515 if (!tmp) return SILC_CONFIG_OK; \
517 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
519 config->__member__ = tmp; \
520 config->tmp = NULL; \
522 FETCH_LOGGING_CHAN("info", logging_info)
523 FETCH_LOGGING_CHAN("warnings", logging_warnings)
524 FETCH_LOGGING_CHAN("errors", logging_errors)
525 FETCH_LOGGING_CHAN("fatals", logging_fatals)
526 #undef FETCH_LOGGING_CHAN
527 else if (!strcmp(name, "file")) {
528 if (!tmp) { /* FIXME: what the fuck is this? */
529 config->tmp = silc_calloc(1, sizeof(*tmp));
530 tmp = (SilcServerConfigLogging *) config->tmp;
533 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
535 tmp->file = strdup((char *) val);
537 else if (!strcmp(name, "size")) {
539 config->tmp = silc_calloc(1, sizeof(*tmp));
540 tmp = (SilcServerConfigLogging *) config->tmp;
542 tmp->maxsize = *(uint32 *) val;
545 return SILC_CONFIG_EINTERNAL;
546 return SILC_CONFIG_OK;
549 silc_free(tmp->file);
555 SILC_CONFIG_CALLBACK(fetch_connparam)
557 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams);
559 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
560 type, name, context));
562 if (type == SILC_CONFIG_ARG_BLOCK) {
564 return SILC_CONFIG_OK;
567 got_errno = SILC_CONFIG_EMISSFIELDS;
572 my_set_param_defaults(tmp, &config->param);
574 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
576 return SILC_CONFIG_OK;
579 /* if there isn't a temporary struct alloc one */
581 config->tmp = silc_calloc(1, sizeof(*findtmp));
582 tmp = (SilcServerConfigConnParams *) config->tmp;
585 if (!strcmp(name, "name")) {
586 CONFIG_IS_DOUBLE(tmp->name);
587 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
589 else if (!strcmp(name, "connections_max")) {
590 tmp->connections_max = *(uint32 *)val;
592 else if (!strcmp(name, "connections_max_per_host")) {
593 tmp->connections_max_per_host = *(uint32 *)val;
595 else if (!strcmp(name, "keepalive_secs")) {
596 tmp->keepalive_secs = *(uint32 *)val;
598 else if (!strcmp(name, "reconnect_count")) {
599 tmp->reconnect_count = *(uint32 *)val;
601 else if (!strcmp(name, "reconnect_interval")) {
602 tmp->reconnect_interval = *(uint32 *)val;
604 else if (!strcmp(name, "reconnect_interval_max")) {
605 tmp->reconnect_interval_max = *(uint32 *)val;
607 else if (!strcmp(name, "reconnect_keep_trying")) {
608 tmp->reconnect_keep_trying = *(bool *)val;
610 else if (!strcmp(name, "key_exchange_rekey")) {
611 tmp->key_exchange_rekey = *(uint32 *)val;
613 else if (!strcmp(name, "key_exchange_pfs")) {
614 tmp->key_exchange_pfs = *(bool *)val;
617 return SILC_CONFIG_EINTERNAL;
619 return SILC_CONFIG_OK;
622 silc_free(tmp->name);
628 SILC_CONFIG_CALLBACK(fetch_client)
630 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient);
632 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
633 type, name, context));
635 /* alloc tmp before block checking (empty sub-blocks are welcome here) */
637 config->tmp = silc_calloc(1, sizeof(*findtmp));
638 tmp = (SilcServerConfigClient *) config->tmp;
641 if (type == SILC_CONFIG_ARG_BLOCK) {
642 /* closing the block */
643 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
645 return SILC_CONFIG_OK;
648 /* Identify and save this value */
649 if (!strcmp(name, "host")) {
650 CONFIG_IS_DOUBLE(tmp->host);
651 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
653 else if (!strcmp(name, "passphrase")) {
654 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
655 (void **)&tmp->passphrase,
656 &tmp->passphrase_len)) {
657 got_errno = SILC_CONFIG_ESILENT;
661 else if (!strcmp(name, "publickey")) {
662 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
663 &tmp->publickey, NULL)) {
664 got_errno = SILC_CONFIG_ESILENT;
668 else if (!strcmp(name, "params")) {
669 CONFIG_IS_DOUBLE(tmp->param);
670 tmp->param = my_find_param(config, (char *) val, line);
671 if (!tmp->param) { /* error already output */
672 got_errno = SILC_CONFIG_ESILENT;
677 return SILC_CONFIG_EINTERNAL;
678 return SILC_CONFIG_OK;
681 silc_free(tmp->host);
682 CONFIG_FREE_AUTH(tmp);
688 SILC_CONFIG_CALLBACK(fetch_admin)
690 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin);
692 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
693 type, name, context));
695 if (type == SILC_CONFIG_ARG_BLOCK) {
696 /* check the temporary struct's fields */
697 if (!tmp) /* empty sub-block? */
698 return SILC_CONFIG_OK;
700 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
702 return SILC_CONFIG_OK;
705 /* if there isn't a temporary struct alloc one */
707 config->tmp = silc_calloc(1, sizeof(*findtmp));
708 tmp = (SilcServerConfigAdmin *) config->tmp;
711 /* Identify and save this value */
712 if (!strcmp(name, "host")) {
713 CONFIG_IS_DOUBLE(tmp->host);
714 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
716 else if (!strcmp(name, "user")) {
717 CONFIG_IS_DOUBLE(tmp->user);
718 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
720 else if (!strcmp(name, "nick")) {
721 CONFIG_IS_DOUBLE(tmp->nick);
722 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
724 else if (!strcmp(name, "passphrase")) {
725 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
726 (void **)&tmp->passphrase,
727 &tmp->passphrase_len)) {
728 got_errno = SILC_CONFIG_ESILENT;
732 else if (!strcmp(name, "publickey")) {
733 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
734 &tmp->publickey, NULL)) {
735 got_errno = SILC_CONFIG_ESILENT;
740 return SILC_CONFIG_EINTERNAL;
741 return SILC_CONFIG_OK;
744 silc_free(tmp->host);
745 silc_free(tmp->user);
746 silc_free(tmp->nick);
747 CONFIG_FREE_AUTH(tmp);
753 SILC_CONFIG_CALLBACK(fetch_deny)
755 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny);
757 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
758 type, name, context));
759 if (type == SILC_CONFIG_ARG_BLOCK) {
760 /* check the temporary struct's fields */
761 if (!tmp) /* empty sub-block? */
762 return SILC_CONFIG_OK;
764 got_errno = SILC_CONFIG_EMISSFIELDS;
767 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
769 return SILC_CONFIG_OK;
771 /* if there isn't a temporary struct alloc one */
773 config->tmp = silc_calloc(1, sizeof(*findtmp));
774 tmp = (SilcServerConfigDeny *) config->tmp;
777 /* Identify and save this value */
778 if (!strcmp(name, "host")) {
779 CONFIG_IS_DOUBLE(tmp->host);
780 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
782 else if (!strcmp(name, "reason")) {
783 CONFIG_IS_DOUBLE(tmp->reason);
784 tmp->reason = strdup((char *) val);
787 return SILC_CONFIG_EINTERNAL;
788 return SILC_CONFIG_OK;
791 silc_free(tmp->host);
792 silc_free(tmp->reason);
798 SILC_CONFIG_CALLBACK(fetch_server)
800 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer);
802 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
803 type, name, context));
805 if (type == SILC_CONFIG_ARG_BLOCK) {
806 /* check the temporary struct's fields */
807 if (!tmp) /* empty sub-block? */
808 return SILC_CONFIG_OK;
810 /* the temporary struct is ok, append it to the list */
811 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
813 return SILC_CONFIG_OK;
816 /* if there isn't a temporary struct alloc one */
818 config->tmp = silc_calloc(1, sizeof(*findtmp));
819 tmp = (SilcServerConfigServer *) config->tmp;
822 /* Identify and save this value */
823 if (!strcmp(name, "host")) {
824 CONFIG_IS_DOUBLE(tmp->host);
825 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
827 else if (!strcmp(name, "passphrase")) {
828 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
829 (void **)&tmp->passphrase,
830 &tmp->passphrase_len)) {
831 got_errno = SILC_CONFIG_ESILENT;
835 else if (!strcmp(name, "publickey")) {
836 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
837 &tmp->publickey, NULL)) {
838 got_errno = SILC_CONFIG_ESILENT;
842 else if (!strcmp(name, "versionid")) {
843 CONFIG_IS_DOUBLE(tmp->version);
844 tmp->version = strdup((char *) val);
846 else if (!strcmp(name, "params")) {
847 CONFIG_IS_DOUBLE(tmp->param);
848 tmp->param = my_find_param(config, (char *) val, line);
849 if (!tmp->param) { /* error already output */
850 got_errno = SILC_CONFIG_ESILENT;
854 else if (!strcmp(name, "backup")) {
855 tmp->backup_router = *(bool *)val;
858 return SILC_CONFIG_EINTERNAL;
860 return SILC_CONFIG_OK;
863 silc_free(tmp->host);
864 silc_free(tmp->version);
865 CONFIG_FREE_AUTH(tmp);
871 SILC_CONFIG_CALLBACK(fetch_router)
873 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter);
875 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
876 type, name, context));
878 if (type == SILC_CONFIG_ARG_BLOCK) {
879 if (!tmp) /* empty sub-block? */
880 return SILC_CONFIG_OK;
882 /* the temporary struct is ok, append it to the list */
883 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
885 return SILC_CONFIG_OK;
888 /* if there isn't a temporary struct alloc one */
890 config->tmp = silc_calloc(1, sizeof(*findtmp));
891 tmp = (SilcServerConfigRouter *) config->tmp;
894 /* Identify and save this value */
895 if (!strcmp(name, "host")) {
896 CONFIG_IS_DOUBLE(tmp->host);
897 tmp->host = strdup((char *) val);
899 else if (!strcmp(name, "port")) {
900 int port = *(int *)val;
901 if ((port <= 0) || (port > 65535)) {
902 fprintf(stderr, "Invalid port number!\n");
903 return SILC_CONFIG_ESILENT;
905 tmp->port = (uint16) port;
907 else if (!strcmp(name, "passphrase")) {
908 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
909 (void **)&tmp->passphrase,
910 &tmp->passphrase_len)) {
911 got_errno = SILC_CONFIG_ESILENT;
915 else if (!strcmp(name, "publickey")) {
916 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
917 &tmp->publickey, NULL)) {
918 got_errno = SILC_CONFIG_ESILENT;
922 else if (!strcmp(name, "versionid")) {
923 CONFIG_IS_DOUBLE(tmp->version);
924 tmp->version = strdup((char *) val);
926 else if (!strcmp(name, "params")) {
927 CONFIG_IS_DOUBLE(tmp->param);
928 tmp->param = my_find_param(config, (char *) val, line);
929 if (!tmp->param) { /* error already output */
930 got_errno = SILC_CONFIG_ESILENT;
934 else if (!strcmp(name, "initiator")) {
935 tmp->initiator = *(bool *)val;
937 else if (!strcmp(name, "backuphost")) {
938 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
939 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
942 else if (!strcmp(name, "backupport")) {
943 int port = *(int *)val;
944 if ((port <= 0) || (port > 65535)) {
945 fprintf(stderr, "Invalid port number!\n");
946 return SILC_CONFIG_ESILENT;
948 tmp->backup_replace_port = (uint16) port;
950 else if (!strcmp(name, "backuplocal")) {
951 tmp->backup_local = *(bool *)val;
954 return SILC_CONFIG_EINTERNAL;
956 return SILC_CONFIG_OK;
959 silc_free(tmp->host);
960 silc_free(tmp->version);
961 silc_free(tmp->backup_replace_ip);
962 CONFIG_FREE_AUTH(tmp);
968 /* known config options tables */
969 static const SilcConfigTable table_general[] = {
970 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
971 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
972 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
973 { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
974 { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
975 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
976 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
977 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
978 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
979 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
980 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
981 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
982 { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
983 { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
984 { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
988 static const SilcConfigTable table_cipher[] = {
989 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
990 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
991 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
992 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
996 static const SilcConfigTable table_hash[] = {
997 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
998 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
999 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1000 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
1004 static const SilcConfigTable table_hmac[] = {
1005 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1006 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
1007 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
1011 static const SilcConfigTable table_pkcs[] = {
1012 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
1016 static const SilcConfigTable table_serverinfo[] = {
1017 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1018 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1019 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
1020 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1021 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1022 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1023 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1024 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1025 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1026 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1027 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
1028 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1029 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
1033 static const SilcConfigTable table_logging_c[] = {
1034 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
1035 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
1036 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1040 static const SilcConfigTable table_logging[] = {
1041 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1042 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1043 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1044 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1045 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1046 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1050 static const SilcConfigTable table_connparam[] = {
1051 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1052 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1053 { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1054 { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1055 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1056 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1057 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1058 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1059 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1060 { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1061 { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1065 static const SilcConfigTable table_client[] = {
1066 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1067 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1068 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1069 { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1073 static const SilcConfigTable table_admin[] = {
1074 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1075 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1076 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1077 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1078 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1079 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1080 { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1084 static const SilcConfigTable table_deny[] = {
1085 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1086 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1090 static const SilcConfigTable table_serverconn[] = {
1091 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1092 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1093 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1094 { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1095 { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1096 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1100 static const SilcConfigTable table_routerconn[] = {
1101 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1102 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1103 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1104 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1105 { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1106 { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1107 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1108 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1109 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1110 { "backuplocal", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1114 static const SilcConfigTable table_main[] = {
1115 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1116 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1117 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1118 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1119 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1120 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1121 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1122 { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1123 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1124 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1125 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1126 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1127 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1131 /* Allocates a new configuration object, opens configuration file and
1132 * parses it. The parsed data is returned to the newly allocated
1133 * configuration object. */
1135 SilcServerConfig silc_server_config_alloc(char *filename)
1137 SilcServerConfig config;
1138 SilcConfigEntity ent;
1139 SilcConfigFile *file;
1141 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1143 /* alloc a config object */
1144 config = (SilcServerConfig) silc_calloc(1, sizeof(*config));
1145 /* obtain a config file object */
1146 file = silc_config_open(filename);
1148 fprintf(stderr, "\nError: can't open config file `%s'\n", filename);
1151 /* obtain a SilcConfig entity, we can use it to start the parsing */
1152 ent = silc_config_init(file);
1153 /* load the known configuration options, give our empty object as context */
1154 silc_config_register_table(ent, table_main, (void *) config);
1155 /* enter the main parsing loop. When this returns, we have the parsing
1156 * result and the object filled (or partially, in case of errors). */
1157 ret = silc_config_main(ent);
1158 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret,
1159 silc_config_strerror(ret)));
1161 /* Check if the parser returned errors */
1163 /* handle this special error return which asks to quietly return */
1164 if (ret != SILC_CONFIG_ESILENT) {
1165 char *linebuf, *filename = silc_config_get_filename(file);
1166 uint32 line = silc_config_get_line(file);
1167 fprintf(stderr, "\nError while parsing config file: %s.\n",
1168 silc_config_strerror(ret));
1169 linebuf = silc_config_read_line(file, line);
1170 fprintf(stderr, " file %s line %lu: %s\n\n", filename, line, linebuf);
1175 /* close (destroy) the file object */
1176 silc_config_close(file);
1178 /* XXX FIXME: check for missing mandatory fields */
1179 if (!config->server_info) {
1180 fprintf(stderr, "\nError: Missing mandatory block `server_info'\n");
1188 void silc_server_config_destroy(SilcServerConfig config)
1191 silc_free(config->module_path);
1193 /* Destroy Logging channels */
1194 if (config->logging_info)
1195 silc_free(config->logging_info->file);
1196 if (config->logging_warnings)
1197 silc_free(config->logging_warnings->file);
1198 if (config->logging_errors)
1199 silc_free(config->logging_errors->file);
1200 if (config->logging_fatals)
1201 silc_free(config->logging_fatals->file);
1203 /* Destroy the ServerInfo struct */
1204 if (config->server_info) {
1205 register SilcServerConfigServerInfo *si = config->server_info;
1206 silc_free(si->server_name);
1207 silc_free(si->server_ip);
1208 silc_free(si->server_type);
1209 silc_free(si->location);
1210 silc_free(si->admin);
1211 silc_free(si->email);
1212 silc_free(si->user);
1213 silc_free(si->group);
1214 silc_free(si->motd_file);
1215 silc_free(si->pid_file);
1218 /* Now let's destroy the lists */
1220 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher,
1222 silc_free(di->name);
1223 silc_free(di->module);
1226 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash)
1227 silc_free(di->name);
1228 silc_free(di->module);
1231 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac)
1232 silc_free(di->name);
1233 silc_free(di->hash);
1236 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs)
1237 silc_free(di->name);
1240 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient,
1242 silc_free(di->host);
1243 CONFIG_FREE_AUTH(di);
1246 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins)
1247 silc_free(di->host);
1248 silc_free(di->user);
1249 silc_free(di->nick);
1250 CONFIG_FREE_AUTH(di);
1253 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied)
1254 silc_free(di->host);
1255 silc_free(di->reason);
1258 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer,
1260 silc_free(di->host);
1261 silc_free(di->version);
1262 CONFIG_FREE_AUTH(di);
1265 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter,
1267 silc_free(di->host);
1268 silc_free(di->version);
1269 silc_free(di->backup_replace_ip);
1270 CONFIG_FREE_AUTH(di);
1275 /* Registers configured ciphers. These can then be allocated by the
1276 server when needed. */
1278 bool silc_server_config_register_ciphers(SilcServer server)
1280 SilcServerConfig config = server->config;
1281 SilcServerConfigCipher *cipher = config->cipher;
1282 char *module_path = config->module_path;
1284 SILC_LOG_DEBUG(("Registering configured ciphers"));
1286 if (!cipher) /* any cipher in the config file? */
1290 /* if there isn't a module_path OR there isn't a module sim name try to
1291 * use buil-in functions */
1292 if (!module_path || !cipher->module) {
1294 for (i = 0; silc_default_ciphers[i].name; i++)
1295 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1296 silc_cipher_register(&silc_default_ciphers[i]);
1299 if (!silc_cipher_is_supported(cipher->name)) {
1300 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1301 silc_server_stop(server);
1306 /* Load (try at least) the crypto SIM module */
1307 char buf[1023], *alg_name;
1308 SilcCipherObject cipher_obj;
1309 SilcSimContext *sim;
1311 memset(&cipher_obj, 0, sizeof(cipher_obj));
1312 cipher_obj.name = cipher->name;
1313 cipher_obj.block_len = cipher->block_length;
1314 cipher_obj.key_len = cipher->key_length * 8;
1316 /* build the libname */
1317 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1319 sim = silc_sim_alloc();
1320 sim->type = SILC_SIM_CIPHER;
1323 alg_name = strdup(cipher->name);
1324 if (strchr(alg_name, '-'))
1325 *strchr(alg_name, '-') = '\0';
1327 if (silc_sim_load(sim)) {
1328 cipher_obj.set_key =
1329 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1330 SILC_CIPHER_SIM_SET_KEY));
1331 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1332 cipher_obj.set_key_with_string =
1333 silc_sim_getsym(sim,
1334 silc_sim_symname(alg_name,
1335 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1336 SILC_LOG_DEBUG(("set_key_with_string=%p",
1337 cipher_obj.set_key_with_string));
1338 cipher_obj.encrypt =
1339 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1340 SILC_CIPHER_SIM_ENCRYPT_CBC));
1341 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1342 cipher_obj.decrypt =
1343 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1344 SILC_CIPHER_SIM_DECRYPT_CBC));
1345 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1346 cipher_obj.context_len =
1347 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1348 SILC_CIPHER_SIM_CONTEXT_LEN));
1349 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1351 /* Put the SIM to the list of all SIM's in server */
1352 silc_dlist_add(server->sim, sim);
1354 silc_free(alg_name);
1356 SILC_LOG_ERROR(("Error configuring ciphers"));
1357 silc_server_stop(server);
1361 /* Register the cipher */
1362 silc_cipher_register(&cipher_obj);
1364 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1365 "can't load modules!"));
1366 silc_server_stop(server);
1370 cipher = cipher->next;
1376 /* Registers configured hash functions. These can then be allocated by the
1377 server when needed. */
1379 bool silc_server_config_register_hashfuncs(SilcServer server)
1381 SilcServerConfig config = server->config;
1382 SilcServerConfigHash *hash = config->hash;
1383 char *module_path = config->module_path;
1385 SILC_LOG_DEBUG(("Registering configured hash functions"));
1387 if (!hash) /* any hash func in the config file? */
1391 /* if there isn't a module_path OR there isn't a module sim name try to
1392 * use buil-in functions */
1393 if (!module_path || !hash->module) {
1395 for (i = 0; silc_default_hash[i].name; i++)
1396 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1397 silc_hash_register(&silc_default_hash[i]);
1400 if (!silc_hash_is_supported(hash->name)) {
1401 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1402 silc_server_stop(server);
1407 /* Load (try at least) the hash SIM module */
1408 SilcHashObject hash_obj;
1409 SilcSimContext *sim;
1411 memset(&hash_obj, 0, sizeof(hash_obj));
1412 hash_obj.name = hash->name;
1413 hash_obj.block_len = hash->block_length;
1414 hash_obj.hash_len = hash->digest_length;
1416 sim = silc_sim_alloc();
1417 sim->type = SILC_SIM_HASH;
1418 sim->libname = hash->module;
1420 if ((silc_sim_load(sim))) {
1422 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1423 SILC_HASH_SIM_INIT));
1424 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1426 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1427 SILC_HASH_SIM_UPDATE));
1428 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1430 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1431 SILC_HASH_SIM_FINAL));
1432 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1433 hash_obj.context_len =
1434 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1435 SILC_HASH_SIM_CONTEXT_LEN));
1436 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1438 /* Put the SIM to the table of all SIM's in server */
1439 silc_dlist_add(server->sim, sim);
1441 SILC_LOG_ERROR(("Error configuring hash functions"));
1442 silc_server_stop(server);
1446 /* Register the hash function */
1447 silc_hash_register(&hash_obj);
1449 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1450 "can't load modules!"));
1451 silc_server_stop(server);
1461 /* Registers configure HMACs. These can then be allocated by the server
1464 bool silc_server_config_register_hmacs(SilcServer server)
1466 SilcServerConfig config = server->config;
1467 SilcServerConfigHmac *hmac = config->hmac;
1469 SILC_LOG_DEBUG(("Registering configured HMACs"));
1475 SilcHmacObject hmac_obj;
1476 if (!silc_hash_is_supported(hmac->hash)) {
1477 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1478 silc_server_stop(server);
1481 /* Register the HMAC */
1482 memset(&hmac_obj, 0, sizeof(hmac_obj));
1483 hmac_obj.name = hmac->name;
1484 hmac_obj.len = hmac->mac_length;
1485 silc_hmac_register(&hmac_obj);
1493 /* Registers configured PKCS's. */
1495 bool silc_server_config_register_pkcs(SilcServer server)
1497 SilcServerConfig config = server->config;
1498 SilcServerConfigPkcs *pkcs = config->pkcs;
1500 SILC_LOG_DEBUG(("Registering configured PKCS"));
1507 for (i = 0; silc_default_pkcs[i].name; i++)
1508 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1509 silc_pkcs_register(&silc_default_pkcs[i]);
1512 if (!silc_pkcs_is_supported(pkcs->name)) {
1513 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1514 silc_server_stop(server);
1523 /* Sets log files where log messages are saved by the server logger. */
1525 void silc_server_config_setlogfiles(SilcServer server)
1527 SilcServerConfig config = server->config;
1528 SilcServerConfigLogging *this;
1530 SILC_LOG_DEBUG(("Setting configured log file names"));
1532 if ((this = config->logging_info))
1533 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1535 if ((this = config->logging_warnings))
1536 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1538 if ((this = config->logging_errors))
1539 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1541 if ((this = config->logging_fatals))
1542 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1546 /* Returns client authentication information from configuration file by host
1549 SilcServerConfigClient *
1550 silc_server_config_find_client(SilcServer server, char *host)
1552 SilcServerConfig config = server->config;
1553 SilcServerConfigClient *client;
1555 if (!config || !host)
1558 for (client = config->clients; client; client = client->next) {
1559 if (client->host && !silc_string_compare(client->host, host))
1564 /* if none matched, then client is already NULL */
1568 /* Returns admin connection configuration by host, username and/or
1571 SilcServerConfigAdmin *
1572 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1575 SilcServerConfig config = server->config;
1576 SilcServerConfigAdmin *admin;
1578 /* make sure we have a value for the matching parameters */
1586 for (admin = config->admins; admin; admin = admin->next) {
1587 if (admin->host && !silc_string_compare(admin->host, host))
1589 if (admin->user && !silc_string_compare(admin->user, user))
1591 if (admin->nick && !silc_string_compare(admin->nick, nick))
1593 /* no checks failed -> this entry matches */
1597 /* if none matched, then admin is already NULL */
1601 /* Returns the denied connection configuration entry by host. */
1603 SilcServerConfigDeny *
1604 silc_server_config_find_denied(SilcServer server, char *host)
1606 SilcServerConfig config = server->config;
1607 SilcServerConfigDeny *deny;
1609 /* make sure we have a value for the matching parameters */
1610 if (!config || !host)
1613 for (deny = config->denied; deny; deny = deny->next) {
1614 if (deny->host && !silc_string_compare(deny->host, host))
1619 /* if none matched, then deny is already NULL */
1623 /* Returns server connection info from server configuartion by host
1626 SilcServerConfigServer *
1627 silc_server_config_find_server_conn(SilcServer server, char *host)
1629 SilcServerConfig config = server->config;
1630 SilcServerConfigServer *serv = NULL;
1635 if (!config->servers)
1638 for (serv = config->servers; serv; serv = serv->next) {
1639 if (!silc_string_compare(serv->host, host))
1647 /* Returns router connection info from server configuration by
1648 host (name or ip). */
1650 SilcServerConfigRouter *
1651 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1653 SilcServerConfig config = server->config;
1654 SilcServerConfigRouter *serv = NULL;
1659 if (!config->routers)
1662 for (serv = config->routers; serv; serv = serv->next) {
1663 if (!silc_string_compare(serv->host, host))
1665 if (port && serv->port && serv->port != port)
1673 /* Returns TRUE if configuration for a router connection that we are
1674 initiating exists. */
1676 bool silc_server_config_is_primary_route(SilcServer server)
1678 SilcServerConfig config = server->config;
1679 SilcServerConfigRouter *serv = NULL;
1683 serv = config->routers;
1684 for (i = 0; serv; i++) {
1685 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1696 /* Returns our primary connection configuration or NULL if we do not
1697 have primary router configured. */
1699 SilcServerConfigRouter *
1700 silc_server_config_get_primary_router(SilcServer server)
1702 SilcServerConfig config = server->config;
1703 SilcServerConfigRouter *serv = NULL;
1706 serv = config->routers;
1707 for (i = 0; serv; i++) {
1708 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1716 /* Set default values to stuff that was not configured. */
1718 bool silc_server_config_set_defaults(SilcServer server)
1720 SilcServerConfig config = server->config;
1722 my_set_param_defaults(&config->param, NULL);
1724 config->channel_rekey_secs = (config->channel_rekey_secs ?
1725 config->channel_rekey_secs :
1726 SILC_SERVER_CHANNEL_REKEY);
1727 config->key_exchange_timeout = (config->key_exchange_timeout ?
1728 config->key_exchange_timeout :
1729 SILC_SERVER_SKE_TIMEOUT);
1730 config->conn_auth_timeout = (config->conn_auth_timeout ?
1731 config->conn_auth_timeout :
1732 SILC_SERVER_CONNAUTH_TIMEOUT);