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, 2 },
31 SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 },
33 SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 },
35 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 },
37 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 },
39 SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 },
41 SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY, 2 },
43 SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 },
44 { "[ConnectionClass]",
45 SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 },
46 { "[ClientConnection]",
47 SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION, 5 },
48 { "[ServerConnection]",
49 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION, 6 },
50 { "[RouterConnection]",
51 SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION, 7 },
52 { "[AdminConnection]",
53 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 },
55 SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 4 },
57 SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
59 { NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
62 /* Allocates a new configuration object, opens configuration file and
63 parses the file. The parsed data is returned to the newly allocated
64 configuration object. */
66 SilcServerConfig silc_server_config_alloc(char *filename)
70 SilcServerConfigParse config_parse;
72 SILC_LOG_DEBUG(("Allocating new configuration object"));
74 new = silc_calloc(1, sizeof(*new));
76 fprintf(stderr, "Could not allocate new configuration object");
80 new->filename = filename;
82 /* Open configuration file and parse it */
85 silc_config_open(filename, &buffer);
88 if ((silc_server_config_parse(new, buffer, &config_parse)) == FALSE)
90 if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
102 /* Free's a configuration object. */
104 void silc_server_config_free(SilcServerConfig config)
107 silc_free(config->filename);
108 silc_free(config->server_info);
109 silc_free(config->admin_info);
110 silc_free(config->listen_port);
111 silc_free(config->identity);
112 silc_free(config->conn_class);
113 silc_free(config->clients);
114 silc_free(config->admins);
115 silc_free(config->servers);
116 silc_free(config->routers);
117 silc_free(config->denied);
118 silc_free(config->motd);
123 /* Parses the the buffer and returns the parsed lines into return_config
124 argument. The return_config argument doesn't have to be initialized
125 before calling this. It will be initialized during the parsing. The
126 buffer sent as argument can be safely free'd after this function has
127 succesfully returned. */
129 int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
130 SilcServerConfigParse *return_config)
132 int i, begin, linenum;
133 char line[1024], *cp;
134 SilcServerConfigSection *cptr = NULL;
135 SilcServerConfigParse parse = *return_config, first = NULL;
137 SILC_LOG_DEBUG(("Parsing configuration file"));
141 while((begin = silc_gets(line, sizeof(line),
142 buffer->data, buffer->len, begin)) != EOF) {
146 /* Check for bad line */
147 if (silc_check_line(cp))
150 /* Remove tabs and whitespaces from the line */
151 if (strchr(cp, '\t')) {
153 while(strchr(cp + i, '\t')) {
154 *strchr(cp + i, '\t') = ' ';
158 for (i = 0; i < strlen(cp); i++) {
174 /* Remove new line sign */
175 if (strchr(cp, '\n'))
176 *strchr(cp, '\n') = '\0';
178 /* Check for matching sections */
179 for (cptr = silc_server_config_sections; cptr->section; cptr++)
180 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
183 if (!cptr->section) {
184 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
185 config->filename, linenum, cp);
192 * Start of a configuration line
195 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
197 if (strchr(cp, '\n'))
198 *strchr(cp, '\n') = ':';
201 parse = silc_calloc(1, sizeof(*parse));
203 parse->section = NULL;
207 if (parse->next == NULL) {
208 parse->next = silc_calloc(1, sizeof(*parse->next));
209 parse->next->line = NULL;
210 parse->next->section = NULL;
211 parse->next->next = NULL;
212 parse->next->prev = parse;
220 /* Add the line to parsing structure for further parsing. */
222 parse->section = cptr;
223 parse->line = silc_buffer_alloc(strlen(cp) + 1);
224 parse->linenum = linenum;
225 silc_buffer_pull_tail(parse->line, strlen(cp));
226 silc_buffer_put(parse->line, cp, strlen(cp));
233 /* Set the return_config argument to its first value so that further
234 parsing can be started from the first line. */
235 *return_config = first;
240 /* Parses the lines earlier read from configuration file. The config object
241 must not be initialized, it will be initialized in this function. The
242 parse_config argument is uninitialized automatically during this
245 int silc_server_config_parse_lines(SilcServerConfig config,
246 SilcServerConfigParse parse_config)
248 int ret, check = FALSE;
251 SilcServerConfigParse pc = parse_config;
254 SILC_LOG_DEBUG(("Parsing configuration lines"));
264 /* Get number of tokens in line */
265 ret = silc_config_check_num_token(line);
266 if (ret != pc->section->maxfields) {
268 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
269 config->filename, pc->linenum, ret,
270 pc->section->maxfields);
275 switch(pc->section->type) {
276 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
278 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
280 /* Get cipher name */
281 ret = silc_config_get_token(line, &config->cipher->alg_name);
285 fprintf(stderr, "%s:%d: Cipher name not defined\n",
286 config->filename, pc->linenum);
290 /* Get module name */
291 config->cipher->sim_name = NULL;
292 ret = silc_config_get_token(line, &config->cipher->sim_name);
297 ret = silc_config_get_token(line, &tmp);
301 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
302 config->filename, pc->linenum);
305 config->cipher->key_len = atoi(tmp);
308 /* Get block length */
309 ret = silc_config_get_token(line, &tmp);
313 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
314 config->filename, pc->linenum);
317 config->cipher->block_len = atoi(tmp);
321 checkmask |= (1L << pc->section->type);
324 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
326 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
329 ret = silc_config_get_token(line, &config->pkcs->alg_name);
333 fprintf(stderr, "%s:%d: PKCS name not defined\n",
334 config->filename, pc->linenum);
339 ret = silc_config_get_token(line, &tmp);
343 fprintf(stderr, "%s:%d: PKCS key length not defined\n",
344 config->filename, pc->linenum);
347 config->pkcs->key_len = atoi(tmp);
351 checkmask |= (1L << pc->section->type);
354 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
356 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
358 /* Get Hash function name */
359 ret = silc_config_get_token(line, &config->hash_func->alg_name);
363 fprintf(stderr, "%s:%d: Hash function name not defined\n",
364 config->filename, pc->linenum);
368 /* Get Hash function module name */
369 config->hash_func->sim_name = NULL;
370 ret = silc_config_get_token(line, &config->hash_func->sim_name);
374 /* Get block length */
375 ret = silc_config_get_token(line, &tmp);
379 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
380 config->filename, pc->linenum);
383 config->hash_func->block_len = atoi(tmp);
386 /* Get hash length */
387 ret = silc_config_get_token(line, &tmp);
391 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
392 config->filename, pc->linenum);
395 config->hash_func->key_len = atoi(tmp);
399 checkmask |= (1L << pc->section->type);
402 case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
404 SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
407 ret = silc_config_get_token(line, &config->hmac->alg_name);
411 fprintf(stderr, "%s:%d: HMAC name not defined\n",
412 config->filename, pc->linenum);
417 ret = silc_config_get_token(line, &config->hmac->sim_name);
421 fprintf(stderr, "%s:%d: Hash function name not defined\n",
422 config->filename, pc->linenum);
427 ret = silc_config_get_token(line, &tmp);
431 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
432 config->filename, pc->linenum);
435 config->hmac->key_len = atoi(tmp);
439 checkmask |= (1L << pc->section->type);
442 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
444 if (!config->server_info)
445 config->server_info = silc_calloc(1, sizeof(*config->server_info));
447 /* Get server name */
448 ret = silc_config_get_token(line, &config->server_info->server_name);
452 /* Server name not defined */
457 ret = silc_config_get_token(line, &config->server_info->server_ip);
461 /* Server IP not defined */
465 /* Get server location */
466 ret = silc_config_get_token(line, &config->server_info->location);
470 /* Get server port */
471 /* XXX: Need port here??? */
472 ret = silc_config_get_token(line, &tmp);
476 /* Port not defined */
479 config->server_info->port = atoi(tmp);
483 checkmask |= (1L << pc->section->type);
486 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
488 if (!config->admin_info)
489 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
492 ret = silc_config_get_token(line, &config->admin_info->location);
496 /* Get server type */
497 ret = silc_config_get_token(line, &config->admin_info->server_type);
501 /* Get admins name */
502 ret = silc_config_get_token(line, &config->admin_info->admin_name);
506 /* Get admins email address */
507 ret = silc_config_get_token(line, &config->admin_info->admin_email);
512 checkmask |= (1L << pc->section->type);
515 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
517 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
520 ret = silc_config_get_token(line, &config->listen_port->host);
525 ret = silc_config_get_token(line, &config->listen_port->remote_ip);
530 ret = silc_config_get_token(line, &tmp);
535 config->listen_port->port = 0;
537 config->listen_port->port = atoi(tmp);
542 checkmask |= (1L << pc->section->type);
545 case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
547 if (!config->identity)
548 config->identity = silc_calloc(1, sizeof(*config->identity));
551 ret = silc_config_get_token(line, &config->identity->user);
555 ret = silc_config_get_token(line, &config->identity->group);
560 checkmask |= (1L << pc->section->type);
562 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
564 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
566 /* Get class number */
567 ret = silc_config_get_token(line, &tmp);
571 /* Class number not defined */
574 config->conn_class->class = atoi(tmp);
577 /* Get ping frequency */
578 ret = silc_config_get_token(line, &tmp);
581 config->conn_class->ping_freq = atoi(tmp);
584 /* Get connect frequency */
585 ret = silc_config_get_token(line, &tmp);
588 config->conn_class->connect_freq = atoi(tmp);
592 ret = silc_config_get_token(line, &tmp);
595 config->conn_class->max_links = atoi(tmp);
599 checkmask |= (1L << pc->section->type);
602 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
604 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
606 /* Get log section type and check it */
607 ret = silc_config_get_token(line, &config->logging->logtype);
611 fprintf(stderr, "%s:%d: Log file section not defined\n",
612 config->filename, pc->linenum);
615 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
616 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
617 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
618 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
619 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
620 config->filename, pc->linenum, config->logging->logtype);
624 /* Get log filename */
625 ret = silc_config_get_token(line, &config->logging->filename);
629 fprintf(stderr, "%s:%d: Log file name not defined\n",
630 config->filename, pc->linenum);
634 /* Get max byte size */
635 ret = silc_config_get_token(line, &tmp);
639 config->logging->maxsize = atoi(tmp);
644 checkmask |= (1L << pc->section->type);
647 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
649 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
652 ret = silc_config_get_token(line, &config->clients->host);
657 config->clients->host = strdup("*");
659 /* Get authentication method */
660 ret = silc_config_get_token(line, &tmp);
664 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
665 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
666 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
667 config->filename, pc->linenum, tmp);
671 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
672 config->clients->auth_meth = SILC_AUTH_PASSWORD;
674 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
675 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
680 /* Get authentication data */
681 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
685 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
686 config->clients->auth_data_len = strlen(config->clients->auth_data);
687 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
688 /* Get the public key */
689 SilcPublicKey public_key;
691 if (!silc_pkcs_load_public_key(config->clients->auth_data,
692 &public_key, SILC_PKCS_FILE_PEM))
693 if (!silc_pkcs_load_public_key(config->clients->auth_data,
694 &public_key, SILC_PKCS_FILE_BIN)) {
695 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
696 config->filename, pc->linenum,
697 (char *)config->clients->auth_data);
701 silc_free(config->clients->auth_data);
702 config->clients->auth_data = (void *)public_key;
703 config->clients->auth_data_len = 0;
707 ret = silc_config_get_token(line, &tmp);
711 config->clients->port = atoi(tmp);
715 /* Get class number */
716 ret = silc_config_get_token(line, &tmp);
720 config->clients->class = atoi(tmp);
725 checkmask |= (1L << pc->section->type);
728 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
730 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
733 ret = silc_config_get_token(line, &config->servers->host);
738 config->servers->host = strdup("*");
740 /* Get authentication method */
741 ret = silc_config_get_token(line, &tmp);
745 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
746 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
747 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
748 config->filename, pc->linenum, tmp);
752 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
753 config->servers->auth_meth = SILC_AUTH_PASSWORD;
755 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
756 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
761 /* Get authentication data */
762 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
766 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
767 config->servers->auth_data_len = strlen(config->servers->auth_data);
768 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
769 /* Get the public key */
770 SilcPublicKey public_key;
772 if (!silc_pkcs_load_public_key(config->servers->auth_data,
773 &public_key, SILC_PKCS_FILE_PEM))
774 if (!silc_pkcs_load_public_key(config->servers->auth_data,
775 &public_key, SILC_PKCS_FILE_BIN)) {
776 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
777 config->filename, pc->linenum,
778 (char *)config->servers->auth_data);
782 silc_free(config->servers->auth_data);
783 config->servers->auth_data = (void *)public_key;
784 config->servers->auth_data_len = 0;
788 ret = silc_config_get_token(line, &tmp);
792 config->servers->port = atoi(tmp);
797 ret = silc_config_get_token(line, &config->servers->version);
801 /* Get class number */
802 ret = silc_config_get_token(line, &tmp);
806 config->servers->class = atoi(tmp);
811 checkmask |= (1L << pc->section->type);
814 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
816 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
819 ret = silc_config_get_token(line, &config->routers->host);
824 // config->routers->host = strdup("*");
826 /* Get authentication method */
827 ret = silc_config_get_token(line, &tmp);
831 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
832 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
833 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
834 config->filename, pc->linenum, tmp);
838 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
839 config->routers->auth_meth = SILC_AUTH_PASSWORD;
841 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
842 config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
847 /* Get authentication data */
848 ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
852 if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
853 config->routers->auth_data_len = strlen(config->routers->auth_data);
854 } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
855 /* Get the public key */
856 SilcPublicKey public_key;
858 if (!silc_pkcs_load_public_key(config->routers->auth_data,
859 &public_key, SILC_PKCS_FILE_PEM))
860 if (!silc_pkcs_load_public_key(config->routers->auth_data,
861 &public_key, SILC_PKCS_FILE_BIN)) {
862 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
863 config->filename, pc->linenum,
864 (char *)config->routers->auth_data);
868 silc_free(config->routers->auth_data);
869 config->routers->auth_data = (void *)public_key;
870 config->routers->auth_data_len = 0;
874 ret = silc_config_get_token(line, &tmp);
878 config->routers->port = atoi(tmp);
883 ret = silc_config_get_token(line, &config->routers->version);
887 /* Get class number */
888 ret = silc_config_get_token(line, &tmp);
892 config->routers->class = atoi(tmp);
896 /* Get whether we are initiator or not */
897 ret = silc_config_get_token(line, &tmp);
901 config->routers->initiator = atoi(tmp);
902 if (config->routers->initiator != 0)
903 config->routers->initiator = TRUE;
908 checkmask |= (1L << pc->section->type);
911 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
913 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
916 ret = silc_config_get_token(line, &config->admins->host);
921 config->admins->host = strdup("*");
924 ret = silc_config_get_token(line, &config->admins->username);
929 config->admins->username = strdup("*");
932 ret = silc_config_get_token(line, &config->admins->nickname);
937 config->admins->nickname = strdup("*");
939 /* Get authentication method */
940 ret = silc_config_get_token(line, &tmp);
944 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
945 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
946 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
947 config->filename, pc->linenum, tmp);
951 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
952 config->admins->auth_meth = SILC_AUTH_PASSWORD;
954 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
955 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
960 /* Get authentication data */
961 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
965 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
966 config->admins->auth_data_len = strlen(config->admins->auth_data);
967 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
968 /* Get the public key */
969 SilcPublicKey public_key;
971 if (!silc_pkcs_load_public_key(config->admins->auth_data,
972 &public_key, SILC_PKCS_FILE_PEM))
973 if (!silc_pkcs_load_public_key(config->admins->auth_data,
974 &public_key, SILC_PKCS_FILE_BIN)) {
975 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
976 config->filename, pc->linenum,
977 (char *)config->admins->auth_data);
981 silc_free(config->admins->auth_data);
982 config->admins->auth_data = (void *)public_key;
983 config->admins->auth_data_len = 0;
987 checkmask |= (1L << pc->section->type);
990 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
991 /* Not implemented yet */
995 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
998 config->motd = silc_calloc(1, sizeof(*config->motd));
1001 ret = silc_config_get_token(line, &config->motd->motd_file);
1006 checkmask |= (1L << pc->section->type);
1009 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1015 /* Check for error */
1016 if (check == FALSE) {
1017 /* Line could not be parsed */
1018 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1028 /* Check that all mandatory sections really were found. If not, the server
1029 cannot function and we return error. */
1030 ret = silc_server_config_check_sections(checkmask);
1036 /* Before returning all the lists in the config object must be set
1037 to their first values (the last value is first here). */
1038 while (config->cipher && config->cipher->prev)
1039 config->cipher = config->cipher->prev;
1040 while (config->pkcs && config->pkcs->prev)
1041 config->pkcs = config->pkcs->prev;
1042 while (config->hash_func && config->hash_func->prev)
1043 config->hash_func = config->hash_func->prev;
1044 while (config->hmac && config->hmac->prev)
1045 config->hmac = config->hmac->prev;
1046 while (config->listen_port && config->listen_port->prev)
1047 config->listen_port = config->listen_port->prev;
1048 while (config->logging && config->logging->prev)
1049 config->logging = config->logging->prev;
1050 while (config->conn_class && config->conn_class->prev)
1051 config->conn_class = config->conn_class->prev;
1052 while (config->clients && config->clients->prev)
1053 config->clients = config->clients->prev;
1054 while (config->servers && config->servers->prev)
1055 config->servers = config->servers->prev;
1056 while (config->routers && config->routers->prev)
1057 config->routers = config->routers->prev;
1059 SILC_LOG_DEBUG(("Done"));
1064 /* This function checks that the mask sent as argument includes all the
1065 sections that are mandatory in SILC server. */
1067 int silc_server_config_check_sections(uint32 checkmask)
1069 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1073 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1077 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1082 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1087 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1092 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1100 /* Sets log files where log messages is saved by the server. */
1102 void silc_server_config_setlogfiles(SilcServerConfig config)
1104 SilcServerConfigSectionLogging *log;
1105 char *info, *warning, *error, *fatal;
1106 uint32 info_size, warning_size, error_size, fatal_size;
1108 SILC_LOG_DEBUG(("Setting configured log file names"));
1110 /* Set default files before checking configuration */
1111 info = SILC_LOG_FILE_INFO;
1112 warning = SILC_LOG_FILE_WARNING;
1113 error = SILC_LOG_FILE_ERROR;
1114 fatal = SILC_LOG_FILE_FATAL;
1120 log = config->logging;
1122 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1123 info = log->filename;
1124 info_size = log->maxsize;
1126 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1127 warning = log->filename;
1128 warning_size = log->maxsize;
1130 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1131 error = log->filename;
1132 error_size = log->maxsize;
1134 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1135 fatal = log->filename;
1136 fatal_size = log->maxsize;
1142 silc_log_set_files(info, info_size, warning, warning_size,
1143 error, error_size, fatal, fatal_size);
1146 /* Registers configured ciphers. These can then be allocated by the
1147 server when needed. */
1149 void silc_server_config_register_ciphers(SilcServerConfig config)
1151 SilcServerConfigSectionAlg *alg;
1152 SilcServer server = (SilcServer)config->server;
1154 SILC_LOG_DEBUG(("Registering configured ciphers"));
1156 alg = config->cipher;
1159 if (!alg->sim_name) {
1160 /* Crypto module is supposed to be built in. Nothing to be done
1161 here except to test that the cipher really is built in. */
1162 SilcCipher tmp = NULL;
1164 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1165 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1166 silc_server_stop(server);
1169 silc_cipher_free(tmp);
1173 /* Load (try at least) the crypto SIM module */
1174 SilcCipherObject cipher;
1175 SilcSimContext *sim;
1178 memset(&cipher, 0, sizeof(cipher));
1179 cipher.name = alg->alg_name;
1180 cipher.block_len = alg->block_len;
1181 cipher.key_len = alg->key_len * 8;
1183 sim = silc_sim_alloc();
1184 sim->type = SILC_SIM_CIPHER;
1185 sim->libname = alg->sim_name;
1187 alg_name = strdup(alg->alg_name);
1188 if (strchr(alg_name, '-'))
1189 *strchr(alg_name, '-') = '\0';
1191 if ((silc_sim_load(sim))) {
1193 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1194 SILC_CIPHER_SIM_SET_KEY));
1195 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1196 cipher.set_key_with_string =
1197 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1198 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1199 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1201 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1202 SILC_CIPHER_SIM_ENCRYPT_CBC));
1203 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1205 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1206 SILC_CIPHER_SIM_DECRYPT_CBC));
1207 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1208 cipher.context_len =
1209 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1210 SILC_CIPHER_SIM_CONTEXT_LEN));
1211 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1213 /* Put the SIM to the list of all SIM's in server */
1214 silc_dlist_add(server->sim, sim);
1216 silc_free(alg_name);
1218 SILC_LOG_ERROR(("Error configuring ciphers"));
1219 silc_server_stop(server);
1223 /* Register the cipher */
1224 silc_cipher_register(&cipher);
1232 /* Registers configured PKCS's. */
1233 /* XXX: This really doesn't do anything now since we have statically
1234 registered our PKCS's. This should be implemented when PKCS works
1235 as SIM's. This checks now only that the PKCS user requested is
1236 really out there. */
1238 void silc_server_config_register_pkcs(SilcServerConfig config)
1240 SilcServerConfigSectionAlg *alg = config->pkcs;
1241 SilcServer server = (SilcServer)config->server;
1242 SilcPKCS tmp = NULL;
1244 SILC_LOG_DEBUG(("Registering configured PKCS"));
1248 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1249 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1250 silc_server_stop(server);
1259 /* Registers configured hash functions. These can then be allocated by the
1260 server when needed. */
1262 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1264 SilcServerConfigSectionAlg *alg;
1265 SilcServer server = (SilcServer)config->server;
1267 SILC_LOG_DEBUG(("Registering configured hash functions"));
1269 alg = config->hash_func;
1272 if (!alg->sim_name) {
1273 /* Hash module is supposed to be built in. Nothing to be done
1274 here except to test that the hash function really is built in. */
1275 SilcHash tmp = NULL;
1277 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1278 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1279 silc_server_stop(server);
1282 silc_hash_free(tmp);
1286 /* Load (try at least) the hash SIM module */
1287 SilcHashObject hash;
1288 SilcSimContext *sim;
1290 memset(&hash, 0, sizeof(hash));
1291 hash.name = alg->alg_name;
1292 hash.block_len = alg->block_len;
1293 hash.hash_len = alg->key_len;
1295 sim = silc_sim_alloc();
1296 sim->type = SILC_SIM_HASH;
1297 sim->libname = alg->sim_name;
1299 if ((silc_sim_load(sim))) {
1301 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1302 SILC_HASH_SIM_INIT));
1303 SILC_LOG_DEBUG(("init=%p", hash.init));
1305 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1306 SILC_HASH_SIM_UPDATE));
1307 SILC_LOG_DEBUG(("update=%p", hash.update));
1309 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1310 SILC_HASH_SIM_FINAL));
1311 SILC_LOG_DEBUG(("final=%p", hash.final));
1313 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1314 SILC_HASH_SIM_CONTEXT_LEN));
1315 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1317 /* Put the SIM to the table of all SIM's in server */
1318 silc_dlist_add(server->sim, sim);
1320 SILC_LOG_ERROR(("Error configuring hash functions"));
1321 silc_server_stop(server);
1325 /* Register the hash function */
1326 silc_hash_register(&hash);
1334 /* Registers configure HMACs. These can then be allocated by the server
1337 void silc_server_config_register_hmacs(SilcServerConfig config)
1339 SilcServerConfigSectionAlg *alg;
1340 SilcServer server = (SilcServer)config->server;
1342 SILC_LOG_DEBUG(("Registering configured HMACs"));
1344 if (!config->hmac) {
1345 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1347 silc_server_stop(server);
1353 SilcHmacObject hmac;
1355 if (!silc_hash_is_supported(alg->sim_name)) {
1356 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1357 silc_server_stop(server);
1361 /* Register the HMAC */
1362 memset(&hmac, 0, sizeof(hmac));
1363 hmac.name = alg->alg_name;
1364 hmac.len = alg->key_len;
1365 silc_hmac_register(&hmac);
1371 /* Returns client authentication information from server configuration
1372 by host (name or ip). */
1374 SilcServerConfigSectionClientConnection *
1375 silc_server_config_find_client_conn(SilcServerConfig config,
1376 char *host, int port)
1379 SilcServerConfigSectionClientConnection *client = NULL;
1384 if (!config->clients)
1387 client = config->clients;
1389 for (i = 0; client; i++) {
1390 if (silc_string_compare(client->host, host))
1392 client = client->next;
1401 /* Returns server connection info from server configuartion by host
1404 SilcServerConfigSectionServerConnection *
1405 silc_server_config_find_server_conn(SilcServerConfig config,
1406 char *host, int port)
1409 SilcServerConfigSectionServerConnection *serv = NULL;
1414 if (!config->servers)
1417 serv = config->servers;
1418 for (i = 0; serv; i++) {
1419 if (silc_string_compare(serv->host, host))
1430 /* Returns router connection info from server configuartion by
1431 host (name or ip). */
1433 SilcServerConfigSectionServerConnection *
1434 silc_server_config_find_router_conn(SilcServerConfig config,
1435 char *host, int port)
1438 SilcServerConfigSectionServerConnection *serv = NULL;
1443 if (!config->routers)
1446 serv = config->routers;
1447 for (i = 0; serv; i++) {
1448 if (silc_string_compare(serv->host, host))
1459 /* Returns Admin connection configuration by host, username and/or
1462 SilcServerConfigSectionAdminConnection *
1463 silc_server_config_find_admin(SilcServerConfig config,
1464 char *host, char *username, char *nickname)
1466 SilcServerConfigSectionAdminConnection *admin = NULL;
1469 if (!config->admins)
1479 admin = config->admins;
1480 for (i = 0; admin; i++) {
1481 if (silc_string_compare(admin->host, host) &&
1482 silc_string_compare(admin->username, username) &&
1483 silc_string_compare(admin->nickname, nickname))
1486 admin = admin->next;
1495 /* Prints out example configuration file with default built in
1496 configuration values. */
1498 void silc_server_config_print()
1504 # Automatically generated example SILCd configuration file with default\n\
1505 # built in values. Use this as a guide to configure your SILCd configuration\n\
1506 # file for your system. For detailed description of different configuration\n\
1507 # sections refer to silcd(8) manual page.\n\
1522 +lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333
1525 +Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
1528 +10.2.1.6:10.2.1.6:1333
1531 +infologfile:silcd.log:10000
1532 #+warninglogfile:/var/log/silcd_warning.log:10000
1533 #+errorlogfile:ERROR.log:10000
1534 #+fatallogfile:/var/log/silcd_error.log:
1541 +10.2.1.199:priikone:333:1
1544 +10.2.1.199:priikone:priikone:1
1553 fprintf(stdout, "%s\n", buf);