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 /* free an authdata according to its auth method */
54 static void my_free_authdata(char *passphrase, void *public_key)
56 silc_free(passphrase);
58 silc_pkcs_public_key_free((SilcPublicKey) public_key);
61 /* parse an authdata according to its auth method */
62 static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line,
63 void **auth_data, uint32 *auth_data_len)
65 if (auth_meth == SILC_AUTH_PASSWORD) {
66 /* p is a plain text password */
68 *auth_data = (void *) strdup(p);
70 *auth_data_len = (uint32) strlen(p);
71 } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
72 /* p is a public key */
73 SilcPublicKey public_key;
75 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
76 if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_BIN)) {
77 fprintf(stderr, "\nError while parsing config file at line %lu: "
78 "Could not load public key file!\n", line);
82 *auth_data = (void *) public_key;
86 fprintf(stderr, "\nError while parsing config file at line %lu: "
87 "Unkonwn authentication method\n", line);
95 SILC_CONFIG_CALLBACK(fetch_generic)
97 SilcServerConfig config = (SilcServerConfig) context;
99 if (!strcmp(name, "module_path")) {
100 if (config->module_path)
101 return SILC_CONFIG_EDOUBLE;
103 /* dup it only if non-empty, otherwise point it to NULL */
104 config->module_path = (*(char *)val ? strdup((char *) val) : NULL);
106 else if (!strcmp(name, "prefer_passphrase_auth")) {
107 config->prefer_passphrase_auth = *(bool *)val;
110 return SILC_CONFIG_EINTERNAL;
112 return SILC_CONFIG_OK;
115 SILC_CONFIG_CALLBACK(fetch_cipher)
117 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionCipher);
119 SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)",
120 type, name, context));
121 if (type == SILC_CONFIG_ARG_BLOCK) {
122 /* check the temporary struct's fields */
123 if (!tmp) /* empty sub-block? */
124 return SILC_CONFIG_OK;
126 got_errno = SILC_CONFIG_EMISSFIELDS;
129 /* the temporary struct is ok, append it to the list */
130 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->cipher);
132 return SILC_CONFIG_OK;
134 /* if there isn't a temporary struct alloc one */
136 config->tmp = silc_calloc(1, sizeof(*findtmp));
137 tmp = (SilcServerConfigSectionCipher *) config->tmp;
140 /* Identify and save this value */
141 if (!strcmp(name, "name")) {
142 if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
143 tmp->name = strdup((char *) val);
145 else if (!strcmp(name, "module")) { /* can be empty */
146 if (tmp->module) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
147 /* dup it only if non-empty, otherwise point it to NULL */
148 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
150 else if (!strcmp(name, "keylength"))
151 tmp->key_length = *(uint32 *)val;
152 else if (!strcmp(name, "blocklength"))
153 tmp->block_length = *(uint32 *)val;
155 return SILC_CONFIG_EINTERNAL;
156 return SILC_CONFIG_OK;
159 silc_free(tmp->name);
160 silc_free(tmp->module);
166 SILC_CONFIG_CALLBACK(fetch_hash)
168 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHash);
170 SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)",
171 type, name, context));
172 if (type == SILC_CONFIG_ARG_BLOCK) {
173 /* check the temporary struct's fields */
174 if (!tmp) /* empty sub-block? */
175 return SILC_CONFIG_OK;
176 if (!tmp->name || (tmp->block_length == 0) || (tmp->digest_length == 0)) {
177 got_errno = SILC_CONFIG_EMISSFIELDS;
180 /* the temporary struct in tmp is ok */
181 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hash);
183 return SILC_CONFIG_OK;
185 /* if there isn't a temporary struct alloc one */
187 config->tmp = silc_calloc(1, sizeof(*findtmp));
188 tmp = (SilcServerConfigSectionHash *) config->tmp;
191 /* Identify and save this value */
192 if (!strcmp(name, "name")) {
193 if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
194 tmp->name = strdup((char *) val);
196 else if (!strcmp(name, "module")) { /* can be empty */
197 if (tmp->module) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
198 /* dup it only if non-empty, otherwise point it to NULL */
199 tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
201 else if (!strcmp(name, "blocklength"))
202 tmp->block_length = *(int *)val;
203 else if (!strcmp(name, "digestlength"))
204 tmp->digest_length = *(int *)val;
206 return SILC_CONFIG_EINTERNAL;
207 return SILC_CONFIG_OK;
210 silc_free(tmp->name);
211 silc_free(tmp->module);
217 SILC_CONFIG_CALLBACK(fetch_hmac)
219 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHmac);
221 SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)",
222 type, name, context));
223 if (type == SILC_CONFIG_ARG_BLOCK) {
224 /* check the temporary struct's fields */
225 if (!tmp) /* empty sub-block? */
226 return SILC_CONFIG_OK;
227 if (!tmp->name || !tmp->hash || (tmp->mac_length == 0)) {
228 got_errno = SILC_CONFIG_EMISSFIELDS;
231 /* the temporary struct is ok, append it to the list */
232 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->hmac);
234 return SILC_CONFIG_OK;
236 /* if there isn't a temporary struct alloc one */
238 config->tmp = silc_calloc(1, sizeof(*findtmp));
239 tmp = (SilcServerConfigSectionHmac *) config->tmp;
242 /* Identify and save this value */
243 if (!strcmp(name, "name")) {
244 if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
245 tmp->name = strdup((char *) val);
247 else if (!strcmp(name, "hash")) {
248 if (tmp->hash) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
249 tmp->hash = strdup((char *) val);
251 else if (!strcmp(name, "maclength"))
252 tmp->mac_length = *(int *)val;
254 return SILC_CONFIG_EINTERNAL;
255 return SILC_CONFIG_OK;
258 silc_free(tmp->name);
259 silc_free(tmp->hash);
265 SILC_CONFIG_CALLBACK(fetch_pkcs)
267 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionPkcs);
269 SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)",
270 type, name, context));
271 if (type == SILC_CONFIG_ARG_BLOCK) {
272 /* check the temporary struct's fields */
273 if (!tmp) /* empty sub-block? */
274 return SILC_CONFIG_OK;
276 got_errno = SILC_CONFIG_EMISSFIELDS;
279 /* the temporary struct is ok, append it to the list */
280 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->pkcs);
282 return SILC_CONFIG_OK;
284 /* if there isn't a temporary struct alloc one */
286 config->tmp = silc_calloc(1, sizeof(*findtmp));
287 tmp = (SilcServerConfigSectionPkcs *) config->tmp;
290 /* Identify and save this value */
291 if (!strcmp(name, "name")) {
292 if (tmp->name) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
293 tmp->name = strdup((char *) val);
296 return SILC_CONFIG_EINTERNAL;
297 return SILC_CONFIG_OK;
300 silc_free(tmp->name);
306 SILC_CONFIG_CALLBACK(fetch_serverinfo)
308 SilcServerConfig config = (SilcServerConfig) context;
309 SilcServerConfigSectionServerInfo *server_info = config->server_info;
311 /* if there isn't the struct alloc it */
313 config->server_info = server_info = (SilcServerConfigSectionServerInfo *)
314 silc_calloc(1, sizeof(*server_info));
317 if (type == SILC_CONFIG_ARG_BLOCK) {
318 /* check for mandatory inputs */
319 return SILC_CONFIG_OK;
321 if (!strcmp(name, "hostname")) {
322 if (server_info->server_name) return SILC_CONFIG_EDOUBLE;
323 server_info->server_name = strdup((char *) val);
325 else if (!strcmp(name, "ip")) {
326 if (server_info->server_ip) return SILC_CONFIG_EDOUBLE;
327 server_info->server_ip = strdup((char *) val);
329 else if (!strcmp(name, "port")) {
330 int port = *(int *)val;
331 if ((port <= 0) || (port > 65535)) {
332 fprintf(stderr, "Invalid port number!\n");
333 return SILC_CONFIG_ESILENT;
335 server_info->port = (uint16) port;
337 else if (!strcmp(name, "servertype")) {
338 if (server_info->server_type) return SILC_CONFIG_EDOUBLE;
339 server_info->server_type = strdup((char *) val);
341 else if (!strcmp(name, "admin")) {
342 if (server_info->admin) return SILC_CONFIG_EDOUBLE;
343 server_info->admin = strdup((char *) val);
345 else if (!strcmp(name, "adminemail")) {
346 if (server_info->email) return SILC_CONFIG_EDOUBLE;
347 server_info->email = strdup((char *) val);
349 else if (!strcmp(name, "location")) {
350 if (server_info->location) return SILC_CONFIG_EDOUBLE;
351 server_info->location = strdup((char *) val);
353 else if (!strcmp(name, "user")) {
354 if (server_info->user) return SILC_CONFIG_EDOUBLE;
355 server_info->user = strdup((char *) val);
357 else if (!strcmp(name, "group")) {
358 if (server_info->group) return SILC_CONFIG_EDOUBLE;
359 server_info->group = strdup((char *) val);
361 else if (!strcmp(name, "motdfile")) {
362 if (server_info->motd_file) return SILC_CONFIG_EDOUBLE;
363 server_info->motd_file = strdup((char *) val);
365 else if (!strcmp(name, "pidfile")) {
366 if (server_info->pid_file) return SILC_CONFIG_EDOUBLE;
367 server_info->pid_file = strdup((char *) val);
369 else if (!strcmp(name, "publickey")) {
370 char *tmp = (char *) val;
372 /* try to load specified file, if fail stop config parsing */
373 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
375 if (!silc_pkcs_load_public_key(tmp, &server_info->public_key,
376 SILC_PKCS_FILE_BIN)) {
377 fprintf(stderr, "\nError: Could not load public key file.");
378 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
379 return SILC_CONFIG_ESILENT;
382 else if (!strcmp(name, "privatekey")) {
383 char *tmp = (char *) val;
385 /* try to load specified file, if fail stop config parsing */
386 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
388 if (!silc_pkcs_load_private_key(tmp, &server_info->private_key,
389 SILC_PKCS_FILE_PEM)) {
390 fprintf(stderr, "\nError: Could not load private key file.");
391 fprintf(stderr, "\n line %lu: file \"%s\"\n", line, tmp);
392 return SILC_CONFIG_ESILENT;
396 return SILC_CONFIG_EINTERNAL;
397 return SILC_CONFIG_OK;
400 SILC_CONFIG_CALLBACK(fetch_logging)
402 SilcServerConfig config = (SilcServerConfig) context;
403 SilcServerConfigSectionLogging *tmp =
404 (SilcServerConfigSectionLogging *) config->tmp;
407 if (!strcmp(name, "quicklogs")) {
408 silc_log_quick = *(bool *)val;
410 else if (!strcmp(name, "flushdelay")) {
411 int flushdelay = *(int *)val;
412 if (flushdelay < 2) { /* this value was taken from silclog.h (min delay) */
413 fprintf(stderr, "Error: line %lu: invalid flushdelay value, use "
414 "quicklogs if you want real-time logging.\n", line);
415 return SILC_CONFIG_ESILENT;
417 silc_log_flushdelay = (long) flushdelay;
419 #define FETCH_LOGGING_CHAN(__chan__, __member__) \
420 else if (!strcmp(name, __chan__)) { \
421 if (!tmp) return SILC_CONFIG_OK; \
423 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; \
425 config->__member__ = tmp; \
426 config->tmp = NULL; \
428 FETCH_LOGGING_CHAN("info", logging_info)
429 FETCH_LOGGING_CHAN("warnings", logging_warnings)
430 FETCH_LOGGING_CHAN("errors", logging_errors)
431 FETCH_LOGGING_CHAN("fatals", logging_fatals)
432 #undef FETCH_LOGGING_CHAN
433 else if (!strcmp(name, "file")) {
434 if (!tmp) { /* FIXME: what the fuck is this? */
435 config->tmp = silc_calloc(1, sizeof(*tmp));
436 tmp = (SilcServerConfigSectionLogging *) config->tmp;
439 got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err;
441 tmp->file = strdup((char *) val);
443 else if (!strcmp(name, "size")) {
445 config->tmp = silc_calloc(1, sizeof(*tmp));
446 tmp = (SilcServerConfigSectionLogging *) config->tmp;
448 tmp->maxsize = *(uint32 *) val;
451 return SILC_CONFIG_EINTERNAL;
452 return SILC_CONFIG_OK;
455 silc_free(tmp->file);
461 SILC_CONFIG_CALLBACK(fetch_client)
463 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionClient);
465 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
466 type, name, context));
468 if (type == SILC_CONFIG_ARG_BLOCK) {
469 if (!tmp) /* empty sub-block? */
470 return SILC_CONFIG_OK;
472 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->clients);
474 return SILC_CONFIG_OK;
477 /* if there isn't a temporary struct alloc one */
479 config->tmp = silc_calloc(1, sizeof(*findtmp));
480 tmp = (SilcServerConfigSectionClient *) config->tmp;
483 /* Identify and save this value */
484 if (!strcmp(name, "host")) { /* any host (*) accepted */
485 if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
486 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
488 else if (!strcmp(name, "passphrase")) {
489 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
490 (void **)&tmp->passphrase,
491 &tmp->passphrase_len)) {
492 got_errno = SILC_CONFIG_ESILENT;
496 else if (!strcmp(name, "publickey")) {
497 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
498 &tmp->publickey, NULL)) {
499 got_errno = SILC_CONFIG_ESILENT;
503 else if (!strcmp(name, "port")) {
504 int port = *(int *)val;
505 if ((port <= 0) || (port > 65535)) {
506 fprintf(stderr, "Invalid port number!\n");
507 got_errno = SILC_CONFIG_ESILENT; goto got_err;
509 tmp->port = (uint16) port;
511 /* FIXME: Improvement: use a direct class struct pointer instead of num */
512 else if (!strcmp(name, "class")) {
516 return SILC_CONFIG_EINTERNAL;
517 return SILC_CONFIG_OK;
520 silc_free(tmp->host);
521 my_free_authdata(tmp->passphrase, tmp->publickey);
527 SILC_CONFIG_CALLBACK(fetch_admin)
529 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionAdmin);
531 SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)",
532 type, name, context));
534 if (type == SILC_CONFIG_ARG_BLOCK) {
535 /* check the temporary struct's fields */
536 if (!tmp) /* empty sub-block? */
537 return SILC_CONFIG_OK;
539 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->admins);
541 return SILC_CONFIG_OK;
544 /* if there isn't a temporary struct alloc one */
546 config->tmp = silc_calloc(1, sizeof(*findtmp));
547 tmp = (SilcServerConfigSectionAdmin *) config->tmp;
550 /* Identify and save this value */
551 if (!strcmp(name, "host")) { /* any host (*) accepted */
552 if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
553 tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
555 else if (!strcmp(name, "user")) {
556 if (tmp->user) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
557 tmp->user = (*(char *)val ? strdup((char *) val) : NULL);
559 else if (!strcmp(name, "nick")) {
560 if (tmp->nick) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
561 tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
563 else if (!strcmp(name, "passphrase")) {
564 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
565 (void **)&tmp->passphrase,
566 &tmp->passphrase_len)) {
567 got_errno = SILC_CONFIG_ESILENT;
571 else if (!strcmp(name, "publickey")) {
572 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
573 &tmp->publickey, NULL)) {
574 got_errno = SILC_CONFIG_ESILENT;
579 return SILC_CONFIG_EINTERNAL;
580 return SILC_CONFIG_OK;
583 silc_free(tmp->host);
584 silc_free(tmp->user);
585 silc_free(tmp->nick);
586 my_free_authdata(tmp->passphrase, tmp->publickey);
592 SILC_CONFIG_CALLBACK(fetch_deny)
594 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionDeny);
596 SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)",
597 type, name, context));
598 if (type == SILC_CONFIG_ARG_BLOCK) {
599 /* check the temporary struct's fields */
600 if (!tmp) /* empty sub-block? */
601 return SILC_CONFIG_OK;
603 got_errno = SILC_CONFIG_EMISSFIELDS;
606 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->denied);
608 return SILC_CONFIG_OK;
610 /* if there isn't a temporary struct alloc one */
612 config->tmp = silc_calloc(1, sizeof(*findtmp));
613 tmp = (SilcServerConfigSectionDeny *) config->tmp;
616 /* Identify and save this value */
617 if (!strcmp(name, "host")) { /* any host (*) accepted */
618 if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
619 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
621 else if (!strcmp(name, "port")) {
622 int port = *(int *)val;
623 if ((port <= 0) || (port > 65535)) {
624 fprintf(stderr, "Invalid port number!\n");
625 got_errno = SILC_CONFIG_ESILENT; goto got_err;
627 tmp->port = (uint16) port;
629 else if (!strcmp(name, "reason")) {
630 if (tmp->reason) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
631 tmp->reason = strdup((char *) val);
634 return SILC_CONFIG_EINTERNAL;
635 return SILC_CONFIG_OK;
638 silc_free(tmp->host);
639 silc_free(tmp->reason);
645 SILC_CONFIG_CALLBACK(fetch_server)
647 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionServer);
649 SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)",
650 type, name, context));
652 if (type == SILC_CONFIG_ARG_BLOCK) {
653 /* check the temporary struct's fields */
654 if (!tmp) /* empty sub-block? */
655 return SILC_CONFIG_OK;
657 /* the temporary struct is ok, append it to the list */
658 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers);
660 return SILC_CONFIG_OK;
663 /* if there isn't a temporary struct alloc one */
665 config->tmp = silc_calloc(1, sizeof(*findtmp));
666 tmp = (SilcServerConfigSectionServer *) config->tmp;
669 /* Identify and save this value */
670 if (!strcmp(name, "host")) { /* any host (*) accepted */
671 if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
672 tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
674 else if (!strcmp(name, "passphrase")) {
675 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
676 (void **)&tmp->passphrase,
677 &tmp->passphrase_len)) {
678 got_errno = SILC_CONFIG_ESILENT;
682 else if (!strcmp(name, "publickey")) {
683 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
684 &tmp->publickey, NULL)) {
685 got_errno = SILC_CONFIG_ESILENT;
689 else if (!strcmp(name, "versionid")) {
690 if (tmp->version) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
691 tmp->version = strdup((char *) val);
693 /* FIXME: Improvement: use a direct class struct pointer instead of num */
694 else if (!strcmp(name, "class")) {
697 else if (!strcmp(name, "backup")) {
698 tmp->backup_router = *(bool *)val;
701 return SILC_CONFIG_EINTERNAL;
703 return SILC_CONFIG_OK;
706 silc_free(tmp->host);
707 silc_free(tmp->version);
708 my_free_authdata(tmp->passphrase, tmp->publickey);
714 SILC_CONFIG_CALLBACK(fetch_router)
716 SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionRouter);
718 SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)",
719 type, name, context));
721 if (type == SILC_CONFIG_ARG_BLOCK) {
722 if (!tmp) /* empty sub-block? */
723 return SILC_CONFIG_OK;
725 /* the temporary struct is ok, append it to the list */
726 SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers);
728 return SILC_CONFIG_OK;
731 /* if there isn't a temporary struct alloc one */
733 config->tmp = silc_calloc(1, sizeof(*findtmp));
734 tmp = (SilcServerConfigSectionRouter *) config->tmp;
737 /* Identify and save this value */
738 if (!strcmp(name, "host")) {
739 if (tmp->host) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
740 tmp->host = strdup((char *) val);
742 else if (!strcmp(name, "port")) {
743 int port = *(int *)val;
744 if ((port <= 0) || (port > 65535)) {
745 fprintf(stderr, "Invalid port number!\n");
746 return SILC_CONFIG_ESILENT;
748 tmp->port = (uint16) port;
750 else if (!strcmp(name, "passphrase")) {
751 if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
752 (void **)&tmp->passphrase,
753 &tmp->passphrase_len)) {
754 got_errno = SILC_CONFIG_ESILENT;
758 else if (!strcmp(name, "publickey")) {
759 if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
760 &tmp->publickey, NULL)) {
761 got_errno = SILC_CONFIG_ESILENT;
765 else if (!strcmp(name, "versionid")) {
766 if (tmp->version) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
767 tmp->version = strdup((char *) val);
769 /* FIXME: Improvement: use a direct class struct pointer instead of num */
770 else if (!strcmp(name, "class")) {
773 else if (!strcmp(name, "initiator"))
774 tmp->initiator = *(bool *)val;
775 else if (!strcmp(name, "backuphost")) {
776 if (tmp->backup_replace_ip) { got_errno = SILC_CONFIG_EDOUBLE; goto got_err; }
777 tmp->backup_replace_ip = (*(char *)val ? strdup((char *) val) : strdup("*"));
780 return SILC_CONFIG_EINTERNAL;
782 return SILC_CONFIG_OK;
785 silc_free(tmp->host);
786 silc_free(tmp->version);
787 silc_free(tmp->backup_replace_ip);
788 my_free_authdata(tmp->passphrase, tmp->publickey);
794 /* known config options tables */
795 static const SilcConfigTable table_general[] = {
796 { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
797 { "prefer_passphrase_auth", SILC_CONFIG_ARG_STRE, fetch_generic, NULL },
801 static const SilcConfigTable table_cipher[] = {
802 { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL },
803 { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL },
804 { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
805 { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL },
809 static const SilcConfigTable table_hash[] = {
810 { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL },
811 { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL },
812 { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
813 { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL },
817 static const SilcConfigTable table_hmac[] = {
818 { "name", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
819 { "hash", SILC_CONFIG_ARG_STR, fetch_hmac, NULL },
820 { "maclength", SILC_CONFIG_ARG_INT, fetch_hmac, NULL },
824 static const SilcConfigTable table_pkcs[] = {
825 { "name", SILC_CONFIG_ARG_STR, fetch_pkcs, NULL },
829 static const SilcConfigTable table_serverinfo[] = {
830 { "hostname", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
831 { "ip", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
832 { "port", SILC_CONFIG_ARG_INT, fetch_serverinfo, NULL},
833 { "servertype", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
834 { "location", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
835 { "admin", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
836 { "adminemail", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
837 { "user", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
838 { "group", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
839 { "publickey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
840 { "privatekey", SILC_CONFIG_ARG_STR, fetch_serverinfo, NULL},
841 { "motdfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
842 { "pidfile", SILC_CONFIG_ARG_STRE, fetch_serverinfo, NULL},
846 static const SilcConfigTable table_logging_c[] = {
847 { "file", SILC_CONFIG_ARG_STR, fetch_logging, NULL },
848 { "size", SILC_CONFIG_ARG_SIZE, fetch_logging, NULL },
849 /*{ "quicklog", SILC_CONFIG_ARG_NONE, fetch_logging, NULL }, */
853 static const SilcConfigTable table_logging[] = {
854 { "quicklogs", SILC_CONFIG_ARG_TOGGLE, fetch_logging, NULL },
855 { "flushdelay", SILC_CONFIG_ARG_INT, fetch_logging, NULL },
856 { "info", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
857 { "warnings", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
858 { "errors", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
859 { "fatals", SILC_CONFIG_ARG_BLOCK, fetch_logging, table_logging_c },
864 static const SilcConfigTable table_class[] = {
865 { "name", SILC_CONFIG_ARG_STR, fetch_class, NULL },
866 { "ping", SILC_CONFIG_ARG_INT, fetch_class, NULL },
867 { "connect", SILC_CONFIG_ARG_INT, fetch_class, NULL },
868 { "links", SILC_CONFIG_ARG_INT, fetch_class, NULL },
872 static const SilcConfigTable table_client[] = {
873 { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL },
874 { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL },
875 { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL },
876 { "port", SILC_CONFIG_ARG_INT, fetch_client, NULL },
877 { "class", SILC_CONFIG_ARG_STR, fetch_client, NULL },
881 static const SilcConfigTable table_admin[] = {
882 { "host", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
883 { "user", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
884 { "nick", SILC_CONFIG_ARG_STRE, fetch_admin, NULL },
885 { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
886 { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
887 { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL },
888 { "class", SILC_CONFIG_ARG_STR, fetch_admin, NULL },
892 static const SilcConfigTable table_deny[] = {
893 { "host", SILC_CONFIG_ARG_STRE, fetch_deny, NULL },
894 { "port", SILC_CONFIG_ARG_INT, fetch_deny, NULL },
895 { "reason", SILC_CONFIG_ARG_STR, fetch_deny, NULL },
899 static const SilcConfigTable table_serverconn[] = {
900 { "host", SILC_CONFIG_ARG_STRE, fetch_server, NULL },
901 { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL },
902 { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL },
903 { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL },
904 { "class", SILC_CONFIG_ARG_STR, fetch_server, NULL },
905 { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL },
909 static const SilcConfigTable table_routerconn[] = {
910 { "host", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
911 { "port", SILC_CONFIG_ARG_INT, fetch_router, NULL },
912 { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL },
913 { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL },
914 { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL },
915 { "class", SILC_CONFIG_ARG_STR, fetch_router, NULL },
916 { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
917 { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL },
918 { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL },
919 { "localbackup", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL },
923 static const SilcConfigTable table_main[] = {
924 { "general", SILC_CONFIG_ARG_BLOCK, NULL, table_general },
925 { "cipher", SILC_CONFIG_ARG_BLOCK, fetch_cipher, table_cipher },
926 { "hash", SILC_CONFIG_ARG_BLOCK, fetch_hash, table_hash },
927 { "hmac", SILC_CONFIG_ARG_BLOCK, fetch_hmac, table_hmac },
928 { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs },
929 { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo },
930 { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging },
931 /*{ "class", SILC_CONFIG_ARG_BLOCK, fetch_class, table_class }, */
932 { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client },
933 { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin },
934 { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny },
935 { "serverconnection", SILC_CONFIG_ARG_BLOCK, fetch_server, table_serverconn },
936 { "routerconnection", SILC_CONFIG_ARG_BLOCK, fetch_router, table_routerconn },
940 /* Allocates a new configuration object, opens configuration file and
941 * parses it. The parsed data is returned to the newly allocated
942 * configuration object. */
944 SilcServerConfig silc_server_config_alloc(char *filename)
946 SilcServerConfig config;
947 SilcConfigEntity ent;
948 SilcConfigFile *file;
950 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
952 /* alloc a config object */
953 config = (SilcServerConfig) silc_calloc(1, sizeof(*config));
954 /* obtain a config file object */
955 file = silc_config_open(filename);
957 fprintf(stderr, "\nError: can't open config file `%s'\n", filename);
960 /* obtain a SilcConfig entity, we can use it to start the parsing */
961 ent = silc_config_init(file);
962 /* load the known configuration options, give our empty object as context */
963 silc_config_register_table(ent, table_main, (void *) config);
964 /* enter the main parsing loop. When this returns, we have the parsing
965 * result and the object filled (or partially, in case of errors). */
966 ret = silc_config_main(ent);
967 SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret, silc_config_strerror(ret)));
969 /* Check if the parser returned errors */
971 /* handle this special error return which asks to quietly return */
972 if (ret != SILC_CONFIG_ESILENT) {
973 char *linebuf, *filename = silc_config_get_filename(file);
974 uint32 line = silc_config_get_line(file);
975 fprintf(stderr, "\nError while parsing config file: %s.\n",
976 silc_config_strerror(ret));
977 linebuf = silc_config_read_line(file, line);
978 fprintf(stderr, " file %s line %lu: %s\n\n", filename, line, linebuf);
983 /* close (destroy) the file object */
984 silc_config_close(file);
986 /* XXX FIXME: check for missing mandatory fields */
987 if (!config->server_info) {
988 fprintf(stderr, "\nError: Missing mandatory block `server_info'\n");
996 void silc_server_config_destroy(SilcServerConfig config)
999 silc_free(config->module_path);
1001 /* Destroy Logging channels */
1002 if (config->logging_info)
1003 silc_free(config->logging_info->file);
1004 if (config->logging_warnings)
1005 silc_free(config->logging_warnings->file);
1006 if (config->logging_errors)
1007 silc_free(config->logging_errors->file);
1008 if (config->logging_fatals)
1009 silc_free(config->logging_fatals->file);
1011 /* Destroy the ServerInfo struct */
1012 if (config->server_info) {
1013 register SilcServerConfigSectionServerInfo *si = config->server_info;
1014 silc_free(si->server_name);
1015 silc_free(si->server_ip);
1016 silc_free(si->server_type);
1017 silc_free(si->location);
1018 silc_free(si->admin);
1019 silc_free(si->email);
1020 silc_free(si->user);
1021 silc_free(si->group);
1022 silc_free(si->motd_file);
1023 silc_free(si->pid_file);
1026 /* Now let's destroy the lists */
1028 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionCipher,
1030 silc_free(di->name);
1031 silc_free(di->module);
1034 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHash, config->hash)
1035 silc_free(di->name);
1036 silc_free(di->module);
1039 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHmac, config->hmac)
1040 silc_free(di->name);
1041 silc_free(di->hash);
1044 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionPkcs, config->pkcs)
1045 silc_free(di->name);
1048 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionClient,
1050 silc_free(di->host);
1051 my_free_authdata(di->passphrase, di->publickey);
1054 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionAdmin, config->admins)
1055 silc_free(di->host);
1056 silc_free(di->user);
1057 silc_free(di->nick);
1058 my_free_authdata(di->passphrase, di->publickey);
1061 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionDeny, config->denied)
1062 silc_free(di->host);
1063 silc_free(di->reason);
1066 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionServer,
1068 silc_free(di->host);
1069 silc_free(di->version);
1070 my_free_authdata(di->passphrase, di->publickey);
1073 SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionRouter,
1075 silc_free(di->host);
1076 silc_free(di->version);
1077 silc_free(di->backup_replace_ip);
1078 my_free_authdata(di->passphrase, di->publickey);
1083 /* Registers configured ciphers. These can then be allocated by the
1084 server when needed. */
1086 bool silc_server_config_register_ciphers(SilcServer server)
1088 SilcServerConfig config = server->config;
1089 SilcServerConfigSectionCipher *cipher = config->cipher;
1090 char *module_path = config->module_path;
1092 SILC_LOG_DEBUG(("Registering configured ciphers"));
1094 if (!cipher) /* any cipher in the config file? */
1098 /* if there isn't a module_path OR there isn't a module sim name try to
1099 * use buil-in functions */
1100 if (!module_path || !cipher->module) {
1102 for (i = 0; silc_default_ciphers[i].name; i++)
1103 if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
1104 silc_cipher_register(&silc_default_ciphers[i]);
1107 if (!silc_cipher_is_supported(cipher->name)) {
1108 SILC_LOG_ERROR(("Unknown cipher `%s'", cipher->name));
1109 silc_server_stop(server);
1114 /* Load (try at least) the crypto SIM module */
1115 char buf[1023], *alg_name;
1116 SilcCipherObject cipher_obj;
1117 SilcSimContext *sim;
1119 memset(&cipher_obj, 0, sizeof(cipher_obj));
1120 cipher_obj.name = cipher->name;
1121 cipher_obj.block_len = cipher->block_length;
1122 cipher_obj.key_len = cipher->key_length * 8;
1124 /* build the libname */
1125 snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
1127 sim = silc_sim_alloc();
1128 sim->type = SILC_SIM_CIPHER;
1131 alg_name = strdup(cipher->name);
1132 if (strchr(alg_name, '-'))
1133 *strchr(alg_name, '-') = '\0';
1135 if (silc_sim_load(sim)) {
1136 cipher_obj.set_key =
1137 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1138 SILC_CIPHER_SIM_SET_KEY));
1139 SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key));
1140 cipher_obj.set_key_with_string =
1141 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1142 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1143 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher_obj.set_key_with_string));
1144 cipher_obj.encrypt =
1145 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1146 SILC_CIPHER_SIM_ENCRYPT_CBC));
1147 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher_obj.encrypt));
1148 cipher_obj.decrypt =
1149 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1150 SILC_CIPHER_SIM_DECRYPT_CBC));
1151 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher_obj.decrypt));
1152 cipher_obj.context_len =
1153 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1154 SILC_CIPHER_SIM_CONTEXT_LEN));
1155 SILC_LOG_DEBUG(("context_len=%p", cipher_obj.context_len));
1157 /* Put the SIM to the list of all SIM's in server */
1158 silc_dlist_add(server->sim, sim);
1160 silc_free(alg_name);
1162 SILC_LOG_ERROR(("Error configuring ciphers"));
1163 silc_server_stop(server);
1167 /* Register the cipher */
1168 silc_cipher_register(&cipher_obj);
1170 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1171 "can't load modules!"));
1172 silc_server_stop(server);
1176 cipher = cipher->next;
1182 /* Registers configured hash functions. These can then be allocated by the
1183 server when needed. */
1185 bool silc_server_config_register_hashfuncs(SilcServer server)
1187 SilcServerConfig config = server->config;
1188 SilcServerConfigSectionHash *hash = config->hash;
1189 char *module_path = config->module_path;
1191 SILC_LOG_DEBUG(("Registering configured hash functions"));
1193 if (!hash) /* any hash func in the config file? */
1197 /* if there isn't a module_path OR there isn't a module sim name try to
1198 * use buil-in functions */
1199 if (!module_path || !hash->module) {
1201 for (i = 0; silc_default_hash[i].name; i++)
1202 if (!strcmp(silc_default_hash[i].name, hash->name)) {
1203 silc_hash_register(&silc_default_hash[i]);
1206 if (!silc_hash_is_supported(hash->name)) {
1207 SILC_LOG_ERROR(("Unknown hash funtion `%s'", hash->name));
1208 silc_server_stop(server);
1213 /* Load (try at least) the hash SIM module */
1214 SilcHashObject hash_obj;
1215 SilcSimContext *sim;
1217 memset(&hash_obj, 0, sizeof(hash_obj));
1218 hash_obj.name = hash->name;
1219 hash_obj.block_len = hash->block_length;
1220 hash_obj.hash_len = hash->digest_length;
1222 sim = silc_sim_alloc();
1223 sim->type = SILC_SIM_HASH;
1224 sim->libname = hash->module;
1226 if ((silc_sim_load(sim))) {
1228 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1229 SILC_HASH_SIM_INIT));
1230 SILC_LOG_DEBUG(("init=%p", hash_obj.init));
1232 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1233 SILC_HASH_SIM_UPDATE));
1234 SILC_LOG_DEBUG(("update=%p", hash_obj.update));
1236 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1237 SILC_HASH_SIM_FINAL));
1238 SILC_LOG_DEBUG(("final=%p", hash_obj.final));
1239 hash_obj.context_len =
1240 silc_sim_getsym(sim, silc_sim_symname(hash->name,
1241 SILC_HASH_SIM_CONTEXT_LEN));
1242 SILC_LOG_DEBUG(("context_len=%p", hash_obj.context_len));
1244 /* Put the SIM to the table of all SIM's in server */
1245 silc_dlist_add(server->sim, sim);
1247 SILC_LOG_ERROR(("Error configuring hash functions"));
1248 silc_server_stop(server);
1252 /* Register the hash function */
1253 silc_hash_register(&hash_obj);
1255 SILC_LOG_ERROR(("Dynamic module support not compiled, "
1256 "can't load modules!"));
1257 silc_server_stop(server);
1267 /* Registers configure HMACs. These can then be allocated by the server
1270 bool silc_server_config_register_hmacs(SilcServer server)
1272 SilcServerConfig config = server->config;
1273 SilcServerConfigSectionHmac *hmac = config->hmac;
1275 SILC_LOG_DEBUG(("Registering configured HMACs"));
1281 SilcHmacObject hmac_obj;
1282 if (!silc_hash_is_supported(hmac->hash)) {
1283 SILC_LOG_ERROR(("Unknown hash function `%s'", hmac->hash));
1284 silc_server_stop(server);
1287 /* Register the HMAC */
1288 memset(&hmac_obj, 0, sizeof(hmac_obj));
1289 hmac_obj.name = hmac->name;
1290 hmac_obj.len = hmac->mac_length;
1291 silc_hmac_register(&hmac_obj);
1299 /* Registers configured PKCS's. */
1301 bool silc_server_config_register_pkcs(SilcServer server)
1303 SilcServerConfig config = server->config;
1304 SilcServerConfigSectionPkcs *pkcs = config->pkcs;
1306 SILC_LOG_DEBUG(("Registering configured PKCS"));
1313 for (i = 0; silc_default_pkcs[i].name; i++)
1314 if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
1315 silc_pkcs_register(&silc_default_pkcs[i]);
1318 if (!silc_pkcs_is_supported(pkcs->name)) {
1319 SILC_LOG_ERROR(("Unknown PKCS `%s'", pkcs->name));
1320 silc_server_stop(server);
1329 /* Sets log files where log messages are saved by the server logger. */
1331 void silc_server_config_setlogfiles(SilcServer server)
1333 SilcServerConfig config = server->config;
1334 SilcServerConfigSectionLogging *this;
1336 SILC_LOG_DEBUG(("Setting configured log file names"));
1338 if ((this = config->logging_info))
1339 silc_log_set_file(SILC_LOG_INFO, this->file, this->maxsize,
1341 if ((this = config->logging_warnings))
1342 silc_log_set_file(SILC_LOG_WARNING, this->file, this->maxsize,
1344 if ((this = config->logging_errors))
1345 silc_log_set_file(SILC_LOG_ERROR, this->file, this->maxsize,
1347 if ((this = config->logging_fatals))
1348 silc_log_set_file(SILC_LOG_FATAL, this->file, this->maxsize,
1352 /* Returns client authentication information from configuration file by host
1355 SilcServerConfigSectionClient *
1356 silc_server_config_find_client(SilcServer server, char *host, int port)
1358 SilcServerConfig config = server->config;
1359 SilcServerConfigSectionClient *client;
1361 if (!config || !port) {
1362 SILC_LOG_WARNING(("Bogus: config_find_client(config=0x%08x, "
1363 "host=0x%08x \"%s\", port=%hu)",
1364 (uint32) config, (uint32) host, host, port));
1370 for (client = config->clients; client; client = client->next) {
1371 if (client->host && !silc_string_compare(client->host, host))
1373 if (client->port && (client->port != port))
1378 /* if none matched, then client is already NULL */
1382 /* Returns admin connection configuration by host, username and/or
1385 SilcServerConfigSectionAdmin *
1386 silc_server_config_find_admin(SilcServer server, char *host, char *user,
1389 SilcServerConfig config = server->config;
1390 SilcServerConfigSectionAdmin *admin;
1392 /* make sure we have a value for the matching parameters */
1400 for (admin = config->admins; admin; admin = admin->next) {
1401 if (admin->host && !silc_string_compare(admin->host, host))
1403 if (admin->user && !silc_string_compare(admin->user, user))
1405 if (admin->nick && !silc_string_compare(admin->nick, nick))
1407 /* no checks failed -> this entry matches */
1411 /* if none matched, then admin is already NULL */
1415 /* Returns the denied connection configuration entry by host and port. */
1417 SilcServerConfigSectionDeny *
1418 silc_server_config_find_denied(SilcServer server, char *host, uint16 port)
1420 SilcServerConfig config = server->config;
1421 SilcServerConfigSectionDeny *deny;
1423 /* make sure we have a value for the matching parameters */
1424 if (!config || !port) {
1425 SILC_LOG_WARNING(("Bogus: config_find_denied(config=0x%08x, "
1426 "host=0x%08x \"%s\", port=%hu)",
1427 (uint32) config, (uint32) host, host, port));
1433 for (deny = config->denied; deny; deny = deny->next) {
1434 if (deny->host && !silc_string_compare(deny->host, host))
1439 /* if none matched, then deny is already NULL */
1443 /* Returns server connection info from server configuartion by host
1446 SilcServerConfigSectionServer *
1447 silc_server_config_find_server_conn(SilcServer server, char *host)
1449 SilcServerConfig config = server->config;
1450 SilcServerConfigSectionServer *serv = NULL;
1455 if (!config->servers)
1458 for (serv = config->servers; serv; serv = serv->next) {
1459 if (!silc_string_compare(serv->host, host))
1467 /* Returns router connection info from server configuration by
1468 host (name or ip). */
1470 SilcServerConfigSectionRouter *
1471 silc_server_config_find_router_conn(SilcServer server, char *host, int port)
1473 SilcServerConfig config = server->config;
1474 SilcServerConfigSectionRouter *serv = NULL;
1479 if (!config->routers)
1482 for (serv = config->routers; serv; serv = serv->next) {
1483 if (!silc_string_compare(serv->host, host))
1485 if (port && serv->port && serv->port != port)
1493 /* Returns TRUE if configuration for a router connection that we are
1494 initiating exists. */
1496 bool silc_server_config_is_primary_route(SilcServer server)
1498 SilcServerConfig config = server->config;
1499 SilcServerConfigSectionRouter *serv = NULL;
1503 serv = config->routers;
1504 for (i = 0; serv; i++) {
1505 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1516 /* Returns our primary connection configuration or NULL if we do not
1517 have primary router configured. */
1519 SilcServerConfigSectionRouter *
1520 silc_server_config_get_primary_router(SilcServer server)
1522 SilcServerConfig config = server->config;
1523 SilcServerConfigSectionRouter *serv = NULL;
1526 serv = config->routers;
1527 for (i = 0; serv; i++) {
1528 if (serv->initiator == TRUE && serv->backup_router == FALSE)