5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 Pekka Riikonen
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"
25 SilcServerConfigSection silc_server_config_sections[] = {
27 SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 },
29 SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 1 },
31 SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 },
33 SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 },
35 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, 2 },
37 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 },
39 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 },
41 SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 },
43 SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY, 2 },
45 SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 },
46 { "[ConnectionClass]",
47 SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 },
48 { "[ClientConnection]",
49 SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION, 5 },
50 { "[ServerConnection]",
51 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION, 6 },
52 { "[RouterConnection]",
53 SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION, 7 },
54 { "[AdminConnection]",
55 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 },
57 SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 },
59 SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
61 { NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
64 /* Allocates a new configuration object, opens configuration file and
65 parses the file. The parsed data is returned to the newly allocated
66 configuration object. */
68 SilcServerConfig silc_server_config_alloc(char *filename)
72 SilcServerConfigParse config_parse;
74 SILC_LOG_DEBUG(("Allocating new configuration object"));
76 new = silc_calloc(1, sizeof(*new));
78 fprintf(stderr, "Could not allocate new configuration object");
82 new->filename = filename;
84 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
86 /* Open configuration file and parse it */
89 silc_config_open(filename, &buffer);
92 if ((silc_server_config_parse(new, buffer, &config_parse)) == FALSE)
94 if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
106 /* Free's a configuration object. */
108 void silc_server_config_free(SilcServerConfig config)
111 silc_free(config->filename);
112 silc_free(config->server_keys);
113 silc_free(config->server_info);
114 silc_free(config->admin_info);
115 silc_free(config->listen_port);
116 silc_free(config->identity);
117 silc_free(config->conn_class);
118 silc_free(config->clients);
119 silc_free(config->admins);
120 silc_free(config->servers);
121 silc_free(config->routers);
122 silc_free(config->denied);
123 silc_free(config->motd);
128 /* Parses the the buffer and returns the parsed lines into return_config
129 argument. The return_config argument doesn't have to be initialized
130 before calling this. It will be initialized during the parsing. The
131 buffer sent as argument can be safely free'd after this function has
132 succesfully returned. */
134 int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
135 SilcServerConfigParse *return_config)
137 int i, begin, linenum;
138 char line[1024], *cp;
139 SilcServerConfigSection *cptr = NULL;
140 SilcServerConfigParse parse = *return_config, first = NULL;
142 SILC_LOG_DEBUG(("Parsing configuration file"));
146 while((begin = silc_gets(line, sizeof(line),
147 buffer->data, buffer->len, begin)) != EOF) {
151 /* Check for bad line */
152 if (silc_check_line(cp))
155 /* Remove tabs and whitespaces from the line */
156 if (strchr(cp, '\t')) {
158 while(strchr(cp + i, '\t')) {
159 *strchr(cp + i, '\t') = ' ';
163 for (i = 0; i < strlen(cp); i++) {
179 /* Remove new line sign */
180 if (strchr(cp, '\n'))
181 *strchr(cp, '\n') = '\0';
183 /* Check for matching sections */
184 for (cptr = silc_server_config_sections; cptr->section; cptr++)
185 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
188 if (!cptr->section) {
189 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
190 config->filename, linenum, cp);
197 * Start of a configuration line
200 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
202 if (strchr(cp, '\n'))
203 *strchr(cp, '\n') = ':';
206 parse = silc_calloc(1, sizeof(*parse));
208 parse->section = NULL;
212 if (parse->next == NULL) {
213 parse->next = silc_calloc(1, sizeof(*parse->next));
214 parse->next->line = NULL;
215 parse->next->section = NULL;
216 parse->next->next = NULL;
217 parse->next->prev = parse;
225 /* Add the line to parsing structure for further parsing. */
227 parse->section = cptr;
228 parse->line = silc_buffer_alloc(strlen(cp) + 1);
229 parse->linenum = linenum;
230 silc_buffer_pull_tail(parse->line, strlen(cp));
231 silc_buffer_put(parse->line, cp, strlen(cp));
238 /* Set the return_config argument to its first value so that further
239 parsing can be started from the first line. */
240 *return_config = first;
245 /* Parses the lines earlier read from configuration file. The config object
246 must not be initialized, it will be initialized in this function. The
247 parse_config argument is uninitialized automatically during this
250 int silc_server_config_parse_lines(SilcServerConfig config,
251 SilcServerConfigParse parse_config)
253 int ret, check = FALSE;
256 SilcServerConfigParse pc = parse_config;
259 SILC_LOG_DEBUG(("Parsing configuration lines"));
269 /* Get number of tokens in line */
270 ret = silc_config_check_num_token(line);
271 if (ret < pc->section->maxfields) {
273 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
274 config->filename, pc->linenum, ret,
275 pc->section->maxfields);
280 switch(pc->section->type) {
281 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
283 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
285 /* Get cipher name */
286 ret = silc_config_get_token(line, &config->cipher->alg_name);
290 fprintf(stderr, "%s:%d: Cipher name not defined\n",
291 config->filename, pc->linenum);
295 /* Get module name */
296 config->cipher->sim_name = NULL;
297 ret = silc_config_get_token(line, &config->cipher->sim_name);
302 ret = silc_config_get_token(line, &tmp);
306 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
307 config->filename, pc->linenum);
310 config->cipher->key_len = atoi(tmp);
313 /* Get block length */
314 ret = silc_config_get_token(line, &tmp);
318 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
319 config->filename, pc->linenum);
322 config->cipher->block_len = atoi(tmp);
326 checkmask |= (1L << pc->section->type);
329 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
331 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
334 ret = silc_config_get_token(line, &config->pkcs->alg_name);
338 fprintf(stderr, "%s:%d: PKCS name not defined\n",
339 config->filename, pc->linenum);
344 checkmask |= (1L << pc->section->type);
347 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
349 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
351 /* Get Hash function name */
352 ret = silc_config_get_token(line, &config->hash_func->alg_name);
356 fprintf(stderr, "%s:%d: Hash function name not defined\n",
357 config->filename, pc->linenum);
361 /* Get Hash function module name */
362 config->hash_func->sim_name = NULL;
363 ret = silc_config_get_token(line, &config->hash_func->sim_name);
367 /* Get block length */
368 ret = silc_config_get_token(line, &tmp);
372 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
373 config->filename, pc->linenum);
376 config->hash_func->block_len = atoi(tmp);
379 /* Get hash length */
380 ret = silc_config_get_token(line, &tmp);
384 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
385 config->filename, pc->linenum);
388 config->hash_func->key_len = atoi(tmp);
392 checkmask |= (1L << pc->section->type);
395 case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
397 SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
400 ret = silc_config_get_token(line, &config->hmac->alg_name);
404 fprintf(stderr, "%s:%d: HMAC name not defined\n",
405 config->filename, pc->linenum);
410 ret = silc_config_get_token(line, &config->hmac->sim_name);
414 fprintf(stderr, "%s:%d: Hash function name not defined\n",
415 config->filename, pc->linenum);
420 ret = silc_config_get_token(line, &tmp);
424 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
425 config->filename, pc->linenum);
428 config->hmac->key_len = atoi(tmp);
432 checkmask |= (1L << pc->section->type);
435 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS:
437 if (!config->server_keys)
438 config->server_keys = silc_calloc(1, sizeof(*config->server_keys));
440 ret = silc_config_get_token(line, &tmp);
444 fprintf(stderr, "%s:%d: Public key name not defined\n",
445 config->filename, pc->linenum);
449 if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
451 if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
452 SILC_PKCS_FILE_BIN)) {
453 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
454 config->filename, pc->linenum, tmp);
459 ret = silc_config_get_token(line, &tmp);
463 fprintf(stderr, "%s:%d: Private key name not defined\n",
464 config->filename, pc->linenum);
468 if (!silc_pkcs_load_private_key(tmp, &config->server_keys->private_key,
470 if (!silc_pkcs_load_private_key(tmp,
471 &config->server_keys->private_key,
472 SILC_PKCS_FILE_PEM)) {
473 fprintf(stderr, "%s:%d: Could not load private key file `%s'\n",
474 config->filename, pc->linenum, tmp);
480 checkmask |= (1L << pc->section->type);
483 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
485 if (!config->server_info)
486 config->server_info = silc_calloc(1, sizeof(*config->server_info));
488 /* Get server name */
489 ret = silc_config_get_token(line, &config->server_info->server_name);
493 /* Server name not defined */
498 ret = silc_config_get_token(line, &config->server_info->server_ip);
502 /* Server IP not defined */
506 /* Get server location */
507 ret = silc_config_get_token(line, &config->server_info->location);
511 /* Get server port */
512 /* XXX: Need port here??? */
513 ret = silc_config_get_token(line, &tmp);
517 /* Port not defined */
520 config->server_info->port = atoi(tmp);
524 checkmask |= (1L << pc->section->type);
527 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
529 if (!config->admin_info)
530 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
533 ret = silc_config_get_token(line, &config->admin_info->location);
537 /* Get server type */
538 ret = silc_config_get_token(line, &config->admin_info->server_type);
542 /* Get admins name */
543 ret = silc_config_get_token(line, &config->admin_info->admin_name);
547 /* Get admins email address */
548 ret = silc_config_get_token(line, &config->admin_info->admin_email);
553 checkmask |= (1L << pc->section->type);
556 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
558 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
561 ret = silc_config_get_token(line, &config->listen_port->local_ip);
565 /* Get listener IP */
566 ret = silc_config_get_token(line, &config->listen_port->listener_ip);
571 ret = silc_config_get_token(line, &tmp);
576 config->listen_port->port = 0;
578 config->listen_port->port = atoi(tmp);
583 checkmask |= (1L << pc->section->type);
586 case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
588 if (!config->identity)
589 config->identity = silc_calloc(1, sizeof(*config->identity));
592 ret = silc_config_get_token(line, &config->identity->user);
596 ret = silc_config_get_token(line, &config->identity->group);
601 checkmask |= (1L << pc->section->type);
603 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
605 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
607 /* Get class number */
608 ret = silc_config_get_token(line, &tmp);
612 /* Class number not defined */
615 config->conn_class->class = atoi(tmp);
618 /* Get ping frequency */
619 ret = silc_config_get_token(line, &tmp);
622 config->conn_class->ping_freq = atoi(tmp);
625 /* Get connect frequency */
626 ret = silc_config_get_token(line, &tmp);
629 config->conn_class->connect_freq = atoi(tmp);
633 ret = silc_config_get_token(line, &tmp);
636 config->conn_class->max_links = atoi(tmp);
640 checkmask |= (1L << pc->section->type);
643 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
645 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
647 /* Get log section type and check it */
648 ret = silc_config_get_token(line, &config->logging->logtype);
652 fprintf(stderr, "%s:%d: Log file section not defined\n",
653 config->filename, pc->linenum);
656 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
657 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
658 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
659 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
660 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
661 config->filename, pc->linenum, config->logging->logtype);
665 /* Get log filename */
666 ret = silc_config_get_token(line, &config->logging->filename);
670 fprintf(stderr, "%s:%d: Log file name not defined\n",
671 config->filename, pc->linenum);
675 /* Get max byte size */
676 ret = silc_config_get_token(line, &tmp);
680 config->logging->maxsize = atoi(tmp);
685 checkmask |= (1L << pc->section->type);
688 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
690 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
693 ret = silc_config_get_token(line, &config->clients->host);
698 config->clients->host = strdup("*");
700 /* Get authentication method */
701 ret = silc_config_get_token(line, &tmp);
705 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
706 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
707 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
708 config->filename, pc->linenum, tmp);
712 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
713 config->clients->auth_meth = SILC_AUTH_PASSWORD;
715 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
716 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
721 /* Get authentication data */
722 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
726 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
727 config->clients->auth_data_len = strlen(config->clients->auth_data);
728 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
729 /* Get the public key */
730 SilcPublicKey public_key;
732 if (!silc_pkcs_load_public_key(config->clients->auth_data,
733 &public_key, SILC_PKCS_FILE_PEM))
734 if (!silc_pkcs_load_public_key(config->clients->auth_data,
735 &public_key, SILC_PKCS_FILE_BIN)) {
736 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
737 config->filename, pc->linenum,
738 (char *)config->clients->auth_data);
742 silc_free(config->clients->auth_data);
743 config->clients->auth_data = (void *)public_key;
744 config->clients->auth_data_len = 0;
748 ret = silc_config_get_token(line, &tmp);
752 config->clients->port = atoi(tmp);
756 /* Get class number */
757 ret = silc_config_get_token(line, &tmp);
761 config->clients->class = atoi(tmp);
766 checkmask |= (1L << pc->section->type);
769 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
771 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
774 ret = silc_config_get_token(line, &config->servers->host);
779 config->servers->host = strdup("*");
781 /* Get authentication method */
782 ret = silc_config_get_token(line, &tmp);
786 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
787 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
788 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
789 config->filename, pc->linenum, tmp);
793 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
794 config->servers->auth_meth = SILC_AUTH_PASSWORD;
796 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
797 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
802 /* Get authentication data */
803 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
807 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
808 config->servers->auth_data_len = strlen(config->servers->auth_data);
809 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
810 /* Get the public key */
811 SilcPublicKey public_key;
813 if (!silc_pkcs_load_public_key(config->servers->auth_data,
814 &public_key, SILC_PKCS_FILE_PEM))
815 if (!silc_pkcs_load_public_key(config->servers->auth_data,
816 &public_key, SILC_PKCS_FILE_BIN)) {
817 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
818 config->filename, pc->linenum,
819 (char *)config->servers->auth_data);
823 silc_free(config->servers->auth_data);
824 config->servers->auth_data = (void *)public_key;
825 config->servers->auth_data_len = 0;
829 ret = silc_config_get_token(line, &tmp);
833 config->servers->port = atoi(tmp);
838 ret = silc_config_get_token(line, &config->servers->version);
842 /* Get class number */
843 ret = silc_config_get_token(line, &tmp);
847 config->servers->class = atoi(tmp);
851 /* Check whether this connection is backup router connection */
852 ret = silc_config_get_token(line, &tmp);
854 config->servers->backup_router = atoi(tmp);
855 if (config->servers->backup_router != 0)
856 config->servers->backup_router = TRUE;
861 checkmask |= (1L << pc->section->type);
864 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
866 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
869 ret = silc_config_get_token(line, &config->routers->host);
873 /* Get authentication method */
874 ret = silc_config_get_token(line, &tmp);
878 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
879 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
880 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
881 config->filename, pc->linenum, tmp);
885 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
886 config->routers->auth_meth = SILC_AUTH_PASSWORD;
888 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
889 config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
894 /* Get authentication data */
895 ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
899 if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
900 config->routers->auth_data_len = strlen(config->routers->auth_data);
901 } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
902 /* Get the public key */
903 SilcPublicKey public_key;
905 if (!silc_pkcs_load_public_key(config->routers->auth_data,
906 &public_key, SILC_PKCS_FILE_PEM))
907 if (!silc_pkcs_load_public_key(config->routers->auth_data,
908 &public_key, SILC_PKCS_FILE_BIN)) {
909 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
910 config->filename, pc->linenum,
911 (char *)config->routers->auth_data);
915 silc_free(config->routers->auth_data);
916 config->routers->auth_data = (void *)public_key;
917 config->routers->auth_data_len = 0;
921 ret = silc_config_get_token(line, &tmp);
925 config->routers->port = atoi(tmp);
930 ret = silc_config_get_token(line, &config->routers->version);
934 /* Get class number */
935 ret = silc_config_get_token(line, &tmp);
939 config->routers->class = atoi(tmp);
943 /* Get whether we are initiator or not */
944 ret = silc_config_get_token(line, &tmp);
948 config->routers->initiator = atoi(tmp);
949 if (config->routers->initiator != 0)
950 config->routers->initiator = TRUE;
954 /* Get backup replace IP */
955 ret = silc_config_get_token(line, &config->routers->backup_replace_ip);
957 config->routers->backup_router = TRUE;
959 if (config->routers->backup_router) {
960 /* Get backup replace port */
961 ret = silc_config_get_token(line, &tmp);
963 config->routers->backup_replace_port = atoi(tmp);
967 /* Check whether the backup connection is local */
968 ret = silc_config_get_token(line, &tmp);
970 config->routers->backup_local = atoi(tmp);
971 if (config->routers->backup_local != 0)
972 config->routers->backup_local = TRUE;
978 checkmask |= (1L << pc->section->type);
981 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
983 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
986 ret = silc_config_get_token(line, &config->admins->host);
991 config->admins->host = strdup("*");
994 ret = silc_config_get_token(line, &config->admins->username);
999 config->admins->username = strdup("*");
1002 ret = silc_config_get_token(line, &config->admins->nickname);
1007 config->admins->nickname = strdup("*");
1009 /* Get authentication method */
1010 ret = silc_config_get_token(line, &tmp);
1014 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
1015 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
1016 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
1017 config->filename, pc->linenum, tmp);
1021 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
1022 config->admins->auth_meth = SILC_AUTH_PASSWORD;
1024 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
1025 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
1030 /* Get authentication data */
1031 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
1035 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
1036 config->admins->auth_data_len = strlen(config->admins->auth_data);
1037 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
1038 /* Get the public key */
1039 SilcPublicKey public_key;
1041 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1042 &public_key, SILC_PKCS_FILE_PEM))
1043 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1044 &public_key, SILC_PKCS_FILE_BIN)) {
1045 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
1046 config->filename, pc->linenum,
1047 (char *)config->admins->auth_data);
1051 silc_free(config->admins->auth_data);
1052 config->admins->auth_data = (void *)public_key;
1053 config->admins->auth_data_len = 0;
1057 checkmask |= (1L << pc->section->type);
1060 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
1062 SILC_SERVER_CONFIG_LIST_ALLOC(config->denied);
1065 ret = silc_config_get_token(line, &config->denied->host);
1070 config->denied->host = strdup("*");
1071 fprintf(stderr, "warning: %s:%d: Denying all connections",
1072 config->filename, pc->linenum);
1076 ret = silc_config_get_token(line, &tmp);
1081 config->denied->port = 0;
1083 config->denied->port = atoi(tmp);
1088 ret = silc_config_get_token(line, &config->denied->comment);
1093 checkmask |= (1L << pc->section->type);
1096 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1099 config->motd = silc_calloc(1, sizeof(*config->motd));
1102 ret = silc_config_get_token(line, &config->motd->motd_file);
1107 checkmask |= (1L << pc->section->type);
1110 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1116 /* Check for error */
1117 if (check == FALSE) {
1118 /* Line could not be parsed */
1119 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1129 /* Check that all mandatory sections really were found. If not, the server
1130 cannot function and we return error. */
1131 ret = silc_server_config_check_sections(checkmask);
1137 /* Before returning all the lists in the config object must be set
1138 to their first values (the last value is first here). */
1139 while (config->cipher && config->cipher->prev)
1140 config->cipher = config->cipher->prev;
1141 while (config->pkcs && config->pkcs->prev)
1142 config->pkcs = config->pkcs->prev;
1143 while (config->hash_func && config->hash_func->prev)
1144 config->hash_func = config->hash_func->prev;
1145 while (config->hmac && config->hmac->prev)
1146 config->hmac = config->hmac->prev;
1147 while (config->listen_port && config->listen_port->prev)
1148 config->listen_port = config->listen_port->prev;
1149 while (config->logging && config->logging->prev)
1150 config->logging = config->logging->prev;
1151 while (config->conn_class && config->conn_class->prev)
1152 config->conn_class = config->conn_class->prev;
1153 while (config->clients && config->clients->prev)
1154 config->clients = config->clients->prev;
1155 while (config->servers && config->servers->prev)
1156 config->servers = config->servers->prev;
1157 while (config->admins && config->admins->prev)
1158 config->admins = config->admins->prev;
1159 while (config->routers && config->routers->prev)
1160 config->routers = config->routers->prev;
1162 SILC_LOG_DEBUG(("Done"));
1167 /* This function checks that the mask sent as argument includes all the
1168 sections that are mandatory in SILC server. */
1170 int silc_server_config_check_sections(uint32 checkmask)
1172 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1176 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1180 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1185 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1190 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1195 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1203 /* Sets log files where log messages is saved by the server. */
1205 void silc_server_config_setlogfiles(SilcServerConfig config)
1207 SilcServerConfigSectionLogging *log;
1208 char *info, *warning, *error, *fatal;
1209 uint32 info_size, warning_size, error_size, fatal_size;
1211 SILC_LOG_DEBUG(("Setting configured log file names"));
1213 /* Set default files before checking configuration */
1214 info = SILC_LOG_FILE_INFO;
1215 warning = SILC_LOG_FILE_WARNING;
1216 error = SILC_LOG_FILE_ERROR;
1217 fatal = SILC_LOG_FILE_FATAL;
1223 log = config->logging;
1225 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1226 info = log->filename;
1227 info_size = log->maxsize;
1229 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1230 warning = log->filename;
1231 warning_size = log->maxsize;
1233 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1234 error = log->filename;
1235 error_size = log->maxsize;
1237 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1238 fatal = log->filename;
1239 fatal_size = log->maxsize;
1245 silc_log_set_files(info, info_size, warning, warning_size,
1246 error, error_size, fatal, fatal_size);
1249 /* Registers configured ciphers. These can then be allocated by the
1250 server when needed. */
1252 bool silc_server_config_register_ciphers(SilcServerConfig config)
1254 SilcServerConfigSectionAlg *alg;
1255 SilcServer server = (SilcServer)config->server;
1257 SILC_LOG_DEBUG(("Registering configured ciphers"));
1259 if (!config->cipher)
1262 alg = config->cipher;
1265 if (!alg->sim_name) {
1268 for (i = 0; silc_default_ciphers[i].name; i++)
1269 if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
1270 silc_cipher_register(&silc_default_ciphers[i]);
1274 if (!silc_cipher_is_supported(alg->alg_name)) {
1275 SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
1276 silc_server_stop(server);
1281 /* Load (try at least) the crypto SIM module */
1282 SilcCipherObject cipher;
1283 SilcSimContext *sim;
1286 memset(&cipher, 0, sizeof(cipher));
1287 cipher.name = alg->alg_name;
1288 cipher.block_len = alg->block_len;
1289 cipher.key_len = alg->key_len * 8;
1291 sim = silc_sim_alloc();
1292 sim->type = SILC_SIM_CIPHER;
1293 sim->libname = alg->sim_name;
1295 alg_name = strdup(alg->alg_name);
1296 if (strchr(alg_name, '-'))
1297 *strchr(alg_name, '-') = '\0';
1299 if ((silc_sim_load(sim))) {
1301 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1302 SILC_CIPHER_SIM_SET_KEY));
1303 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1304 cipher.set_key_with_string =
1305 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1306 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1307 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1309 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1310 SILC_CIPHER_SIM_ENCRYPT_CBC));
1311 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1313 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1314 SILC_CIPHER_SIM_DECRYPT_CBC));
1315 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1316 cipher.context_len =
1317 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1318 SILC_CIPHER_SIM_CONTEXT_LEN));
1319 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1321 /* Put the SIM to the list of all SIM's in server */
1322 silc_dlist_add(server->sim, sim);
1324 silc_free(alg_name);
1326 SILC_LOG_ERROR(("Error configuring ciphers"));
1327 silc_server_stop(server);
1331 /* Register the cipher */
1332 silc_cipher_register(&cipher);
1342 /* Registers configured PKCS's. */
1344 bool silc_server_config_register_pkcs(SilcServerConfig config)
1346 SilcServerConfigSectionAlg *alg = config->pkcs;
1347 SilcServer server = (SilcServer)config->server;
1349 SILC_LOG_DEBUG(("Registering configured PKCS"));
1357 for (i = 0; silc_default_pkcs[i].name; i++)
1358 if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
1359 silc_pkcs_register(&silc_default_pkcs[i]);
1363 if (!silc_pkcs_is_supported(alg->alg_name)) {
1364 SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
1365 silc_server_stop(server);
1375 /* Registers configured hash functions. These can then be allocated by the
1376 server when needed. */
1378 bool silc_server_config_register_hashfuncs(SilcServerConfig config)
1380 SilcServerConfigSectionAlg *alg;
1381 SilcServer server = (SilcServer)config->server;
1383 SILC_LOG_DEBUG(("Registering configured hash functions"));
1385 if (!config->hash_func)
1388 alg = config->hash_func;
1391 if (!alg->sim_name) {
1394 for (i = 0; silc_default_hash[i].name; i++)
1395 if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
1396 silc_hash_register(&silc_default_hash[i]);
1400 if (!silc_hash_is_supported(alg->alg_name)) {
1401 SILC_LOG_ERROR(("Unknown hash funtion `%s'", alg->alg_name));
1402 silc_server_stop(server);
1408 /* Load (try at least) the hash SIM module */
1409 SilcHashObject hash;
1410 SilcSimContext *sim;
1412 memset(&hash, 0, sizeof(hash));
1413 hash.name = alg->alg_name;
1414 hash.block_len = alg->block_len;
1415 hash.hash_len = alg->key_len;
1417 sim = silc_sim_alloc();
1418 sim->type = SILC_SIM_HASH;
1419 sim->libname = alg->sim_name;
1421 if ((silc_sim_load(sim))) {
1423 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1424 SILC_HASH_SIM_INIT));
1425 SILC_LOG_DEBUG(("init=%p", hash.init));
1427 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1428 SILC_HASH_SIM_UPDATE));
1429 SILC_LOG_DEBUG(("update=%p", hash.update));
1431 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1432 SILC_HASH_SIM_FINAL));
1433 SILC_LOG_DEBUG(("final=%p", hash.final));
1435 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1436 SILC_HASH_SIM_CONTEXT_LEN));
1437 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1439 /* Put the SIM to the table of all SIM's in server */
1440 silc_dlist_add(server->sim, sim);
1442 SILC_LOG_ERROR(("Error configuring hash functions"));
1443 silc_server_stop(server);
1447 /* Register the hash function */
1448 silc_hash_register(&hash);
1458 /* Registers configure HMACs. These can then be allocated by the server
1461 bool silc_server_config_register_hmacs(SilcServerConfig config)
1463 SilcServerConfigSectionAlg *alg;
1464 SilcServer server = (SilcServer)config->server;
1466 SILC_LOG_DEBUG(("Registering configured HMACs"));
1473 SilcHmacObject hmac;
1475 if (!silc_hash_is_supported(alg->sim_name)) {
1476 SILC_LOG_ERROR(("Unknown hash function `%s'", alg->sim_name));
1477 silc_server_stop(server);
1481 /* Register the HMAC */
1482 memset(&hmac, 0, sizeof(hmac));
1483 hmac.name = alg->alg_name;
1484 hmac.len = alg->key_len;
1485 silc_hmac_register(&hmac);
1493 /* Returns client authentication information from server configuration
1494 by host (name or ip). If `port' is non-null then both name or IP and
1495 the port must match. */
1497 SilcServerConfigSectionClientConnection *
1498 silc_server_config_find_client_conn(SilcServerConfig config,
1499 char *host, int port)
1502 SilcServerConfigSectionClientConnection *client = NULL;
1508 if (!config->clients)
1511 client = config->clients;
1513 for (i = 0; client; i++) {
1514 if (silc_string_compare(client->host, host))
1517 if (port && client->port && client->port != port)
1523 client = client->next;
1532 /* Returns server connection info from server configuartion by host
1533 (name or ip). If `port' is non-null then both name or IP and the port
1536 SilcServerConfigSectionServerConnection *
1537 silc_server_config_find_server_conn(SilcServerConfig config,
1538 char *host, int port)
1541 SilcServerConfigSectionServerConnection *serv = NULL;
1547 if (!config->servers)
1550 serv = config->servers;
1551 for (i = 0; serv; i++) {
1552 if (silc_string_compare(serv->host, host))
1555 if (port && serv->port && serv->port != port)
1570 /* Returns router connection info from server configuartion by
1571 host (name or ip). */
1573 SilcServerConfigSectionServerConnection *
1574 silc_server_config_find_router_conn(SilcServerConfig config,
1575 char *host, int port)
1578 SilcServerConfigSectionServerConnection *serv = NULL;
1584 if (!config->routers)
1587 serv = config->routers;
1588 for (i = 0; serv; i++) {
1589 if (silc_string_compare(serv->host, host))
1592 if (port && serv->port && serv->port != port)
1607 /* Returns TRUE if configuartion for a router connection that we are
1608 initiating exists. */
1610 bool silc_server_config_is_primary_route(SilcServerConfig config)
1613 SilcServerConfigSectionServerConnection *serv = NULL;
1616 serv = config->routers;
1617 for (i = 0; serv; i++) {
1618 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1629 /* Returns our primary connection configuration or NULL if we do not
1630 have primary router configured. */
1632 SilcServerConfigSectionServerConnection *
1633 silc_server_config_get_primary_router(SilcServerConfig config)
1636 SilcServerConfigSectionServerConnection *serv = NULL;
1638 serv = config->routers;
1639 for (i = 0; serv; i++) {
1640 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1648 /* Returns Admin connection configuration by host, username and/or
1651 SilcServerConfigSectionAdminConnection *
1652 silc_server_config_find_admin(SilcServerConfig config,
1653 char *host, char *username, char *nickname)
1655 SilcServerConfigSectionAdminConnection *admin = NULL;
1658 if (!config->admins)
1668 admin = config->admins;
1669 for (i = 0; admin; i++) {
1670 if (silc_string_compare(admin->host, host) &&
1671 silc_string_compare(admin->username, username) &&
1672 silc_string_compare(admin->nickname, nickname))
1675 admin = admin->next;
1684 /* Returns the Denied connection configuration by host and port. */
1686 SilcServerConfigSectionDenyConnection *
1687 silc_server_config_denied_conn(SilcServerConfig config, char *host,
1691 SilcServerConfigSectionDenyConnection *deny = NULL;
1697 if (!config->denied)
1700 deny = config->denied;
1701 for (i = 0; deny; i++) {
1702 if (silc_string_compare(deny->host, host))
1705 if (port && deny->port && deny->port != port)