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 /* Find connection parameters by the parameter block name. */
61 static SilcServerConfigSectionConnectionParam *
62 my_find_param(SilcServerConfig config, const char *name)
64 SilcServerConfigSectionConnectionParam *param;
69 for (param = config->conn_params; param; param = param->next) {
70 if (!strcasecmp(param->name, name))
77 /* free an authdata according to its auth method */
78 static void my_free_authdata(char *passphrase, void *public_key)
80 silc_free(passphrase);
82 silc_pkcs_public_key_free((SilcPublicKey) public_key);
85 /* parse an authdata according to its auth method */
86 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line,
87 void **auth_data, uint32 *auth_data_len)
89 if (auth_meth == SILC_AUTH_PASSWORD) {
90 /* p is a plain text password */
92 *auth_data = (void *) strdup(p);
94 *auth_data_len = (uint32) strlen(p);
95 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
96 /* p is a public key */
97 SilcPublicKey public_key;
99 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
100 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
101 fprintf(stderr, "\nError while parsing config file at line %lu: "
102 "Could not load public key file!\n", line);
106 *auth_data = (void *) public_key;
110 fprintf(stderr, "\nError while parsing config file at line %lu: "
111 "Unkonwn authentication method\n", line);
119 SILC_CONFIG_CALLBACK(fetch_generic)
121 SilcServerConfig config = (SilcServerConfig) context;
124 if (!strcmp(name, "module_path")) {
125 CONFIG_IS_DOUBLE(config->module_path);
126 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
128 else if (!strcmp(name, "prefer_passphrase_auth")) {
129 config->prefer_passphrase_auth = *(bool *)val;
131 else if (!strcmp(name, "require_reverse_lookup")) {
132 config->require_reverse_lookup = *(bool *)val;
134 else if (!strcmp(name, "keepalive_secs")) {
135 config->param.keepalive_secs = *(uint32 *)val;
137 else if (!strcmp(name, "reconnect_count")) {
138 config->param.reconnect_count = *(uint32 *)val;
140 else if (!strcmp(name, "reconnect_interval")) {
141 config->param.reconnect_interval = *(uint32 *)val;
143 else if (!strcmp(name, "reconnect_interval_max")) {
144 config->param.reconnect_interval_max = *(uint32 *)val;
146 else if (!strcmp(name, "reconnect_keep_trying")) {
147 config->param.reconnect_keep_trying = *(bool *)val;
150 return SILC_CONFIG_EINTERNAL;
152 return SILC_CONFIG_OK;
158 SILC_CONFIG_CALLBACK(fetch_cipher)
160 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionCipher);
162 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
163 type, name, context));
164 if (type == SILC_CONFIG_ARG_BLOCK) {
165 /* check the temporary struct's fields */
166 if (!tmp) /* empty sub-block? */
167 return SILC_CONFIG_OK;
169 got_errno = SILC_CONFIG_EMISSFIELDS;
172 /* the temporary struct is ok, append it to the list */
173 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
175 return SILC_CONFIG_OK;
177 /* if there isn't a temporary struct alloc one */
179 config->tmp = silc_calloc(1, sizeof(*findtmp));
180 tmp = (SilcServerConfigSectionCipher *) config->tmp;
183 /* Identify and save this value */
184 if (!strcmp(name, "name")) {
185 CONFIG_IS_DOUBLE(tmp->name);
186 tmp->name = strdup((char *) val);
188 else if (!strcmp(name, "module")) {
189 CONFIG_IS_DOUBLE(tmp->module);
190 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
192 else if (!strcmp(name, "keylength")) {
193 tmp->key_length = *(uint32 *)val;
195 else if (!strcmp(name, "blocklength")) {
196 tmp->block_length = *(uint32 *)val;
199 return SILC_CONFIG_EINTERNAL;
200 return SILC_CONFIG_OK;
203 silc_free(tmp->name);
204 silc_free(tmp->module);
210 SILC_CONFIG_CALLBACK(fetch_hash)
212 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHash);
214 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
215 type, name, context));
216 if (type == SILC_CONFIG_ARG_BLOCK) {
217 /* check the temporary struct's fields */
218 if (!tmp) /* empty sub-block? */
219 return SILC_CONFIG_OK;
220 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
221 got_errno = SILC_CONFIG_EMISSFIELDS;
224 /* the temporary struct in tmp is ok */
225 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
227 return SILC_CONFIG_OK;
230 /* if there isn't a temporary struct alloc one */
232 config->tmp = silc_calloc(1, sizeof(*findtmp));
233 tmp = (SilcServerConfigSectionHash *) config->tmp;
236 /* Identify and save this value */
237 if (!strcmp(name, "name")) {
238 CONFIG_IS_DOUBLE(tmp->name);
239 tmp->name = strdup((char *) val);
241 else if (!strcmp(name, "module")) {
242 CONFIG_IS_DOUBLE(tmp->module);
243 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
245 else if (!strcmp(name, "blocklength")) {
246 tmp->block_length = *(int *)val;
248 else if (!strcmp(name, "digestlength")) {
249 tmp->digest_length = *(int *)val;
252 return SILC_CONFIG_EINTERNAL;
253 return SILC_CONFIG_OK;
256 silc_free(tmp->name);
257 silc_free(tmp->module);
263 SILC_CONFIG_CALLBACK(fetch_hmac)
265 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHmac);
267 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
268 type, name, context));
269 if (type == SILC_CONFIG_ARG_BLOCK) {
270 /* check the temporary struct's fields */
271 if (!tmp) /* empty sub-block? */
272 return SILC_CONFIG_OK;
273 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
274 got_errno = SILC_CONFIG_EMISSFIELDS;
277 /* the temporary struct is ok, append it to the list */
278 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
280 return SILC_CONFIG_OK;
282 /* if there isn't a temporary struct alloc one */
284 config->tmp = silc_calloc(1, sizeof(*findtmp));
285 tmp = (SilcServerConfigSectionHmac *) config->tmp;
288 /* Identify and save this value */
289 if (!strcmp(name, "name")) {
290 CONFIG_IS_DOUBLE(tmp->name);
291 tmp->name = strdup((char *) val);
293 else if (!strcmp(name, "hash")) {
294 CONFIG_IS_DOUBLE(tmp->hash);
295 tmp->hash = strdup((char *) val);
297 else if (!strcmp(name, "maclength")) {
298 tmp->mac_length = *(int *)val;
301 return SILC_CONFIG_EINTERNAL;
302 return SILC_CONFIG_OK;
305 silc_free(tmp->name);
306 silc_free(tmp->hash);
312 SILC_CONFIG_CALLBACK(fetch_pkcs)
314 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionPkcs);
316 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
317 type, name, context));
318 if (type == SILC_CONFIG_ARG_BLOCK) {
319 /* check the temporary struct's fields */
320 if (!tmp) /* empty sub-block? */
321 return SILC_CONFIG_OK;
323 got_errno = SILC_CONFIG_EMISSFIELDS;
326 /* the temporary struct is ok, append it to the list */
327 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
329 return SILC_CONFIG_OK;
331 /* if there isn't a temporary struct alloc one */
333 config->tmp = silc_calloc(1, sizeof(*findtmp));
334 tmp = (SilcServerConfigSectionPkcs *) config->tmp;
337 /* Identify and save this value */
338 if (!strcmp(name, "name")) {
339 CONFIG_IS_DOUBLE(tmp->name);
340 tmp->name = strdup((char *) val);
343 return SILC_CONFIG_EINTERNAL;
344 return SILC_CONFIG_OK;
347 silc_free(tmp->name);
353 SILC_CONFIG_CALLBACK(fetch_serverinfo)
355 SilcServerConfig config = (SilcServerConfig) context;
356 SilcServerConfigSectionServerInfo *server_info = config->server_info;
359 /* if there isn't the struct alloc it */
361 config->server_info = server_info = (SilcServerConfigSectionServerInfo *)
362 silc_calloc(1, sizeof(*server_info));
364 if (type == SILC_CONFIG_ARG_BLOCK) {
365 /* check for mandatory inputs */
366 return SILC_CONFIG_OK;
368 if (!strcmp(name, "hostname")) {
369 CONFIG_IS_DOUBLE(server_info->server_name);
370 server_info->server_name = strdup((char *) val);
372 else if (!strcmp(name, "ip")) {
373 CONFIG_IS_DOUBLE(server_info->server_ip);
374 server_info->server_ip = strdup((char *) val);
376 else if (!strcmp(name, "port")) {
377 int port = *(int *)val;
378 if ((port <= 0) || (port > 65535)) {
379 fprintf(stderr, "Invalid port number!\n");
380 return SILC_CONFIG_ESILENT;
382 server_info->port = (uint16) port;
384 else if (!strcmp(name, "servertype")) {
385 CONFIG_IS_DOUBLE(server_info->server_type);
386 server_info->server_type = strdup((char *) val);
388 else if (!strcmp(name, "admin")) {
389 CONFIG_IS_DOUBLE(server_info->admin);
390 server_info->admin = strdup((char *) val);
392 else if (!strcmp(name, "adminemail")) {
393 CONFIG_IS_DOUBLE(server_info->email);
394 server_info->email = strdup((char *) val);
396 else if (!strcmp(name, "location")) {
397 CONFIG_IS_DOUBLE(server_info->location);
398 server_info->location = strdup((char *) val);
400 else if (!strcmp(name, "user")) {
401 CONFIG_IS_DOUBLE(server_info->user);
402 server_info->user = strdup((char *) val);
404 else if (!strcmp(name, "group")) {
405 CONFIG_IS_DOUBLE(server_info->group);
406 server_info->group = strdup((char *) val);
408 else if (!strcmp(name, "motdfile")) {
409 CONFIG_IS_DOUBLE(server_info->motd_file);
410 server_info->motd_file = strdup((char *) val);
412 else if (!strcmp(name, "pidfile")) {
413 CONFIG_IS_DOUBLE(server_info->pid_file);
414 server_info->pid_file = strdup((char *) val);
416 else if (!strcmp(name, "publickey")) {
417 char *tmp = (char *) val;
419 /* try to load specified file, if fail stop config parsing */
420 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
422 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
423 SILC_PKCS_FILE_BIN)) {
424 fprintf(stderr, "\nError: Could not load public key file.");
425 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
426 return SILC_CONFIG_ESILENT;
429 else if (!strcmp(name, "privatekey")) {
430 char *tmp = (char *) val;
432 /* try to load specified file, if fail stop config parsing */
433 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
435 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
436 SILC_PKCS_FILE_PEM)) {
437 fprintf(stderr, "\nError: Could not load private key file.");
438 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
439 return SILC_CONFIG_ESILENT;
443 return SILC_CONFIG_EINTERNAL;
444 return SILC_CONFIG_OK;
450 SILC_CONFIG_CALLBACK(fetch_logging)
452 SilcServerConfig config = (SilcServerConfig) context;
453 SilcServerConfigSectionLogging *tmp =
454 (SilcServerConfigSectionLogging *) config->tmp;
457 if (!strcmp(name, "quicklogs")) {
458 silc_log_quick = *(bool *)val;
460 else if (!strcmp(name, "flushdelay")) {
461 int flushdelay = *(int *)val;
462 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
463 fprintf(stderr, "Error: line %lu: invalid flushdelay value, use "
464 "quicklogs if you want real-time logging.\n", line);
465 return SILC_CONFIG_ESILENT;
467 silc_log_flushdelay = (long) flushdelay;
469 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
470 else if (!strcmp(name, __chan__)) { \
471 if (!tmp) return SILC_CONFIG_OK; \
473 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
475 config->__member__ = tmp; \
476 config->tmp = NULL; \
478 FETCH_LOGGING_CHAN("info", logging_info)
479 FETCH_LOGGING_CHAN("warnings", logging_warnings)
480 FETCH_LOGGING_CHAN("errors", logging_errors)
481 FETCH_LOGGING_CHAN("fatals", logging_fatals)
482 #undef FETCH_LOGGING_CHAN
483 else if (!strcmp(name, "file")) {
484 if (!tmp) { /* FIXME: what the fuck is this? */
485 config->tmp = silc_calloc(1, sizeof(*tmp));
486 tmp = (SilcServerConfigSectionLogging *) config->tmp;
489 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
491 tmp->file = strdup((char *) val);
493 else if (!strcmp(name, "size")) {
495 config->tmp = silc_calloc(1, sizeof(*tmp));
496 tmp = (SilcServerConfigSectionLogging *) config->tmp;
498 tmp->maxsize = *(uint32 *) val;
501 return SILC_CONFIG_EINTERNAL;
502 return SILC_CONFIG_OK;
505 silc_free(tmp->file);
511 SILC_CONFIG_CALLBACK(fetch_connparam)
513 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionConnectionParam);
515 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
516 type, name, context));
518 if (type == SILC_CONFIG_ARG_BLOCK) {
520 return SILC_CONFIG_OK;
522 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
524 return SILC_CONFIG_OK;
527 /* if there isn't a temporary struct alloc one */
529 config->tmp = silc_calloc(1, sizeof(*findtmp));
530 tmp = (SilcServerConfigSectionConnectionParam *) config->tmp;
533 if (!strcmp(name, "name")) {
534 CONFIG_IS_DOUBLE(tmp->name);
535 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
537 else if (!strcmp(name, "keepalive_secs")) {
538 tmp->keepalive_secs = *(uint32 *)val;
540 else if (!strcmp(name, "reconnect_count")) {
541 tmp->reconnect_count = *(uint32 *)val;
543 else if (!strcmp(name, "reconnect_interval")) {
544 tmp->reconnect_interval = *(uint32 *)val;
546 else if (!strcmp(name, "reconnect_interval_max")) {
547 tmp->reconnect_interval_max = *(uint32 *)val;
549 else if (!strcmp(name, "reconnect_keep_trying")) {
550 tmp->reconnect_keep_trying = *(bool *)val;
553 return SILC_CONFIG_EINTERNAL;
555 return SILC_CONFIG_OK;
558 silc_free(tmp->name);
564 SILC_CONFIG_CALLBACK(fetch_client)
566 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionClient);
568 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
569 type, name, context));
571 if (type == SILC_CONFIG_ARG_BLOCK) {
572 if (!tmp) /* empty sub-block? */
573 return SILC_CONFIG_OK;
575 /* Find connection parameter block */
576 if (tmp->param_name) {
577 tmp->param = my_find_param(config, tmp->param_name);
579 fprintf(stderr, "Unknown ConnectionParam: %s\n", tmp->param_name);
580 silc_free(tmp->param_name);
581 got_errno = SILC_CONFIG_ESILENT;
584 silc_free(tmp->param_name);
587 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
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 = (SilcServerConfigSectionClient *) config->tmp;
598 /* Identify and save this value */
599 if (!strcmp(name, "host")) {
600 CONFIG_IS_DOUBLE(tmp->host);
601 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
603 else if (!strcmp(name, "passphrase")) {
604 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
605 (void **)&tmp->passphrase,
606 &tmp->passphrase_len)) {
607 got_errno = SILC_CONFIG_ESILENT;
611 else if (!strcmp(name, "publickey")) {
612 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
613 &tmp->publickey, NULL)) {
614 got_errno = SILC_CONFIG_ESILENT;
618 else if (!strcmp(name, "port")) {
619 int port = *(int *)val;
620 if ((port <= 0) || (port > 65535)) {
621 fprintf(stderr, "Invalid port number!\n");
622 got_errno = SILC_CONFIG_ESILENT;
625 tmp->port = (uint16) port;
627 else if (!strcmp(name, "param")) {
628 CONFIG_IS_DOUBLE(tmp->param_name);
629 tmp->param_name = (*(char *)val ? strdup((char *) val) : NULL);
632 return SILC_CONFIG_EINTERNAL;
633 return SILC_CONFIG_OK;
636 silc_free(tmp->host);
637 my_free_authdata(tmp->passphrase, tmp->publickey);
643 SILC_CONFIG_CALLBACK(fetch_admin)
645 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionAdmin);
647 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
648 type, name, context));
650 if (type == SILC_CONFIG_ARG_BLOCK) {
651 /* check the temporary struct's fields */
652 if (!tmp) /* empty sub-block? */
653 return SILC_CONFIG_OK;
655 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
657 return SILC_CONFIG_OK;
660 /* if there isn't a temporary struct alloc one */
662 config->tmp = silc_calloc(1, sizeof(*findtmp));
663 tmp = (SilcServerConfigSectionAdmin *) config->tmp;
666 /* Identify and save this value */
667 if (!strcmp(name, "host")) {
668 CONFIG_IS_DOUBLE(tmp->host);
669 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
671 else if (!strcmp(name, "user")) {
672 CONFIG_IS_DOUBLE(tmp->user);
673 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
675 else if (!strcmp(name, "nick")) {
676 CONFIG_IS_DOUBLE(tmp->nick);
677 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
679 else if (!strcmp(name, "passphrase")) {
680 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
681 (void **)&tmp->passphrase,
682 &tmp->passphrase_len)) {
683 got_errno = SILC_CONFIG_ESILENT;
687 else if (!strcmp(name, "publickey")) {
688 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
689 &tmp->publickey, NULL)) {
690 got_errno = SILC_CONFIG_ESILENT;
695 return SILC_CONFIG_EINTERNAL;
696 return SILC_CONFIG_OK;
699 silc_free(tmp->host);
700 silc_free(tmp->user);
701 silc_free(tmp->nick);
702 my_free_authdata(tmp->passphrase, tmp->publickey);
708 SILC_CONFIG_CALLBACK(fetch_deny)
710 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionDeny);
712 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
713 type, name, context));
714 if (type == SILC_CONFIG_ARG_BLOCK) {
715 /* check the temporary struct's fields */
716 if (!tmp) /* empty sub-block? */
717 return SILC_CONFIG_OK;
719 got_errno = SILC_CONFIG_EMISSFIELDS;
722 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
724 return SILC_CONFIG_OK;
726 /* if there isn't a temporary struct alloc one */
728 config->tmp = silc_calloc(1, sizeof(*findtmp));
729 tmp = (SilcServerConfigSectionDeny *) config->tmp;
732 /* Identify and save this value */
733 if (!strcmp(name, "host")) {
734 CONFIG_IS_DOUBLE(tmp->host);
735 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
737 else if (!strcmp(name, "port")) {
738 int port = *(int *)val;
739 if ((port <= 0) || (port > 65535)) {
740 fprintf(stderr, "Invalid port number!\n");
741 got_errno = SILC_CONFIG_ESILENT; goto got_err;
743 tmp->port = (uint16) port;
745 else if (!strcmp(name, "reason")) {
746 CONFIG_IS_DOUBLE(tmp->reason);
747 tmp->reason = strdup((char *) val);
750 return SILC_CONFIG_EINTERNAL;
751 return SILC_CONFIG_OK;
754 silc_free(tmp->host);
755 silc_free(tmp->reason);
761 SILC_CONFIG_CALLBACK(fetch_server)
763 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionServer);
765 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
766 type, name, context));
768 if (type == SILC_CONFIG_ARG_BLOCK) {
769 /* check the temporary struct's fields */
770 if (!tmp) /* empty sub-block? */
771 return SILC_CONFIG_OK;
773 /* Find connection parameter block */
774 if (tmp->param_name) {
775 tmp->param = my_find_param(config, tmp->param_name);
777 fprintf(stderr, "Unknown ConnectionParam: %s\n", tmp->param_name);
778 silc_free(tmp->param_name);
779 got_errno = SILC_CONFIG_ESILENT;
782 silc_free(tmp->param_name);
785 /* the temporary struct is ok, append it to the list */
786 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
788 return SILC_CONFIG_OK;
791 /* if there isn't a temporary struct alloc one */
793 config->tmp = silc_calloc(1, sizeof(*findtmp));
794 tmp = (SilcServerConfigSectionServer *) config->tmp;
797 /* Identify and save this value */
798 if (!strcmp(name, "host")) {
799 CONFIG_IS_DOUBLE(tmp->host);
800 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
802 else if (!strcmp(name, "passphrase")) {
803 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
804 (void **)&tmp->passphrase,
805 &tmp->passphrase_len)) {
806 got_errno = SILC_CONFIG_ESILENT;
810 else if (!strcmp(name, "publickey")) {
811 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
812 &tmp->publickey, NULL)) {
813 got_errno = SILC_CONFIG_ESILENT;
817 else if (!strcmp(name, "versionid")) {
818 CONFIG_IS_DOUBLE(tmp->version);
819 tmp->version = strdup((char *) val);
821 else if (!strcmp(name, "param")) {
822 CONFIG_IS_DOUBLE(tmp->param_name);
823 tmp->param_name = (*(char *)val ? strdup((char *) val) : NULL);
825 else if (!strcmp(name, "backup")) {
826 tmp->backup_router = *(bool *)val;
829 return SILC_CONFIG_EINTERNAL;
831 return SILC_CONFIG_OK;
834 silc_free(tmp->host);
835 silc_free(tmp->version);
836 my_free_authdata(tmp->passphrase, tmp->publickey);
842 SILC_CONFIG_CALLBACK(fetch_router)
844 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionRouter);
846 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
847 type, name, context));
849 if (type == SILC_CONFIG_ARG_BLOCK) {
850 if (!tmp) /* empty sub-block? */
851 return SILC_CONFIG_OK;
853 /* Find connection parameter block */
854 if (tmp->param_name) {
855 tmp->param = my_find_param(config, tmp->param_name);
857 fprintf(stderr, "Unknown ConnectionParam: %s\n", tmp->param_name);
858 silc_free(tmp->param_name);
859 got_errno = SILC_CONFIG_ESILENT;
862 silc_free(tmp->param_name);
865 /* the temporary struct is ok, append it to the list */
866 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
868 return SILC_CONFIG_OK;
871 /* if there isn't a temporary struct alloc one */
873 config->tmp = silc_calloc(1, sizeof(*findtmp));
874 tmp = (SilcServerConfigSectionRouter *) config->tmp;
877 /* Identify and save this value */
878 if (!strcmp(name, "host")) {
879 CONFIG_IS_DOUBLE(tmp->host);
880 tmp->host = strdup((char *) val);
882 else if (!strcmp(name, "port")) {
883 int port = *(int *)val;
884 if ((port <= 0) || (port > 65535)) {
885 fprintf(stderr, "Invalid port number!\n");
886 return SILC_CONFIG_ESILENT;
888 tmp->port = (uint16) port;
890 else if (!strcmp(name, "passphrase")) {
891 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
892 (void **)&tmp->passphrase,
893 &tmp->passphrase_len)) {
894 got_errno = SILC_CONFIG_ESILENT;
898 else if (!strcmp(name, "publickey")) {
899 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
900 &tmp->publickey, NULL)) {
901 got_errno = SILC_CONFIG_ESILENT;
905 else if (!strcmp(name, "versionid")) {
906 CONFIG_IS_DOUBLE(tmp->version);
907 tmp->version = strdup((char *) val);
909 else if (!strcmp(name, "param")) {
910 CONFIG_IS_DOUBLE(tmp->param_name);
911 tmp->param_name = (*(char *)val ? strdup((char *) val) : NULL);
913 else if (!strcmp(name, "initiator")) {
914 tmp->initiator = *(bool *)val;
916 else if (!strcmp(name, "backuphost")) {
917 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
918 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
922 return SILC_CONFIG_EINTERNAL;
924 return SILC_CONFIG_OK;
927 silc_free(tmp->host);
928 silc_free(tmp->version);
929 silc_free(tmp->backup_replace_ip);
930 my_free_authdata(tmp->passphrase, tmp->publickey);
936 /* known config options tables */
937 static const SilcConfigTable table_general[] = {
938 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
939 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
940 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
941 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
942 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
943 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
944 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
945 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
949 static const SilcConfigTable table_cipher[] = {
950 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
951 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
952 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
953 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
957 static const SilcConfigTable table_hash[] = {
958 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
959 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
960 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
961 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
965 static const SilcConfigTable table_hmac[] = {
966 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
967 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
968 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
972 static const SilcConfigTable table_pkcs[] = {
973 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
977 static const SilcConfigTable table_serverinfo[] = {
978 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
979 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
980 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
981 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
982 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
983 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
984 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
985 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
986 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
987 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
988 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
989 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
990 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
994 static const SilcConfigTable table_logging_c[] = {
995 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
996 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
997 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
1001 static const SilcConfigTable table_logging[] = {
1002 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
1003 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
1004 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1005 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1006 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1007 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
1011 static const SilcConfigTable table_connparam[] = {
1012 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
1013 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1014 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1015 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1016 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1017 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
1018 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
1022 static const SilcConfigTable table_client[] = {
1023 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1024 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1025 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1026 { "port", SILC_CONFIG_ARG_INT, fetch_client, NULL },
1027 { "param", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1031 static const SilcConfigTable table_admin[] = {
1032 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1033 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1034 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1035 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1036 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1037 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1038 { "param", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1042 static const SilcConfigTable table_deny[] = {
1043 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1044 { "port", SILC_CONFIG_ARG_INT, fetch_deny, NULL },
1045 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1049 static const SilcConfigTable table_serverconn[] = {
1050 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1051 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1052 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1053 { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1054 { "param", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1055 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1059 static const SilcConfigTable table_routerconn[] = {
1060 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1061 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1062 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1063 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1064 { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1065 { "param", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1066 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1067 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1068 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1069 { "localbackup", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1073 static const SilcConfigTable table_main[] = {
1074 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1075 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1076 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1077 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1078 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1079 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1080 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1081 { "connectionparam", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1082 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1083 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1084 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1085 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1086 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1090 /* Allocates a new configuration object, opens configuration file and
1091 * parses it. The parsed data is returned to the newly allocated
1092 * configuration object. */
1094 SilcServerConfig silc_server_config_alloc(char *filename)
1096 SilcServerConfig config;
1097 SilcConfigEntity ent;
1098 SilcConfigFile *file;
1100 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1102 /* alloc a config object */
1103 config = (SilcServerConfig) silc_calloc(1, sizeof(*config));
1104 /* obtain a config file object */
1105 file = silc_config_open(filename);
1107 fprintf(stderr, "\nError: can't open config file `%s'\n", filename);
1110 /* obtain a SilcConfig entity, we can use it to start the parsing */
1111 ent = silc_config_init(file);
1112 /* load the known configuration options, give our empty object as context */
1113 silc_config_register_table(ent, table_main, (void *) config);
1114 /* enter the main parsing loop. When this returns, we have the parsing
1115 * result and the object filled (or partially, in case of errors). */
1116 ret = silc_config_main(ent);
1117 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret, silc_config_strerror(ret)));
1119 /* Check if the parser returned errors */
1121 /* handle this special error return which asks to quietly return */
1122 if (ret != SILC_CONFIG_ESILENT) {
1123 char *linebuf, *filename = silc_config_get_filename(file);
1124 uint32 line = silc_config_get_line(file);
1125 fprintf(stderr, "\nError while parsing config file: %s.\n",
1126 silc_config_strerror(ret));
1127 linebuf = silc_config_read_line(file, line);
1128 fprintf(stderr, " file %s line %lu: %s\n\n", filename, line, linebuf);
1133 /* close (destroy) the file object */
1134 silc_config_close(file);
1136 /* XXX FIXME: check for missing mandatory fields */
1137 if (!config->server_info) {
1138 fprintf(stderr, "\nError: Missing mandatory block `server_info'\n");
1146 void silc_server_config_destroy(SilcServerConfig config)
1149 silc_free(config->module_path);
1151 /* Destroy Logging channels */
1152 if (config->logging_info)
1153 silc_free(config->logging_info->file);
1154 if (config->logging_warnings)
1155 silc_free(config->logging_warnings->file);
1156 if (config->logging_errors)
1157 silc_free(config->logging_errors->file);
1158 if (config->logging_fatals)
1159 silc_free(config->logging_fatals->file);
1161 /* Destroy the ServerInfo struct */
1162 if (config->server_info) {
1163 register SilcServerConfigSectionServerInfo *si = config->server_info;
1164 silc_free(si->server_name);
1165 silc_free(si->server_ip);
1166 silc_free(si->server_type);
1167 silc_free(si->location);
1168 silc_free(si->admin);
1169 silc_free(si->email);
1170 silc_free(si->user);
1171 silc_free(si->group);
1172 silc_free(si->motd_file);
1173 silc_free(si->pid_file);
1176 /* Now let's destroy the lists */
1178 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionCipher,
1180 silc_free(di->name);
1181 silc_free(di->module);
1184 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHash, config->hash)
1185 silc_free(di->name);
1186 silc_free(di->module);
1189 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHmac, config->hmac)
1190 silc_free(di->name);
1191 silc_free(di->hash);
1194 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionPkcs, config->pkcs)
1195 silc_free(di->name);
1198 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionClient,
1200 silc_free(di->host);
1201 my_free_authdata(di->passphrase, di->publickey);
1204 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionAdmin, config->admins)
1205 silc_free(di->host);
1206 silc_free(di->user);
1207 silc_free(di->nick);
1208 my_free_authdata(di->passphrase, di->publickey);
1211 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionDeny, config->denied)
1212 silc_free(di->host);
1213 silc_free(di->reason);
1216 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionServer,
1218 silc_free(di->host);
1219 silc_free(di->version);
1220 my_free_authdata(di->passphrase, di->publickey);
1223 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionRouter,
1225 silc_free(di->host);
1226 silc_free(di->version);
1227 silc_free(di->backup_replace_ip);
1228 my_free_authdata(di->passphrase, di->publickey);
1233 /* Registers configured ciphers. These can then be allocated by the
1234 server when needed. */
1236 bool silc_server_config_register_ciphers(SilcServer server)
1238 SilcServerConfig config = server->config;
1239 SilcServerConfigSectionCipher *cipher = config->cipher;
1240 char *module_path = config->module_path;
1242 SILC_LOG_DEBUG(("Registering configured ciphers"));
1244 if (!cipher) /* any cipher in the config file? */
1248 /* if there isn't a module_path OR there isn't a module sim name try to
1249 * use buil-in functions */
1250 if (!module_path || !cipher->module) {
1252 for (i = 0; silc_default_ciphers[i].name; i++)
1253 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1254 silc_cipher_register(&silc_default_ciphers[i]);
1257 if (!silc_cipher_is_supported(cipher->name)) {
1258 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1259 silc_server_stop(server);
1264 /* Load (try at least) the crypto SIM module */
1265 char buf[1023], *alg_name;
1266 SilcCipherObject cipher_obj;
1267 SilcSimContext *sim;
1269 memset(&cipher_obj, 0, sizeof(cipher_obj));
1270 cipher_obj.name = cipher->name;
1271 cipher_obj.block_len = cipher->block_length;
1272 cipher_obj.key_len = cipher->key_length * 8;
1274 /* build the libname */
1275 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1277 sim = silc_sim_alloc();
1278 sim->type = SILC_SIM_CIPHER;
1281 alg_name = strdup(cipher->name);
1282 if (strchr(alg_name, '-'))
1283 *strchr(alg_name, '-') = '\0';
1285 if (silc_sim_load(sim)) {
1286 cipher_obj.set_key =
1287 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1288 SILC_CIPHER_SIM_SET_KEY));
1289 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1290 cipher_obj.set_key_with_string =
1291 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1292 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1293 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher_obj.set_key_with_string));
1294 cipher_obj.encrypt =
1295 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1296 SILC_CIPHER_SIM_ENCRYPT_CBC));
1297 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1298 cipher_obj.decrypt =
1299 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1300 SILC_CIPHER_SIM_DECRYPT_CBC));
1301 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1302 cipher_obj.context_len =
1303 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1304 SILC_CIPHER_SIM_CONTEXT_LEN));
1305 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1307 /* Put the SIM to the list of all SIM's in server */
1308 silc_dlist_add(server->sim, sim);
1310 silc_free(alg_name);
1312 SILC_LOG_ERROR(("Error configuring ciphers"));
1313 silc_server_stop(server);
1317 /* Register the cipher */
1318 silc_cipher_register(&cipher_obj);
1320 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1321 "can't load modules!"));
1322 silc_server_stop(server);
1326 cipher = cipher->next;
1332 /* Registers configured hash functions. These can then be allocated by the
1333 server when needed. */
1335 bool silc_server_config_register_hashfuncs(SilcServer server)
1337 SilcServerConfig config = server->config;
1338 SilcServerConfigSectionHash *hash = config->hash;
1339 char *module_path = config->module_path;
1341 SILC_LOG_DEBUG(("Registering configured hash functions"));
1343 if (!hash) /* any hash func in the config file? */
1347 /* if there isn't a module_path OR there isn't a module sim name try to
1348 * use buil-in functions */
1349 if (!module_path || !hash->module) {
1351 for (i = 0; silc_default_hash[i].name; i++)
1352 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1353 silc_hash_register(&silc_default_hash[i]);
1356 if (!silc_hash_is_supported(hash->name)) {
1357 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1358 silc_server_stop(server);
1363 /* Load (try at least) the hash SIM module */
1364 SilcHashObject hash_obj;
1365 SilcSimContext *sim;
1367 memset(&hash_obj, 0, sizeof(hash_obj));
1368 hash_obj.name = hash->name;
1369 hash_obj.block_len = hash->block_length;
1370 hash_obj.hash_len = hash->digest_length;
1372 sim = silc_sim_alloc();
1373 sim->type = SILC_SIM_HASH;
1374 sim->libname = hash->module;
1376 if ((silc_sim_load(sim))) {
1378 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1379 SILC_HASH_SIM_INIT));
1380 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1382 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1383 SILC_HASH_SIM_UPDATE));
1384 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1386 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1387 SILC_HASH_SIM_FINAL));
1388 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1389 hash_obj.context_len =
1390 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1391 SILC_HASH_SIM_CONTEXT_LEN));
1392 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1394 /* Put the SIM to the table of all SIM's in server */
1395 silc_dlist_add(server->sim, sim);
1397 SILC_LOG_ERROR(("Error configuring hash functions"));
1398 silc_server_stop(server);
1402 /* Register the hash function */
1403 silc_hash_register(&hash_obj);
1405 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1406 "can't load modules!"));
1407 silc_server_stop(server);
1417 /* Registers configure HMACs. These can then be allocated by the server
1420 bool silc_server_config_register_hmacs(SilcServer server)
1422 SilcServerConfig config = server->config;
1423 SilcServerConfigSectionHmac *hmac = config->hmac;
1425 SILC_LOG_DEBUG(("Registering configured HMACs"));
1431 SilcHmacObject hmac_obj;
1432 if (!silc_hash_is_supported(hmac->hash)) {
1433 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1434 silc_server_stop(server);
1437 /* Register the HMAC */
1438 memset(&hmac_obj, 0, sizeof(hmac_obj));
1439 hmac_obj.name = hmac->name;
1440 hmac_obj.len = hmac->mac_length;
1441 silc_hmac_register(&hmac_obj);
1449 /* Registers configured PKCS's. */
1451 bool silc_server_config_register_pkcs(SilcServer server)
1453 SilcServerConfig config = server->config;
1454 SilcServerConfigSectionPkcs *pkcs = config->pkcs;
1456 SILC_LOG_DEBUG(("Registering configured PKCS"));
1463 for (i = 0; silc_default_pkcs[i].name; i++)
1464 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1465 silc_pkcs_register(&silc_default_pkcs[i]);
1468 if (!silc_pkcs_is_supported(pkcs->name)) {
1469 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1470 silc_server_stop(server);
1479 /* Sets log files where log messages are saved by the server logger. */
1481 void silc_server_config_setlogfiles(SilcServer server)
1483 SilcServerConfig config = server->config;
1484 SilcServerConfigSectionLogging *this;
1486 SILC_LOG_DEBUG(("Setting configured log file names"));
1488 if ((this = config->logging_info))
1489 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1491 if ((this = config->logging_warnings))
1492 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1494 if ((this = config->logging_errors))
1495 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1497 if ((this = config->logging_fatals))
1498 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1502 /* Returns client authentication information from configuration file by host
1505 SilcServerConfigSectionClient *
1506 silc_server_config_find_client(SilcServer server, char *host, int port)
1508 SilcServerConfig config = server->config;
1509 SilcServerConfigSectionClient *client;
1511 if (!config || !port) {
1512 SILC_LOG_WARNING(("Bogus: config_find_client(config=0x%08x, "
1513 "host=0x%08x \"%s\", port=%hu)",
1514 (uint32) config, (uint32) host, host, port));
1520 for (client = config->clients; client; client = client->next) {
1521 if (client->host && !silc_string_compare(client->host, host))
1523 if (client->port && (client->port != port))
1528 /* if none matched, then client is already NULL */
1532 /* Returns admin connection configuration by host, username and/or
1535 SilcServerConfigSectionAdmin *
1536 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1539 SilcServerConfig config = server->config;
1540 SilcServerConfigSectionAdmin *admin;
1542 /* make sure we have a value for the matching parameters */
1550 for (admin = config->admins; admin; admin = admin->next) {
1551 if (admin->host && !silc_string_compare(admin->host, host))
1553 if (admin->user && !silc_string_compare(admin->user, user))
1555 if (admin->nick && !silc_string_compare(admin->nick, nick))
1557 /* no checks failed -> this entry matches */
1561 /* if none matched, then admin is already NULL */
1565 /* Returns the denied connection configuration entry by host and port. */
1567 SilcServerConfigSectionDeny *
1568 silc_server_config_find_denied(SilcServer server, char *host, uint16 port)
1570 SilcServerConfig config = server->config;
1571 SilcServerConfigSectionDeny *deny;
1573 /* make sure we have a value for the matching parameters */
1574 if (!config || !port) {
1575 SILC_LOG_WARNING(("Bogus: config_find_denied(config=0x%08x, "
1576 "host=0x%08x \"%s\", port=%hu)",
1577 (uint32) config, (uint32) host, host, port));
1583 for (deny = config->denied; deny; deny = deny->next) {
1584 if (deny->host && !silc_string_compare(deny->host, host))
1589 /* if none matched, then deny is already NULL */
1593 /* Returns server connection info from server configuartion by host
1596 SilcServerConfigSectionServer *
1597 silc_server_config_find_server_conn(SilcServer server, char *host)
1599 SilcServerConfig config = server->config;
1600 SilcServerConfigSectionServer *serv = NULL;
1605 if (!config->servers)
1608 for (serv = config->servers; serv; serv = serv->next) {
1609 if (!silc_string_compare(serv->host, host))
1617 /* Returns router connection info from server configuration by
1618 host (name or ip). */
1620 SilcServerConfigSectionRouter *
1621 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1623 SilcServerConfig config = server->config;
1624 SilcServerConfigSectionRouter *serv = NULL;
1629 if (!config->routers)
1632 for (serv = config->routers; serv; serv = serv->next) {
1633 if (!silc_string_compare(serv->host, host))
1635 if (port && serv->port && serv->port != port)
1643 /* Returns TRUE if configuration for a router connection that we are
1644 initiating exists. */
1646 bool silc_server_config_is_primary_route(SilcServer server)
1648 SilcServerConfig config = server->config;
1649 SilcServerConfigSectionRouter *serv = NULL;
1653 serv = config->routers;
1654 for (i = 0; serv; i++) {
1655 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1666 /* Returns our primary connection configuration or NULL if we do not
1667 have primary router configured. */
1669 SilcServerConfigSectionRouter *
1670 silc_server_config_get_primary_router(SilcServer server)
1672 SilcServerConfig config = server->config;
1673 SilcServerConfigSectionRouter *serv = NULL;
1676 serv = config->routers;
1677 for (i = 0; serv; i++) {
1678 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1686 /* Set default values to stuff that was not configured. */
1688 bool silc_server_config_set_defaults(SilcServer server)
1690 SilcServerConfig config = server->config;
1692 config->param.keepalive_secs = (config->param.keepalive_secs ?
1693 config->param.keepalive_secs :
1694 SILC_SERVER_KEEPALIVE);
1695 config->param.reconnect_count = (config->param.reconnect_count ?
1696 config->param.reconnect_count :
1697 SILC_SERVER_RETRY_COUNT);
1698 config->param.reconnect_interval = (config->param.reconnect_interval ?
1699 config->param.reconnect_interval :
1700 SILC_SERVER_RETRY_INTERVAL_MIN);
1701 config->param.reconnect_interval_max =
1702 (config->param.reconnect_interval_max ?
1703 config->param.reconnect_interval_max :
1704 SILC_SERVER_RETRY_INTERVAL_MAX);