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 /* Find connection parameters by the parameter block name. */
67 static SilcServerConfigSectionConnectionParam *
68 my_find_param(SilcServerConfig config, const char *name, uint32 line)
70 SilcServerConfigSectionConnectionParam *param;
72 for (param = config->conn_params; param; param = param->next) {
73 if (!strcasecmp(param->name, name))
77 fprintf(stderr, "\nError while parsing config file at line %lu: "
78 "Cannot find Param \"%s\".\n", line, name);
83 /* parse an authdata according to its auth method */
84 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line,
85 void **auth_data, uint32 *auth_data_len)
87 if (auth_meth == SILC_AUTH_PASSWORD) {
88 /* p is a plain text password */
90 *auth_data = (void *) strdup(p);
92 *auth_data_len = (uint32) strlen(p);
93 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
94 /* p is a public key */
95 SilcPublicKey public_key;
97 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
98 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
99 fprintf(stderr, "\nError while parsing config file at line %lu: "
100 "Could not load public key file!\n", line);
104 *auth_data = (void *) public_key;
108 fprintf(stderr, "\nError while parsing config file at line %lu: "
109 "Unknown authentication method.\n", line);
117 SILC_CONFIG_CALLBACK(fetch_generic)
119 SilcServerConfig config = (SilcServerConfig) context;
122 if (!strcmp(name, "module_path")) {
123 CONFIG_IS_DOUBLE(config->module_path);
124 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
126 else if (!strcmp(name, "prefer_passphrase_auth")) {
127 config->prefer_passphrase_auth = *(bool *)val;
129 else if (!strcmp(name, "require_reverse_lookup")) {
130 config->require_reverse_lookup = *(bool *)val;
132 else if (!strcmp(name, "keepalive_secs")) {
133 config->param.keepalive_secs = (uint32) *(int *)val;
135 else if (!strcmp(name, "reconnect_count")) {
136 config->param.reconnect_count = (uint32) *(int *)val;
138 else if (!strcmp(name, "reconnect_interval")) {
139 config->param.reconnect_interval = (uint32) *(int *)val;
141 else if (!strcmp(name, "reconnect_interval_max")) {
142 config->param.reconnect_interval_max = (uint32) *(int *)val;
144 else if (!strcmp(name, "reconnect_keep_trying")) {
145 config->param.reconnect_keep_trying = *(bool *)val;
148 return SILC_CONFIG_EINTERNAL;
150 return SILC_CONFIG_OK;
156 SILC_CONFIG_CALLBACK(fetch_cipher)
158 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionCipher);
160 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
161 type, name, context));
162 if (type == SILC_CONFIG_ARG_BLOCK) {
163 /* check the temporary struct's fields */
164 if (!tmp) /* empty sub-block? */
165 return SILC_CONFIG_OK;
167 got_errno = SILC_CONFIG_EMISSFIELDS;
170 /* the temporary struct is ok, append it to the list */
171 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
173 return SILC_CONFIG_OK;
175 /* if there isn't a temporary struct alloc one */
177 config->tmp = silc_calloc(1, sizeof(*findtmp));
178 tmp = (SilcServerConfigSectionCipher *) config->tmp;
181 /* Identify and save this value */
182 if (!strcmp(name, "name")) {
183 CONFIG_IS_DOUBLE(tmp->name);
184 tmp->name = strdup((char *) val);
186 else if (!strcmp(name, "module")) {
187 CONFIG_IS_DOUBLE(tmp->module);
188 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
190 else if (!strcmp(name, "keylength")) {
191 tmp->key_length = *(uint32 *)val;
193 else if (!strcmp(name, "blocklength")) {
194 tmp->block_length = *(uint32 *)val;
197 return SILC_CONFIG_EINTERNAL;
198 return SILC_CONFIG_OK;
201 silc_free(tmp->name);
202 silc_free(tmp->module);
208 SILC_CONFIG_CALLBACK(fetch_hash)
210 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHash);
212 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
213 type, name, context));
214 if (type == SILC_CONFIG_ARG_BLOCK) {
215 /* check the temporary struct's fields */
216 if (!tmp) /* empty sub-block? */
217 return SILC_CONFIG_OK;
218 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
219 got_errno = SILC_CONFIG_EMISSFIELDS;
222 /* the temporary struct in tmp is ok */
223 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
225 return SILC_CONFIG_OK;
228 /* if there isn't a temporary struct alloc one */
230 config->tmp = silc_calloc(1, sizeof(*findtmp));
231 tmp = (SilcServerConfigSectionHash *) config->tmp;
234 /* Identify and save this value */
235 if (!strcmp(name, "name")) {
236 CONFIG_IS_DOUBLE(tmp->name);
237 tmp->name = strdup((char *) val);
239 else if (!strcmp(name, "module")) {
240 CONFIG_IS_DOUBLE(tmp->module);
241 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
243 else if (!strcmp(name, "blocklength")) {
244 tmp->block_length = *(int *)val;
246 else if (!strcmp(name, "digestlength")) {
247 tmp->digest_length = *(int *)val;
250 return SILC_CONFIG_EINTERNAL;
251 return SILC_CONFIG_OK;
254 silc_free(tmp->name);
255 silc_free(tmp->module);
261 SILC_CONFIG_CALLBACK(fetch_hmac)
263 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHmac);
265 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
266 type, name, context));
267 if (type == SILC_CONFIG_ARG_BLOCK) {
268 /* check the temporary struct's fields */
269 if (!tmp) /* empty sub-block? */
270 return SILC_CONFIG_OK;
271 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
272 got_errno = SILC_CONFIG_EMISSFIELDS;
275 /* the temporary struct is ok, append it to the list */
276 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
278 return SILC_CONFIG_OK;
280 /* if there isn't a temporary struct alloc one */
282 config->tmp = silc_calloc(1, sizeof(*findtmp));
283 tmp = (SilcServerConfigSectionHmac *) config->tmp;
286 /* Identify and save this value */
287 if (!strcmp(name, "name")) {
288 CONFIG_IS_DOUBLE(tmp->name);
289 tmp->name = strdup((char *) val);
291 else if (!strcmp(name, "hash")) {
292 CONFIG_IS_DOUBLE(tmp->hash);
293 tmp->hash = strdup((char *) val);
295 else if (!strcmp(name, "maclength")) {
296 tmp->mac_length = *(int *)val;
299 return SILC_CONFIG_EINTERNAL;
300 return SILC_CONFIG_OK;
303 silc_free(tmp->name);
304 silc_free(tmp->hash);
310 SILC_CONFIG_CALLBACK(fetch_pkcs)
312 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionPkcs);
314 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
315 type, name, context));
316 if (type == SILC_CONFIG_ARG_BLOCK) {
317 /* check the temporary struct's fields */
318 if (!tmp) /* empty sub-block? */
319 return SILC_CONFIG_OK;
321 got_errno = SILC_CONFIG_EMISSFIELDS;
324 /* the temporary struct is ok, append it to the list */
325 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
327 return SILC_CONFIG_OK;
329 /* if there isn't a temporary struct alloc one */
331 config->tmp = silc_calloc(1, sizeof(*findtmp));
332 tmp = (SilcServerConfigSectionPkcs *) config->tmp;
335 /* Identify and save this value */
336 if (!strcmp(name, "name")) {
337 CONFIG_IS_DOUBLE(tmp->name);
338 tmp->name = strdup((char *) val);
341 return SILC_CONFIG_EINTERNAL;
342 return SILC_CONFIG_OK;
345 silc_free(tmp->name);
351 SILC_CONFIG_CALLBACK(fetch_serverinfo)
353 SilcServerConfig config = (SilcServerConfig) context;
354 SilcServerConfigSectionServerInfo *server_info = config->server_info;
357 /* if there isn't the struct alloc it */
359 config->server_info = server_info = (SilcServerConfigSectionServerInfo *)
360 silc_calloc(1, sizeof(*server_info));
362 if (type == SILC_CONFIG_ARG_BLOCK) {
363 /* check for mandatory inputs */
364 return SILC_CONFIG_OK;
366 if (!strcmp(name, "hostname")) {
367 CONFIG_IS_DOUBLE(server_info->server_name);
368 server_info->server_name = strdup((char *) val);
370 else if (!strcmp(name, "ip")) {
371 CONFIG_IS_DOUBLE(server_info->server_ip);
372 server_info->server_ip = strdup((char *) val);
374 else if (!strcmp(name, "port")) {
375 int port = *(int *)val;
376 if ((port <= 0) || (port > 65535)) {
377 fprintf(stderr, "Invalid port number!\n");
378 return SILC_CONFIG_ESILENT;
380 server_info->port = (uint16) port;
382 else if (!strcmp(name, "servertype")) {
383 CONFIG_IS_DOUBLE(server_info->server_type);
384 server_info->server_type = strdup((char *) val);
386 else if (!strcmp(name, "admin")) {
387 CONFIG_IS_DOUBLE(server_info->admin);
388 server_info->admin = strdup((char *) val);
390 else if (!strcmp(name, "adminemail")) {
391 CONFIG_IS_DOUBLE(server_info->email);
392 server_info->email = strdup((char *) val);
394 else if (!strcmp(name, "location")) {
395 CONFIG_IS_DOUBLE(server_info->location);
396 server_info->location = strdup((char *) val);
398 else if (!strcmp(name, "user")) {
399 CONFIG_IS_DOUBLE(server_info->user);
400 server_info->user = strdup((char *) val);
402 else if (!strcmp(name, "group")) {
403 CONFIG_IS_DOUBLE(server_info->group);
404 server_info->group = strdup((char *) val);
406 else if (!strcmp(name, "motdfile")) {
407 CONFIG_IS_DOUBLE(server_info->motd_file);
408 server_info->motd_file = strdup((char *) val);
410 else if (!strcmp(name, "pidfile")) {
411 CONFIG_IS_DOUBLE(server_info->pid_file);
412 server_info->pid_file = strdup((char *) val);
414 else if (!strcmp(name, "publickey")) {
415 char *tmp = (char *) val;
417 /* try to load specified file, if fail stop config parsing */
418 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
420 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
421 SILC_PKCS_FILE_BIN)) {
422 fprintf(stderr, "\nError: Could not load public key file.");
423 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
424 return SILC_CONFIG_ESILENT;
427 else if (!strcmp(name, "privatekey")) {
428 char *tmp = (char *) val;
430 /* try to load specified file, if fail stop config parsing */
431 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
433 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
434 SILC_PKCS_FILE_PEM)) {
435 fprintf(stderr, "\nError: Could not load private key file.");
436 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
437 return SILC_CONFIG_ESILENT;
441 return SILC_CONFIG_EINTERNAL;
442 return SILC_CONFIG_OK;
448 SILC_CONFIG_CALLBACK(fetch_logging)
450 SilcServerConfig config = (SilcServerConfig) context;
451 SilcServerConfigSectionLogging *tmp =
452 (SilcServerConfigSectionLogging *) config->tmp;
455 if (!strcmp(name, "quicklogs")) {
456 silc_log_quick = *(bool *)val;
458 else if (!strcmp(name, "flushdelay")) {
459 int flushdelay = *(int *)val;
460 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
461 fprintf(stderr, "Error: line %lu: invalid flushdelay value, use "
462 "quicklogs if you want real-time logging.\n", line);
463 return SILC_CONFIG_ESILENT;
465 silc_log_flushdelay = (long) flushdelay;
467 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
468 else if (!strcmp(name, __chan__)) { \
469 if (!tmp) return SILC_CONFIG_OK; \
471 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
473 config->__member__ = tmp; \
474 config->tmp = NULL; \
476 FETCH_LOGGING_CHAN("info", logging_info)
477 FETCH_LOGGING_CHAN("warnings", logging_warnings)
478 FETCH_LOGGING_CHAN("errors", logging_errors)
479 FETCH_LOGGING_CHAN("fatals", logging_fatals)
480 #undef FETCH_LOGGING_CHAN
481 else if (!strcmp(name, "file")) {
482 if (!tmp) { /* FIXME: what the fuck is this? */
483 config->tmp = silc_calloc(1, sizeof(*tmp));
484 tmp = (SilcServerConfigSectionLogging *) config->tmp;
487 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
489 tmp->file = strdup((char *) val);
491 else if (!strcmp(name, "size")) {
493 config->tmp = silc_calloc(1, sizeof(*tmp));
494 tmp = (SilcServerConfigSectionLogging *) config->tmp;
496 tmp->maxsize = *(uint32 *) val;
499 return SILC_CONFIG_EINTERNAL;
500 return SILC_CONFIG_OK;
503 silc_free(tmp->file);
509 SILC_CONFIG_CALLBACK(fetch_connparam)
511 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionConnectionParam);
513 SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)",
514 type, name, context));
516 if (type == SILC_CONFIG_ARG_BLOCK) {
518 return SILC_CONFIG_OK;
520 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params);
522 return SILC_CONFIG_OK;
525 /* if there isn't a temporary struct alloc one */
527 config->tmp = silc_calloc(1, sizeof(*findtmp));
528 tmp = (SilcServerConfigSectionConnectionParam *) config->tmp;
531 if (!strcmp(name, "name")) {
532 CONFIG_IS_DOUBLE(tmp->name);
533 tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
535 else if (!strcmp(name, "keepalive_secs")) {
536 tmp->keepalive_secs = *(uint32 *)val;
538 else if (!strcmp(name, "reconnect_count")) {
539 tmp->reconnect_count = *(uint32 *)val;
541 else if (!strcmp(name, "reconnect_interval")) {
542 tmp->reconnect_interval = *(uint32 *)val;
544 else if (!strcmp(name, "reconnect_interval_max")) {
545 tmp->reconnect_interval_max = *(uint32 *)val;
547 else if (!strcmp(name, "reconnect_keep_trying")) {
548 tmp->reconnect_keep_trying = *(bool *)val;
551 return SILC_CONFIG_EINTERNAL;
553 return SILC_CONFIG_OK;
556 silc_free(tmp->name);
562 SILC_CONFIG_CALLBACK(fetch_client)
564 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionClient);
566 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
567 type, name, context));
569 /* alloc tmp before block checking (empty sub-blocks are welcome here) */
571 config->tmp = silc_calloc(1, sizeof(*findtmp));
572 tmp = (SilcServerConfigSectionClient *) config->tmp;
575 if (type == SILC_CONFIG_ARG_BLOCK) {
576 /* closing the block */
577 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
579 return SILC_CONFIG_OK;
582 /* Identify and save this value */
583 if (!strcmp(name, "host")) {
584 CONFIG_IS_DOUBLE(tmp->host);
585 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
587 else if (!strcmp(name, "passphrase")) {
588 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
589 (void **)&tmp->passphrase,
590 &tmp->passphrase_len)) {
591 got_errno = SILC_CONFIG_ESILENT;
595 else if (!strcmp(name, "publickey")) {
596 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
597 &tmp->publickey, NULL)) {
598 got_errno = SILC_CONFIG_ESILENT;
602 else if (!strcmp(name, "port")) {
603 int port = *(int *)val;
604 if ((port <= 0) || (port > 65535)) {
605 fprintf(stderr, "Invalid port number!\n");
606 got_errno = SILC_CONFIG_ESILENT;
609 tmp->port = (uint16) port;
611 else if (!strcmp(name, "param")) {
612 CONFIG_IS_DOUBLE(tmp->param);
613 tmp->param = my_find_param(config, (char *) val, line);
614 if (!tmp->param) { /* error already output */
615 got_errno = SILC_CONFIG_ESILENT;
620 return SILC_CONFIG_EINTERNAL;
621 return SILC_CONFIG_OK;
624 silc_free(tmp->host);
625 CONFIG_FREE_AUTH(tmp);
631 SILC_CONFIG_CALLBACK(fetch_admin)
633 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionAdmin);
635 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
636 type, name, context));
638 if (type == SILC_CONFIG_ARG_BLOCK) {
639 /* check the temporary struct's fields */
640 if (!tmp) /* empty sub-block? */
641 return SILC_CONFIG_OK;
643 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
645 return SILC_CONFIG_OK;
648 /* if there isn't a temporary struct alloc one */
650 config->tmp = silc_calloc(1, sizeof(*findtmp));
651 tmp = (SilcServerConfigSectionAdmin *) config->tmp;
654 /* Identify and save this value */
655 if (!strcmp(name, "host")) {
656 CONFIG_IS_DOUBLE(tmp->host);
657 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
659 else if (!strcmp(name, "user")) {
660 CONFIG_IS_DOUBLE(tmp->user);
661 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
663 else if (!strcmp(name, "nick")) {
664 CONFIG_IS_DOUBLE(tmp->nick);
665 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
667 else if (!strcmp(name, "passphrase")) {
668 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
669 (void **)&tmp->passphrase,
670 &tmp->passphrase_len)) {
671 got_errno = SILC_CONFIG_ESILENT;
675 else if (!strcmp(name, "publickey")) {
676 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
677 &tmp->publickey, NULL)) {
678 got_errno = SILC_CONFIG_ESILENT;
683 return SILC_CONFIG_EINTERNAL;
684 return SILC_CONFIG_OK;
687 silc_free(tmp->host);
688 silc_free(tmp->user);
689 silc_free(tmp->nick);
690 CONFIG_FREE_AUTH(tmp);
696 SILC_CONFIG_CALLBACK(fetch_deny)
698 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionDeny);
700 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
701 type, name, context));
702 if (type == SILC_CONFIG_ARG_BLOCK) {
703 /* check the temporary struct's fields */
704 if (!tmp) /* empty sub-block? */
705 return SILC_CONFIG_OK;
707 got_errno = SILC_CONFIG_EMISSFIELDS;
710 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
712 return SILC_CONFIG_OK;
714 /* if there isn't a temporary struct alloc one */
716 config->tmp = silc_calloc(1, sizeof(*findtmp));
717 tmp = (SilcServerConfigSectionDeny *) config->tmp;
720 /* Identify and save this value */
721 if (!strcmp(name, "host")) {
722 CONFIG_IS_DOUBLE(tmp->host);
723 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
725 else if (!strcmp(name, "port")) {
726 int port = *(int *)val;
727 if ((port <= 0) || (port > 65535)) {
728 fprintf(stderr, "Invalid port number!\n");
729 got_errno = SILC_CONFIG_ESILENT; goto got_err;
731 tmp->port = (uint16) port;
733 else if (!strcmp(name, "reason")) {
734 CONFIG_IS_DOUBLE(tmp->reason);
735 tmp->reason = strdup((char *) val);
738 return SILC_CONFIG_EINTERNAL;
739 return SILC_CONFIG_OK;
742 silc_free(tmp->host);
743 silc_free(tmp->reason);
749 SILC_CONFIG_CALLBACK(fetch_server)
751 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionServer);
753 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
754 type, name, context));
756 if (type == SILC_CONFIG_ARG_BLOCK) {
757 /* check the temporary struct's fields */
758 if (!tmp) /* empty sub-block? */
759 return SILC_CONFIG_OK;
761 /* XXX mandatory fields for server? */
763 /* the temporary struct is ok, append it to the list */
764 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
766 return SILC_CONFIG_OK;
769 /* if there isn't a temporary struct alloc one */
771 config->tmp = silc_calloc(1, sizeof(*findtmp));
772 tmp = (SilcServerConfigSectionServer *) config->tmp;
775 /* Identify and save this value */
776 if (!strcmp(name, "host")) {
777 CONFIG_IS_DOUBLE(tmp->host);
778 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
780 else if (!strcmp(name, "passphrase")) {
781 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
782 (void **)&tmp->passphrase,
783 &tmp->passphrase_len)) {
784 got_errno = SILC_CONFIG_ESILENT;
788 else if (!strcmp(name, "publickey")) {
789 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
790 &tmp->publickey, NULL)) {
791 got_errno = SILC_CONFIG_ESILENT;
795 else if (!strcmp(name, "versionid")) {
796 CONFIG_IS_DOUBLE(tmp->version);
797 tmp->version = strdup((char *) val);
799 else if (!strcmp(name, "param")) {
800 CONFIG_IS_DOUBLE(tmp->param);
801 tmp->param = my_find_param(config, (char *) val, line);
802 if (!tmp->param) { /* error already output */
803 got_errno = SILC_CONFIG_ESILENT;
807 else if (!strcmp(name, "backup")) {
808 tmp->backup_router = *(bool *)val;
811 return SILC_CONFIG_EINTERNAL;
813 return SILC_CONFIG_OK;
816 silc_free(tmp->host);
817 silc_free(tmp->version);
818 CONFIG_FREE_AUTH(tmp);
824 SILC_CONFIG_CALLBACK(fetch_router)
826 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionRouter);
828 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
829 type, name, context));
831 if (type == SILC_CONFIG_ARG_BLOCK) {
832 if (!tmp) /* empty sub-block? */
833 return SILC_CONFIG_OK;
835 /* XXX mandatory fields for router? */
837 /* the temporary struct is ok, append it to the list */
838 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
840 return SILC_CONFIG_OK;
843 /* if there isn't a temporary struct alloc one */
845 config->tmp = silc_calloc(1, sizeof(*findtmp));
846 tmp = (SilcServerConfigSectionRouter *) config->tmp;
849 /* Identify and save this value */
850 if (!strcmp(name, "host")) {
851 CONFIG_IS_DOUBLE(tmp->host);
852 tmp->host = strdup((char *) val);
854 else if (!strcmp(name, "port")) {
855 int port = *(int *)val;
856 if ((port <= 0) || (port > 65535)) {
857 fprintf(stderr, "Invalid port number!\n");
858 return SILC_CONFIG_ESILENT;
860 tmp->port = (uint16) port;
862 else if (!strcmp(name, "passphrase")) {
863 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
864 (void **)&tmp->passphrase,
865 &tmp->passphrase_len)) {
866 got_errno = SILC_CONFIG_ESILENT;
870 else if (!strcmp(name, "publickey")) {
871 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
872 &tmp->publickey, NULL)) {
873 got_errno = SILC_CONFIG_ESILENT;
877 else if (!strcmp(name, "versionid")) {
878 CONFIG_IS_DOUBLE(tmp->version);
879 tmp->version = strdup((char *) val);
881 else if (!strcmp(name, "param")) {
882 CONFIG_IS_DOUBLE(tmp->param);
883 tmp->param = my_find_param(config, (char *) val, line);
884 if (!tmp->param) { /* error already output */
885 got_errno = SILC_CONFIG_ESILENT;
889 else if (!strcmp(name, "initiator")) {
890 tmp->initiator = *(bool *)val;
892 else if (!strcmp(name, "backuphost")) {
893 CONFIG_IS_DOUBLE(tmp->backup_replace_ip);
894 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) :
898 return SILC_CONFIG_EINTERNAL;
900 return SILC_CONFIG_OK;
903 silc_free(tmp->host);
904 silc_free(tmp->version);
905 silc_free(tmp->backup_replace_ip);
906 CONFIG_FREE_AUTH(tmp);
912 /* known config options tables */
913 static const SilcConfigTable table_general[] = {
914 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
915 { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
916 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
917 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
918 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
919 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
920 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL },
921 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL },
925 static const SilcConfigTable table_cipher[] = {
926 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
927 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
928 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
929 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
933 static const SilcConfigTable table_hash[] = {
934 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
935 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
936 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
937 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
941 static const SilcConfigTable table_hmac[] = {
942 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
943 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
944 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
948 static const SilcConfigTable table_pkcs[] = {
949 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
953 static const SilcConfigTable table_serverinfo[] = {
954 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
955 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
956 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
957 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
958 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
959 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
960 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
961 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
962 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
963 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
964 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
965 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
966 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
970 static const SilcConfigTable table_logging_c[] = {
971 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
972 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
973 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
977 static const SilcConfigTable table_logging[] = {
978 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
979 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
980 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
981 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
982 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
983 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
987 static const SilcConfigTable table_connparam[] = {
988 { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL },
989 { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
990 { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
991 { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
992 { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
993 { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL },
994 { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL },
998 static const SilcConfigTable table_client[] = {
999 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
1000 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1001 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1002 { "port", SILC_CONFIG_ARG_INT, fetch_client, NULL },
1003 { "param", SILC_CONFIG_ARG_STR, fetch_client, NULL },
1007 static const SilcConfigTable table_admin[] = {
1008 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1009 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1010 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
1011 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1012 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1013 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
1014 { "param", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
1018 static const SilcConfigTable table_deny[] = {
1019 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
1020 { "port", SILC_CONFIG_ARG_INT, fetch_deny, NULL },
1021 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
1025 static const SilcConfigTable table_serverconn[] = {
1026 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
1027 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1028 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1029 { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1030 { "param", SILC_CONFIG_ARG_STR, fetch_server, NULL },
1031 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
1035 static const SilcConfigTable table_routerconn[] = {
1036 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1037 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1038 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1039 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1040 { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1041 { "param", SILC_CONFIG_ARG_STR, fetch_router, NULL },
1042 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1043 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
1044 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
1045 { "localbackup", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
1049 static const SilcConfigTable table_main[] = {
1050 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
1051 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
1052 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
1053 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
1054 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
1055 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
1056 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
1057 { "connectionparam", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam },
1058 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
1059 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
1060 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
1061 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
1062 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
1066 /* Allocates a new configuration object, opens configuration file and
1067 * parses it. The parsed data is returned to the newly allocated
1068 * configuration object. */
1070 SilcServerConfig silc_server_config_alloc(char *filename)
1072 SilcServerConfig config;
1073 SilcConfigEntity ent;
1074 SilcConfigFile *file;
1076 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
1078 /* alloc a config object */
1079 config = (SilcServerConfig) silc_calloc(1, sizeof(*config));
1080 /* obtain a config file object */
1081 file = silc_config_open(filename);
1083 fprintf(stderr, "\nError: can't open config file `%s'\n", filename);
1086 /* obtain a SilcConfig entity, we can use it to start the parsing */
1087 ent = silc_config_init(file);
1088 /* load the known configuration options, give our empty object as context */
1089 silc_config_register_table(ent, table_main, (void *) config);
1090 /* enter the main parsing loop. When this returns, we have the parsing
1091 * result and the object filled (or partially, in case of errors). */
1092 ret = silc_config_main(ent);
1093 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret, silc_config_strerror(ret)));
1095 /* Check if the parser returned errors */
1097 /* handle this special error return which asks to quietly return */
1098 if (ret != SILC_CONFIG_ESILENT) {
1099 char *linebuf, *filename = silc_config_get_filename(file);
1100 uint32 line = silc_config_get_line(file);
1101 fprintf(stderr, "\nError while parsing config file: %s.\n",
1102 silc_config_strerror(ret));
1103 linebuf = silc_config_read_line(file, line);
1104 fprintf(stderr, " file %s line %lu: %s\n\n", filename, line, linebuf);
1109 /* close (destroy) the file object */
1110 silc_config_close(file);
1112 /* XXX FIXME: check for missing mandatory fields */
1113 if (!config->server_info) {
1114 fprintf(stderr, "\nError: Missing mandatory block `server_info'\n");
1122 void silc_server_config_destroy(SilcServerConfig config)
1125 silc_free(config->module_path);
1127 /* Destroy Logging channels */
1128 if (config->logging_info)
1129 silc_free(config->logging_info->file);
1130 if (config->logging_warnings)
1131 silc_free(config->logging_warnings->file);
1132 if (config->logging_errors)
1133 silc_free(config->logging_errors->file);
1134 if (config->logging_fatals)
1135 silc_free(config->logging_fatals->file);
1137 /* Destroy the ServerInfo struct */
1138 if (config->server_info) {
1139 register SilcServerConfigSectionServerInfo *si = config->server_info;
1140 silc_free(si->server_name);
1141 silc_free(si->server_ip);
1142 silc_free(si->server_type);
1143 silc_free(si->location);
1144 silc_free(si->admin);
1145 silc_free(si->email);
1146 silc_free(si->user);
1147 silc_free(si->group);
1148 silc_free(si->motd_file);
1149 silc_free(si->pid_file);
1152 /* Now let's destroy the lists */
1154 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionCipher,
1156 silc_free(di->name);
1157 silc_free(di->module);
1160 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHash, config->hash)
1161 silc_free(di->name);
1162 silc_free(di->module);
1165 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHmac, config->hmac)
1166 silc_free(di->name);
1167 silc_free(di->hash);
1170 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionPkcs, config->pkcs)
1171 silc_free(di->name);
1174 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionClient,
1176 silc_free(di->host);
1177 CONFIG_FREE_AUTH(di);
1180 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionAdmin, config->admins)
1181 silc_free(di->host);
1182 silc_free(di->user);
1183 silc_free(di->nick);
1184 CONFIG_FREE_AUTH(di);
1187 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionDeny, config->denied)
1188 silc_free(di->host);
1189 silc_free(di->reason);
1192 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionServer,
1194 silc_free(di->host);
1195 silc_free(di->version);
1196 CONFIG_FREE_AUTH(di);
1199 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionRouter,
1201 silc_free(di->host);
1202 silc_free(di->version);
1203 silc_free(di->backup_replace_ip);
1204 CONFIG_FREE_AUTH(di);
1209 /* Registers configured ciphers. These can then be allocated by the
1210 server when needed. */
1212 bool silc_server_config_register_ciphers(SilcServer server)
1214 SilcServerConfig config = server->config;
1215 SilcServerConfigSectionCipher *cipher = config->cipher;
1216 char *module_path = config->module_path;
1218 SILC_LOG_DEBUG(("Registering configured ciphers"));
1220 if (!cipher) /* any cipher in the config file? */
1224 /* if there isn't a module_path OR there isn't a module sim name try to
1225 * use buil-in functions */
1226 if (!module_path || !cipher->module) {
1228 for (i = 0; silc_default_ciphers[i].name; i++)
1229 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1230 silc_cipher_register(&silc_default_ciphers[i]);
1233 if (!silc_cipher_is_supported(cipher->name)) {
1234 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1235 silc_server_stop(server);
1240 /* Load (try at least) the crypto SIM module */
1241 char buf[1023], *alg_name;
1242 SilcCipherObject cipher_obj;
1243 SilcSimContext *sim;
1245 memset(&cipher_obj, 0, sizeof(cipher_obj));
1246 cipher_obj.name = cipher->name;
1247 cipher_obj.block_len = cipher->block_length;
1248 cipher_obj.key_len = cipher->key_length * 8;
1250 /* build the libname */
1251 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1253 sim = silc_sim_alloc();
1254 sim->type = SILC_SIM_CIPHER;
1257 alg_name = strdup(cipher->name);
1258 if (strchr(alg_name, '-'))
1259 *strchr(alg_name, '-') = '\0';
1261 if (silc_sim_load(sim)) {
1262 cipher_obj.set_key =
1263 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1264 SILC_CIPHER_SIM_SET_KEY));
1265 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1266 cipher_obj.set_key_with_string =
1267 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1268 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1269 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher_obj.set_key_with_string));
1270 cipher_obj.encrypt =
1271 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1272 SILC_CIPHER_SIM_ENCRYPT_CBC));
1273 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1274 cipher_obj.decrypt =
1275 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1276 SILC_CIPHER_SIM_DECRYPT_CBC));
1277 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1278 cipher_obj.context_len =
1279 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1280 SILC_CIPHER_SIM_CONTEXT_LEN));
1281 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1283 /* Put the SIM to the list of all SIM's in server */
1284 silc_dlist_add(server->sim, sim);
1286 silc_free(alg_name);
1288 SILC_LOG_ERROR(("Error configuring ciphers"));
1289 silc_server_stop(server);
1293 /* Register the cipher */
1294 silc_cipher_register(&cipher_obj);
1296 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1297 "can't load modules!"));
1298 silc_server_stop(server);
1302 cipher = cipher->next;
1308 /* Registers configured hash functions. These can then be allocated by the
1309 server when needed. */
1311 bool silc_server_config_register_hashfuncs(SilcServer server)
1313 SilcServerConfig config = server->config;
1314 SilcServerConfigSectionHash *hash = config->hash;
1315 char *module_path = config->module_path;
1317 SILC_LOG_DEBUG(("Registering configured hash functions"));
1319 if (!hash) /* any hash func in the config file? */
1323 /* if there isn't a module_path OR there isn't a module sim name try to
1324 * use buil-in functions */
1325 if (!module_path || !hash->module) {
1327 for (i = 0; silc_default_hash[i].name; i++)
1328 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1329 silc_hash_register(&silc_default_hash[i]);
1332 if (!silc_hash_is_supported(hash->name)) {
1333 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1334 silc_server_stop(server);
1339 /* Load (try at least) the hash SIM module */
1340 SilcHashObject hash_obj;
1341 SilcSimContext *sim;
1343 memset(&hash_obj, 0, sizeof(hash_obj));
1344 hash_obj.name = hash->name;
1345 hash_obj.block_len = hash->block_length;
1346 hash_obj.hash_len = hash->digest_length;
1348 sim = silc_sim_alloc();
1349 sim->type = SILC_SIM_HASH;
1350 sim->libname = hash->module;
1352 if ((silc_sim_load(sim))) {
1354 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1355 SILC_HASH_SIM_INIT));
1356 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1358 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1359 SILC_HASH_SIM_UPDATE));
1360 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1362 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1363 SILC_HASH_SIM_FINAL));
1364 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1365 hash_obj.context_len =
1366 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1367 SILC_HASH_SIM_CONTEXT_LEN));
1368 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1370 /* Put the SIM to the table of all SIM's in server */
1371 silc_dlist_add(server->sim, sim);
1373 SILC_LOG_ERROR(("Error configuring hash functions"));
1374 silc_server_stop(server);
1378 /* Register the hash function */
1379 silc_hash_register(&hash_obj);
1381 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1382 "can't load modules!"));
1383 silc_server_stop(server);
1393 /* Registers configure HMACs. These can then be allocated by the server
1396 bool silc_server_config_register_hmacs(SilcServer server)
1398 SilcServerConfig config = server->config;
1399 SilcServerConfigSectionHmac *hmac = config->hmac;
1401 SILC_LOG_DEBUG(("Registering configured HMACs"));
1407 SilcHmacObject hmac_obj;
1408 if (!silc_hash_is_supported(hmac->hash)) {
1409 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1410 silc_server_stop(server);
1413 /* Register the HMAC */
1414 memset(&hmac_obj, 0, sizeof(hmac_obj));
1415 hmac_obj.name = hmac->name;
1416 hmac_obj.len = hmac->mac_length;
1417 silc_hmac_register(&hmac_obj);
1425 /* Registers configured PKCS's. */
1427 bool silc_server_config_register_pkcs(SilcServer server)
1429 SilcServerConfig config = server->config;
1430 SilcServerConfigSectionPkcs *pkcs = config->pkcs;
1432 SILC_LOG_DEBUG(("Registering configured PKCS"));
1439 for (i = 0; silc_default_pkcs[i].name; i++)
1440 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1441 silc_pkcs_register(&silc_default_pkcs[i]);
1444 if (!silc_pkcs_is_supported(pkcs->name)) {
1445 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1446 silc_server_stop(server);
1455 /* Sets log files where log messages are saved by the server logger. */
1457 void silc_server_config_setlogfiles(SilcServer server)
1459 SilcServerConfig config = server->config;
1460 SilcServerConfigSectionLogging *this;
1462 SILC_LOG_DEBUG(("Setting configured log file names"));
1464 if ((this = config->logging_info))
1465 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1467 if ((this = config->logging_warnings))
1468 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1470 if ((this = config->logging_errors))
1471 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1473 if ((this = config->logging_fatals))
1474 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1478 /* Returns client authentication information from configuration file by host
1481 SilcServerConfigSectionClient *
1482 silc_server_config_find_client(SilcServer server, char *host, int port)
1484 SilcServerConfig config = server->config;
1485 SilcServerConfigSectionClient *client;
1487 if (!config || !port) {
1488 SILC_LOG_WARNING(("Bogus: config_find_client(config=0x%08x, "
1489 "host=0x%08x \"%s\", port=%hu)",
1490 (uint32) config, (uint32) host, host, port));
1496 for (client = config->clients; client; client = client->next) {
1497 if (client->host && !silc_string_compare(client->host, host))
1499 if (client->port && (client->port != port))
1504 /* if none matched, then client is already NULL */
1508 /* Returns admin connection configuration by host, username and/or
1511 SilcServerConfigSectionAdmin *
1512 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1515 SilcServerConfig config = server->config;
1516 SilcServerConfigSectionAdmin *admin;
1518 /* make sure we have a value for the matching parameters */
1526 for (admin = config->admins; admin; admin = admin->next) {
1527 if (admin->host && !silc_string_compare(admin->host, host))
1529 if (admin->user && !silc_string_compare(admin->user, user))
1531 if (admin->nick && !silc_string_compare(admin->nick, nick))
1533 /* no checks failed -> this entry matches */
1537 /* if none matched, then admin is already NULL */
1541 /* Returns the denied connection configuration entry by host and port. */
1543 SilcServerConfigSectionDeny *
1544 silc_server_config_find_denied(SilcServer server, char *host, uint16 port)
1546 SilcServerConfig config = server->config;
1547 SilcServerConfigSectionDeny *deny;
1549 /* make sure we have a value for the matching parameters */
1550 if (!config || !port) {
1551 SILC_LOG_WARNING(("Bogus: config_find_denied(config=0x%08x, "
1552 "host=0x%08x \"%s\", port=%hu)",
1553 (uint32) config, (uint32) host, host, port));
1559 for (deny = config->denied; deny; deny = deny->next) {
1560 if (deny->host && !silc_string_compare(deny->host, host))
1565 /* if none matched, then deny is already NULL */
1569 /* Returns server connection info from server configuartion by host
1572 SilcServerConfigSectionServer *
1573 silc_server_config_find_server_conn(SilcServer server, char *host)
1575 SilcServerConfig config = server->config;
1576 SilcServerConfigSectionServer *serv = NULL;
1581 if (!config->servers)
1584 for (serv = config->servers; serv; serv = serv->next) {
1585 if (!silc_string_compare(serv->host, host))
1593 /* Returns router connection info from server configuration by
1594 host (name or ip). */
1596 SilcServerConfigSectionRouter *
1597 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1599 SilcServerConfig config = server->config;
1600 SilcServerConfigSectionRouter *serv = NULL;
1605 if (!config->routers)
1608 for (serv = config->routers; serv; serv = serv->next) {
1609 if (!silc_string_compare(serv->host, host))
1611 if (port && serv->port && serv->port != port)
1619 /* Returns TRUE if configuration for a router connection that we are
1620 initiating exists. */
1622 bool silc_server_config_is_primary_route(SilcServer server)
1624 SilcServerConfig config = server->config;
1625 SilcServerConfigSectionRouter *serv = NULL;
1629 serv = config->routers;
1630 for (i = 0; serv; i++) {
1631 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1642 /* Returns our primary connection configuration or NULL if we do not
1643 have primary router configured. */
1645 SilcServerConfigSectionRouter *
1646 silc_server_config_get_primary_router(SilcServer server)
1648 SilcServerConfig config = server->config;
1649 SilcServerConfigSectionRouter *serv = NULL;
1652 serv = config->routers;
1653 for (i = 0; serv; i++) {
1654 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1662 /* Set default values to stuff that was not configured. */
1664 bool silc_server_config_set_defaults(SilcServer server)
1666 SilcServerConfig config = server->config;
1668 config->param.keepalive_secs = (config->param.keepalive_secs ?
1669 config->param.keepalive_secs :
1670 SILC_SERVER_KEEPALIVE);
1671 config->param.reconnect_count = (config->param.reconnect_count ?
1672 config->param.reconnect_count :
1673 SILC_SERVER_RETRY_COUNT);
1674 config->param.reconnect_interval = (config->param.reconnect_interval ?
1675 config->param.reconnect_interval :
1676 SILC_SERVER_RETRY_INTERVAL_MIN);
1677 config->param.reconnect_interval_max =
1678 (config->param.reconnect_interval_max ?
1679 config->param.reconnect_interval_max :
1680 SILC_SERVER_RETRY_INTERVAL_MAX);