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)
133 unsigned int linenum;
134 char line[1024], *cp;
135 SilcServerConfigSection *cptr = NULL;
136 SilcServerConfigParse parse = *return_config, first = NULL;
138 SILC_LOG_DEBUG(("Parsing configuration file"));
142 while((begin = silc_gets(line, sizeof(line),
143 buffer->data, buffer->len, begin)) != EOF) {
147 /* Check for bad line */
148 if (silc_check_line(cp))
151 /* Remove tabs and whitespaces from the line */
152 if (strchr(cp, '\t')) {
154 while(strchr(cp + i, '\t')) {
155 *strchr(cp + i, '\t') = ' ';
159 for (i = 0; i < strlen(cp); i++) {
175 /* Remove new line sign */
176 if (strchr(cp, '\n'))
177 *strchr(cp, '\n') = '\0';
179 /* Check for matching sections */
180 for (cptr = silc_server_config_sections; cptr->section; cptr++)
181 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
184 if (!cptr->section) {
185 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
186 config->filename, linenum, cp);
193 * Start of a configuration line
196 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
198 if (strchr(cp, '\n'))
199 *strchr(cp, '\n') = ':';
202 parse = silc_calloc(1, sizeof(*parse));
204 parse->section = NULL;
208 if (parse->next == NULL) {
209 parse->next = silc_calloc(1, sizeof(*parse->next));
210 parse->next->line = NULL;
211 parse->next->section = NULL;
212 parse->next->next = NULL;
213 parse->next->prev = parse;
221 /* Add the line to parsing structure for further parsing. */
223 parse->section = cptr;
224 parse->line = silc_buffer_alloc(strlen(cp) + 1);
225 parse->linenum = linenum;
226 silc_buffer_pull_tail(parse->line, strlen(cp));
227 silc_buffer_put(parse->line, cp, strlen(cp));
234 /* Set the return_config argument to its first value so that further
235 parsing can be started from the first line. */
236 *return_config = first;
241 /* Parses the lines earlier read from configuration file. The config object
242 must not be initialized, it will be initialized in this function. The
243 parse_config argument is uninitialized automatically during this
246 int silc_server_config_parse_lines(SilcServerConfig config,
247 SilcServerConfigParse parse_config)
249 int ret, check = FALSE;
250 unsigned int checkmask;
252 SilcServerConfigParse pc = parse_config;
255 SILC_LOG_DEBUG(("Parsing configuration lines"));
265 /* Get number of tokens in line */
266 ret = silc_config_check_num_token(line);
267 if (ret != pc->section->maxfields) {
269 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
270 config->filename, pc->linenum, ret,
271 pc->section->maxfields);
276 switch(pc->section->type) {
277 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
279 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
281 /* Get cipher name */
282 ret = silc_config_get_token(line, &config->cipher->alg_name);
286 fprintf(stderr, "%s:%d: Cipher name not defined\n",
287 config->filename, pc->linenum);
291 /* Get module name */
292 config->cipher->sim_name = NULL;
293 ret = silc_config_get_token(line, &config->cipher->sim_name);
298 ret = silc_config_get_token(line, &tmp);
302 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
303 config->filename, pc->linenum);
306 config->cipher->key_len = atoi(tmp);
309 /* Get block length */
310 ret = silc_config_get_token(line, &tmp);
314 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
315 config->filename, pc->linenum);
318 config->cipher->block_len = atoi(tmp);
322 checkmask |= (1L << pc->section->type);
325 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
327 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
330 ret = silc_config_get_token(line, &config->pkcs->alg_name);
334 fprintf(stderr, "%s:%d: PKCS name not defined\n",
335 config->filename, pc->linenum);
340 ret = silc_config_get_token(line, &tmp);
344 fprintf(stderr, "%s:%d: PKCS key length not defined\n",
345 config->filename, pc->linenum);
348 config->pkcs->key_len = atoi(tmp);
352 checkmask |= (1L << pc->section->type);
355 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
357 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
359 /* Get Hash function name */
360 ret = silc_config_get_token(line, &config->hash_func->alg_name);
364 fprintf(stderr, "%s:%d: Hash function name not defined\n",
365 config->filename, pc->linenum);
369 /* Get Hash function module name */
370 config->hash_func->sim_name = NULL;
371 ret = silc_config_get_token(line, &config->hash_func->sim_name);
375 /* Get block length */
376 ret = silc_config_get_token(line, &tmp);
380 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
381 config->filename, pc->linenum);
384 config->hash_func->block_len = atoi(tmp);
387 /* Get hash length */
388 ret = silc_config_get_token(line, &tmp);
392 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
393 config->filename, pc->linenum);
396 config->hash_func->key_len = atoi(tmp);
400 checkmask |= (1L << pc->section->type);
403 case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
405 SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
408 ret = silc_config_get_token(line, &config->hmac->alg_name);
412 fprintf(stderr, "%s:%d: HMAC name not defined\n",
413 config->filename, pc->linenum);
418 ret = silc_config_get_token(line, &config->hmac->sim_name);
422 fprintf(stderr, "%s:%d: Hash function name not defined\n",
423 config->filename, pc->linenum);
428 ret = silc_config_get_token(line, &tmp);
432 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
433 config->filename, pc->linenum);
436 config->hmac->key_len = atoi(tmp);
440 checkmask |= (1L << pc->section->type);
443 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
445 if (!config->server_info)
446 config->server_info = silc_calloc(1, sizeof(*config->server_info));
448 /* Get server name */
449 ret = silc_config_get_token(line, &config->server_info->server_name);
453 /* Server name not defined */
458 ret = silc_config_get_token(line, &config->server_info->server_ip);
462 /* Server IP not defined */
466 /* Get server location */
467 ret = silc_config_get_token(line, &config->server_info->location);
471 /* Get server port */
472 /* XXX: Need port here??? */
473 ret = silc_config_get_token(line, &tmp);
477 /* Port not defined */
480 config->server_info->port = atoi(tmp);
484 checkmask |= (1L << pc->section->type);
487 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
489 if (!config->admin_info)
490 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
493 ret = silc_config_get_token(line, &config->admin_info->location);
497 /* Get server type */
498 ret = silc_config_get_token(line, &config->admin_info->server_type);
502 /* Get admins name */
503 ret = silc_config_get_token(line, &config->admin_info->admin_name);
507 /* Get admins email address */
508 ret = silc_config_get_token(line, &config->admin_info->admin_email);
513 checkmask |= (1L << pc->section->type);
516 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
518 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
521 ret = silc_config_get_token(line, &config->listen_port->host);
526 ret = silc_config_get_token(line, &config->listen_port->remote_ip);
531 ret = silc_config_get_token(line, &tmp);
536 config->listen_port->port = 0;
538 config->listen_port->port = atoi(tmp);
543 checkmask |= (1L << pc->section->type);
546 case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
548 if (!config->identity)
549 config->identity = silc_calloc(1, sizeof(*config->identity));
552 ret = silc_config_get_token(line, &config->identity->user);
556 ret = silc_config_get_token(line, &config->identity->group);
561 checkmask |= (1L << pc->section->type);
563 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
565 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
567 /* Get class number */
568 ret = silc_config_get_token(line, &tmp);
572 /* Class number not defined */
575 config->conn_class->class = atoi(tmp);
578 /* Get ping frequency */
579 ret = silc_config_get_token(line, &tmp);
582 config->conn_class->ping_freq = atoi(tmp);
585 /* Get connect frequency */
586 ret = silc_config_get_token(line, &tmp);
589 config->conn_class->connect_freq = atoi(tmp);
593 ret = silc_config_get_token(line, &tmp);
596 config->conn_class->max_links = atoi(tmp);
600 checkmask |= (1L << pc->section->type);
603 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
605 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
607 /* Get log section type and check it */
608 ret = silc_config_get_token(line, &config->logging->logtype);
612 fprintf(stderr, "%s:%d: Log file section not defined\n",
613 config->filename, pc->linenum);
616 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
617 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
618 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
619 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
620 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
621 config->filename, pc->linenum, config->logging->logtype);
625 /* Get log filename */
626 ret = silc_config_get_token(line, &config->logging->filename);
630 fprintf(stderr, "%s:%d: Log file name not defined\n",
631 config->filename, pc->linenum);
635 /* Get max byte size */
636 ret = silc_config_get_token(line, &tmp);
640 config->logging->maxsize = atoi(tmp);
645 checkmask |= (1L << pc->section->type);
648 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
650 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
653 ret = silc_config_get_token(line, &config->clients->host);
658 config->clients->host = strdup("*");
660 /* Get authentication method */
661 ret = silc_config_get_token(line, &tmp);
665 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
666 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
667 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
668 config->filename, pc->linenum, tmp);
672 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
673 config->clients->auth_meth = SILC_AUTH_PASSWORD;
675 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
676 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
681 /* Get authentication data */
682 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
686 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
687 config->clients->auth_data_len = strlen(config->clients->auth_data);
688 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
689 /* Get the public key */
690 SilcPublicKey public_key;
692 if (!silc_pkcs_load_public_key(config->clients->auth_data,
693 &public_key, SILC_PKCS_FILE_PEM))
694 if (!silc_pkcs_load_public_key(config->clients->auth_data,
695 &public_key, SILC_PKCS_FILE_BIN)) {
696 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
697 config->filename, pc->linenum,
698 (char *)config->clients->auth_data);
702 silc_free(config->clients->auth_data);
703 config->clients->auth_data = (void *)public_key;
704 config->clients->auth_data_len = 0;
708 ret = silc_config_get_token(line, &tmp);
712 config->clients->port = atoi(tmp);
716 /* Get class number */
717 ret = silc_config_get_token(line, &tmp);
721 config->clients->class = atoi(tmp);
726 checkmask |= (1L << pc->section->type);
729 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
731 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
734 ret = silc_config_get_token(line, &config->servers->host);
739 config->servers->host = strdup("*");
741 /* Get authentication method */
742 ret = silc_config_get_token(line, &tmp);
746 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
747 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
748 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
749 config->filename, pc->linenum, tmp);
753 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
754 config->servers->auth_meth = SILC_AUTH_PASSWORD;
756 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
757 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
762 /* Get authentication data */
763 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
767 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
768 config->servers->auth_data_len = strlen(config->servers->auth_data);
769 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
770 /* Get the public key */
771 SilcPublicKey public_key;
773 if (!silc_pkcs_load_public_key(config->servers->auth_data,
774 &public_key, SILC_PKCS_FILE_PEM))
775 if (!silc_pkcs_load_public_key(config->servers->auth_data,
776 &public_key, SILC_PKCS_FILE_BIN)) {
777 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
778 config->filename, pc->linenum,
779 (char *)config->servers->auth_data);
783 silc_free(config->servers->auth_data);
784 config->servers->auth_data = (void *)public_key;
785 config->servers->auth_data_len = 0;
789 ret = silc_config_get_token(line, &tmp);
793 config->servers->port = atoi(tmp);
798 ret = silc_config_get_token(line, &config->servers->version);
802 /* Get class number */
803 ret = silc_config_get_token(line, &tmp);
807 config->servers->class = atoi(tmp);
812 checkmask |= (1L << pc->section->type);
815 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
817 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
820 ret = silc_config_get_token(line, &config->routers->host);
825 // config->routers->host = strdup("*");
827 /* Get authentication method */
828 ret = silc_config_get_token(line, &tmp);
832 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
833 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
834 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
835 config->filename, pc->linenum, tmp);
839 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
840 config->routers->auth_meth = SILC_AUTH_PASSWORD;
842 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
843 config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
848 /* Get authentication data */
849 ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
853 if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
854 config->routers->auth_data_len = strlen(config->routers->auth_data);
855 } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
856 /* Get the public key */
857 SilcPublicKey public_key;
859 if (!silc_pkcs_load_public_key(config->routers->auth_data,
860 &public_key, SILC_PKCS_FILE_PEM))
861 if (!silc_pkcs_load_public_key(config->routers->auth_data,
862 &public_key, SILC_PKCS_FILE_BIN)) {
863 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
864 config->filename, pc->linenum,
865 (char *)config->routers->auth_data);
869 silc_free(config->routers->auth_data);
870 config->routers->auth_data = (void *)public_key;
871 config->routers->auth_data_len = 0;
875 ret = silc_config_get_token(line, &tmp);
879 config->routers->port = atoi(tmp);
884 ret = silc_config_get_token(line, &config->routers->version);
888 /* Get class number */
889 ret = silc_config_get_token(line, &tmp);
893 config->routers->class = atoi(tmp);
897 /* Get whether we are initiator or not */
898 ret = silc_config_get_token(line, &tmp);
902 config->routers->initiator = atoi(tmp);
903 if (config->routers->initiator != 0)
904 config->routers->initiator = TRUE;
909 checkmask |= (1L << pc->section->type);
912 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
914 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
917 ret = silc_config_get_token(line, &config->admins->host);
922 config->admins->host = strdup("*");
925 ret = silc_config_get_token(line, &config->admins->username);
930 config->admins->username = strdup("*");
933 ret = silc_config_get_token(line, &config->admins->nickname);
938 config->admins->nickname = strdup("*");
940 /* Get authentication method */
941 ret = silc_config_get_token(line, &tmp);
945 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
946 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
947 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
948 config->filename, pc->linenum, tmp);
952 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
953 config->admins->auth_meth = SILC_AUTH_PASSWORD;
955 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
956 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
961 /* Get authentication data */
962 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
966 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
967 config->admins->auth_data_len = strlen(config->admins->auth_data);
968 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
969 /* Get the public key */
970 SilcPublicKey public_key;
972 if (!silc_pkcs_load_public_key(config->admins->auth_data,
973 &public_key, SILC_PKCS_FILE_PEM))
974 if (!silc_pkcs_load_public_key(config->admins->auth_data,
975 &public_key, SILC_PKCS_FILE_BIN)) {
976 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
977 config->filename, pc->linenum,
978 (char *)config->admins->auth_data);
982 silc_free(config->admins->auth_data);
983 config->admins->auth_data = (void *)public_key;
984 config->admins->auth_data_len = 0;
988 checkmask |= (1L << pc->section->type);
991 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
992 /* Not implemented yet */
996 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
999 config->motd = silc_calloc(1, sizeof(*config->motd));
1002 ret = silc_config_get_token(line, &config->motd->motd_file);
1007 checkmask |= (1L << pc->section->type);
1010 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1016 /* Check for error */
1017 if (check == FALSE) {
1018 /* Line could not be parsed */
1019 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1029 /* Check that all mandatory sections really were found. If not, the server
1030 cannot function and we return error. */
1031 ret = silc_server_config_check_sections(checkmask);
1037 /* Before returning all the lists in the config object must be set
1038 to their first values (the last value is first here). */
1039 while (config->cipher && config->cipher->prev)
1040 config->cipher = config->cipher->prev;
1041 while (config->pkcs && config->pkcs->prev)
1042 config->pkcs = config->pkcs->prev;
1043 while (config->hash_func && config->hash_func->prev)
1044 config->hash_func = config->hash_func->prev;
1045 while (config->hmac && config->hmac->prev)
1046 config->hmac = config->hmac->prev;
1047 while (config->listen_port && config->listen_port->prev)
1048 config->listen_port = config->listen_port->prev;
1049 while (config->logging && config->logging->prev)
1050 config->logging = config->logging->prev;
1051 while (config->conn_class && config->conn_class->prev)
1052 config->conn_class = config->conn_class->prev;
1053 while (config->clients && config->clients->prev)
1054 config->clients = config->clients->prev;
1055 while (config->servers && config->servers->prev)
1056 config->servers = config->servers->prev;
1057 while (config->routers && config->routers->prev)
1058 config->routers = config->routers->prev;
1060 SILC_LOG_DEBUG(("Done"));
1065 /* This function checks that the mask sent as argument includes all the
1066 sections that are mandatory in SILC server. */
1068 int silc_server_config_check_sections(unsigned int checkmask)
1070 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1074 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1078 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1083 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1088 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1093 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1101 /* Sets log files where log messages is saved by the server. */
1103 void silc_server_config_setlogfiles(SilcServerConfig config)
1105 SilcServerConfigSectionLogging *log;
1106 char *info, *warning, *error, *fatal;
1107 unsigned int info_size, warning_size, error_size, fatal_size;
1109 SILC_LOG_DEBUG(("Setting configured log file names"));
1111 /* Set default files before checking configuration */
1112 info = SILC_LOG_FILE_INFO;
1113 warning = SILC_LOG_FILE_WARNING;
1114 error = SILC_LOG_FILE_ERROR;
1115 fatal = SILC_LOG_FILE_FATAL;
1121 log = config->logging;
1123 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1124 info = log->filename;
1125 info_size = log->maxsize;
1127 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1128 warning = log->filename;
1129 warning_size = log->maxsize;
1131 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1132 error = log->filename;
1133 error_size = log->maxsize;
1135 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1136 fatal = log->filename;
1137 fatal_size = log->maxsize;
1143 silc_log_set_files(info, info_size, warning, warning_size,
1144 error, error_size, fatal, fatal_size);
1147 /* Registers configured ciphers. These can then be allocated by the
1148 server when needed. */
1150 void silc_server_config_register_ciphers(SilcServerConfig config)
1152 SilcServerConfigSectionAlg *alg;
1153 SilcServer server = (SilcServer)config->server;
1155 SILC_LOG_DEBUG(("Registering configured ciphers"));
1157 alg = config->cipher;
1160 if (!alg->sim_name) {
1161 /* Crypto module is supposed to be built in. Nothing to be done
1162 here except to test that the cipher really is built in. */
1163 SilcCipher tmp = NULL;
1165 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1166 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1167 silc_server_stop(server);
1170 silc_cipher_free(tmp);
1174 /* Load (try at least) the crypto SIM module */
1175 SilcCipherObject cipher;
1176 SilcSimContext *sim;
1179 memset(&cipher, 0, sizeof(cipher));
1180 cipher.name = alg->alg_name;
1181 cipher.block_len = alg->block_len;
1182 cipher.key_len = alg->key_len * 8;
1184 sim = silc_sim_alloc();
1185 sim->type = SILC_SIM_CIPHER;
1186 sim->libname = alg->sim_name;
1188 alg_name = strdup(alg->alg_name);
1189 if (strchr(alg_name, '-'))
1190 *strchr(alg_name, '-') = '\0';
1192 if ((silc_sim_load(sim))) {
1194 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1195 SILC_CIPHER_SIM_SET_KEY));
1196 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1197 cipher.set_key_with_string =
1198 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1199 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1200 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1202 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1203 SILC_CIPHER_SIM_ENCRYPT_CBC));
1204 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1206 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1207 SILC_CIPHER_SIM_DECRYPT_CBC));
1208 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1209 cipher.context_len =
1210 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1211 SILC_CIPHER_SIM_CONTEXT_LEN));
1212 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1214 /* Put the SIM to the list of all SIM's in server */
1215 silc_dlist_add(server->sim, sim);
1217 silc_free(alg_name);
1219 SILC_LOG_ERROR(("Error configuring ciphers"));
1220 silc_server_stop(server);
1224 /* Register the cipher */
1225 silc_cipher_register(&cipher);
1233 /* Registers configured PKCS's. */
1234 /* XXX: This really doesn't do anything now since we have statically
1235 registered our PKCS's. This should be implemented when PKCS works
1236 as SIM's. This checks now only that the PKCS user requested is
1237 really out there. */
1239 void silc_server_config_register_pkcs(SilcServerConfig config)
1241 SilcServerConfigSectionAlg *alg = config->pkcs;
1242 SilcServer server = (SilcServer)config->server;
1243 SilcPKCS tmp = NULL;
1245 SILC_LOG_DEBUG(("Registering configured PKCS"));
1249 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1250 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1251 silc_server_stop(server);
1260 /* Registers configured hash functions. These can then be allocated by the
1261 server when needed. */
1263 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1265 SilcServerConfigSectionAlg *alg;
1266 SilcServer server = (SilcServer)config->server;
1268 SILC_LOG_DEBUG(("Registering configured hash functions"));
1270 alg = config->hash_func;
1273 if (!alg->sim_name) {
1274 /* Hash module is supposed to be built in. Nothing to be done
1275 here except to test that the hash function really is built in. */
1276 SilcHash tmp = NULL;
1278 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1279 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1280 silc_server_stop(server);
1283 silc_hash_free(tmp);
1287 /* Load (try at least) the hash SIM module */
1288 SilcHashObject hash;
1289 SilcSimContext *sim;
1291 memset(&hash, 0, sizeof(hash));
1292 hash.name = alg->alg_name;
1293 hash.block_len = alg->block_len;
1294 hash.hash_len = alg->key_len;
1296 sim = silc_sim_alloc();
1297 sim->type = SILC_SIM_HASH;
1298 sim->libname = alg->sim_name;
1300 if ((silc_sim_load(sim))) {
1302 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1303 SILC_HASH_SIM_INIT));
1304 SILC_LOG_DEBUG(("init=%p", hash.init));
1306 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1307 SILC_HASH_SIM_UPDATE));
1308 SILC_LOG_DEBUG(("update=%p", hash.update));
1310 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1311 SILC_HASH_SIM_FINAL));
1312 SILC_LOG_DEBUG(("final=%p", hash.final));
1314 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1315 SILC_HASH_SIM_CONTEXT_LEN));
1316 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1318 /* Put the SIM to the table of all SIM's in server */
1319 silc_dlist_add(server->sim, sim);
1321 SILC_LOG_ERROR(("Error configuring hash functions"));
1322 silc_server_stop(server);
1326 /* Register the hash function */
1327 silc_hash_register(&hash);
1335 /* Registers configure HMACs. These can then be allocated by the server
1338 void silc_server_config_register_hmacs(SilcServerConfig config)
1340 SilcServerConfigSectionAlg *alg;
1341 SilcServer server = (SilcServer)config->server;
1343 SILC_LOG_DEBUG(("Registering configured HMACs"));
1345 if (!config->hmac) {
1346 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1348 silc_server_stop(server);
1354 SilcHmacObject hmac;
1356 if (!silc_hash_is_supported(alg->sim_name)) {
1357 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1358 silc_server_stop(server);
1362 /* Register the HMAC */
1363 memset(&hmac, 0, sizeof(hmac));
1364 hmac.name = alg->alg_name;
1365 hmac.len = alg->key_len;
1366 silc_hmac_register(&hmac);
1372 /* Returns client authentication information from server configuration
1373 by host (name or ip). */
1375 SilcServerConfigSectionClientConnection *
1376 silc_server_config_find_client_conn(SilcServerConfig config,
1377 char *host, int port)
1380 SilcServerConfigSectionClientConnection *client = NULL;
1385 if (!config->clients)
1388 client = config->clients;
1390 for (i = 0; client; i++) {
1391 if (silc_string_compare(client->host, host))
1393 client = client->next;
1402 /* Returns server connection info from server configuartion by host
1405 SilcServerConfigSectionServerConnection *
1406 silc_server_config_find_server_conn(SilcServerConfig config,
1407 char *host, int port)
1410 SilcServerConfigSectionServerConnection *serv = NULL;
1415 if (!config->servers)
1418 serv = config->servers;
1419 for (i = 0; serv; i++) {
1420 if (silc_string_compare(serv->host, host))
1431 /* Returns router connection info from server configuartion by
1432 host (name or ip). */
1434 SilcServerConfigSectionServerConnection *
1435 silc_server_config_find_router_conn(SilcServerConfig config,
1436 char *host, int port)
1439 SilcServerConfigSectionServerConnection *serv = NULL;
1444 if (!config->routers)
1447 serv = config->routers;
1448 for (i = 0; serv; i++) {
1449 if (silc_string_compare(serv->host, host))
1460 /* Returns Admin connection configuration by host, username and/or
1463 SilcServerConfigSectionAdminConnection *
1464 silc_server_config_find_admin(SilcServerConfig config,
1465 char *host, char *username, char *nickname)
1467 SilcServerConfigSectionAdminConnection *admin = NULL;
1470 if (!config->admins)
1480 admin = config->admins;
1481 for (i = 0; admin; i++) {
1482 if (silc_string_compare(admin->host, host) &&
1483 silc_string_compare(admin->username, username) &&
1484 silc_string_compare(admin->nickname, nickname))
1487 admin = admin->next;
1496 /* Prints out example configuration file with default built in
1497 configuration values. */
1499 void silc_server_config_print()
1505 # Automatically generated example SILCd configuration file with default\n\
1506 # built in values. Use this as a guide to configure your SILCd configuration\n\
1507 # file for your system. For detailed description of different configuration\n\
1508 # sections refer to silcd(8) manual page.\n\
1523 +lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333
1526 +Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
1529 +10.2.1.6:10.2.1.6:1333
1532 +infologfile:silcd.log:10000
1533 #+warninglogfile:/var/log/silcd_warning.log:10000
1534 #+errorlogfile:ERROR.log:10000
1535 #+fatallogfile:/var/log/silcd_error.log:
1542 +10.2.1.199:priikone:333:1
1545 +10.2.1.199:priikone:priikone:1
1554 fprintf(stdout, "%s\n", buf);