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_REDIRECT_CLIENT, 2 },
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 /* Open configuration file and parse it */
87 silc_config_open(filename, &buffer);
90 if ((silc_server_config_parse(new, buffer, &config_parse)) == FALSE)
92 if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
104 /* Free's a configuration object. */
106 void silc_server_config_free(SilcServerConfig config)
109 silc_free(config->filename);
110 silc_free(config->server_info);
111 silc_free(config->admin_info);
112 silc_free(config->listen_port);
113 silc_free(config->identity);
114 silc_free(config->conn_class);
115 silc_free(config->clients);
116 silc_free(config->admins);
117 silc_free(config->servers);
118 silc_free(config->routers);
119 silc_free(config->denied);
120 silc_free(config->redirect);
121 silc_free(config->motd);
126 /* Parses the the buffer and returns the parsed lines into return_config
127 argument. The return_config argument doesn't have to be initialized
128 before calling this. It will be initialized during the parsing. The
129 buffer sent as argument can be safely free'd after this function has
130 succesfully returned. */
132 int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
133 SilcServerConfigParse *return_config)
136 unsigned int linenum;
137 char line[1024], *cp;
138 SilcServerConfigSection *cptr = NULL;
139 SilcServerConfigParse parse = *return_config, first = NULL;
141 SILC_LOG_DEBUG(("Parsing configuration file"));
145 while((begin = silc_gets(line, sizeof(line),
146 buffer->data, buffer->len, begin)) != EOF) {
150 /* Check for bad line */
151 if (silc_check_line(cp))
154 /* Remove tabs and whitespaces from the line */
155 if (strchr(cp, '\t')) {
157 while(strchr(cp + i, '\t')) {
158 *strchr(cp + i, '\t') = ' ';
162 for (i = 0; i < strlen(cp); i++) {
178 /* Remove new line sign */
179 if (strchr(cp, '\n'))
180 *strchr(cp, '\n') = '\0';
182 /* Check for matching sections */
183 for (cptr = silc_server_config_sections; cptr->section; cptr++)
184 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
187 if (!cptr->section) {
188 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
189 config->filename, linenum, cp);
196 * Start of a configuration line
199 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
201 if (strchr(cp, '\n'))
202 *strchr(cp, '\n') = ':';
205 parse = silc_calloc(1, sizeof(*parse));
207 parse->section = NULL;
211 if (parse->next == NULL) {
212 parse->next = silc_calloc(1, sizeof(*parse->next));
213 parse->next->line = NULL;
214 parse->next->section = NULL;
215 parse->next->next = NULL;
216 parse->next->prev = parse;
224 /* Add the line to parsing structure for further parsing. */
226 parse->section = cptr;
227 parse->line = silc_buffer_alloc(strlen(cp) + 1);
228 parse->linenum = linenum;
229 silc_buffer_pull_tail(parse->line, strlen(cp));
230 silc_buffer_put(parse->line, cp, strlen(cp));
237 /* Set the return_config argument to its first value so that further
238 parsing can be started from the first line. */
239 *return_config = first;
244 /* Parses the lines earlier read from configuration file. The config object
245 must not be initialized, it will be initialized in this function. The
246 parse_config argument is uninitialized automatically during this
249 int silc_server_config_parse_lines(SilcServerConfig config,
250 SilcServerConfigParse parse_config)
252 int ret, check = FALSE;
253 unsigned int checkmask;
255 SilcServerConfigParse pc = parse_config;
258 SILC_LOG_DEBUG(("Parsing configuration lines"));
268 /* Get number of tokens in line */
269 ret = silc_config_check_num_token(line);
270 if (ret != pc->section->maxfields) {
272 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
273 config->filename, pc->linenum, ret,
274 pc->section->maxfields);
279 switch(pc->section->type) {
280 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
282 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
284 /* Get cipher name */
285 ret = silc_config_get_token(line, &config->cipher->alg_name);
289 fprintf(stderr, "%s:%d: Cipher name not defined\n",
290 config->filename, pc->linenum);
294 /* Get module name */
295 config->cipher->sim_name = NULL;
296 ret = silc_config_get_token(line, &config->cipher->sim_name);
301 ret = silc_config_get_token(line, &tmp);
305 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
306 config->filename, pc->linenum);
309 config->cipher->key_len = atoi(tmp);
312 /* Get block length */
313 ret = silc_config_get_token(line, &tmp);
317 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
318 config->filename, pc->linenum);
321 config->cipher->block_len = atoi(tmp);
325 checkmask |= (1L << pc->section->type);
328 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
330 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
333 ret = silc_config_get_token(line, &config->pkcs->alg_name);
337 fprintf(stderr, "%s:%d: PKCS name not defined\n",
338 config->filename, pc->linenum);
343 ret = silc_config_get_token(line, &tmp);
347 fprintf(stderr, "%s:%d: PKCS key length not defined\n",
348 config->filename, pc->linenum);
351 config->pkcs->key_len = atoi(tmp);
355 checkmask |= (1L << pc->section->type);
358 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
360 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
362 /* Get Hash function name */
363 ret = silc_config_get_token(line, &config->hash_func->alg_name);
367 fprintf(stderr, "%s:%d: Hash function name not defined\n",
368 config->filename, pc->linenum);
372 /* Get Hash function module name */
373 config->hash_func->sim_name = NULL;
374 ret = silc_config_get_token(line, &config->hash_func->sim_name);
378 /* Get block length */
379 ret = silc_config_get_token(line, &tmp);
383 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
384 config->filename, pc->linenum);
387 config->hash_func->block_len = atoi(tmp);
390 /* Get hash length */
391 ret = silc_config_get_token(line, &tmp);
395 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
396 config->filename, pc->linenum);
399 config->hash_func->key_len = atoi(tmp);
403 checkmask |= (1L << pc->section->type);
406 case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
408 SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
411 ret = silc_config_get_token(line, &config->hmac->alg_name);
415 fprintf(stderr, "%s:%d: HMAC name not defined\n",
416 config->filename, pc->linenum);
421 ret = silc_config_get_token(line, &config->hmac->sim_name);
425 fprintf(stderr, "%s:%d: Hash function name not defined\n",
426 config->filename, pc->linenum);
431 ret = silc_config_get_token(line, &tmp);
435 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
436 config->filename, pc->linenum);
439 config->hmac->key_len = atoi(tmp);
443 checkmask |= (1L << pc->section->type);
446 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
448 if (!config->server_info)
449 config->server_info = silc_calloc(1, sizeof(*config->server_info));
451 /* Get server name */
452 ret = silc_config_get_token(line, &config->server_info->server_name);
456 /* Server name not defined */
461 ret = silc_config_get_token(line, &config->server_info->server_ip);
465 /* Server IP not defined */
469 /* Get server location */
470 ret = silc_config_get_token(line, &config->server_info->location);
474 /* Get server port */
475 /* XXX: Need port here??? */
476 ret = silc_config_get_token(line, &tmp);
480 /* Port not defined */
483 config->server_info->port = atoi(tmp);
487 checkmask |= (1L << pc->section->type);
490 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
492 if (!config->admin_info)
493 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
496 ret = silc_config_get_token(line, &config->admin_info->location);
500 /* Get server type */
501 ret = silc_config_get_token(line, &config->admin_info->server_type);
505 /* Get admins name */
506 ret = silc_config_get_token(line, &config->admin_info->admin_name);
510 /* Get admins email address */
511 ret = silc_config_get_token(line, &config->admin_info->admin_email);
516 checkmask |= (1L << pc->section->type);
519 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
521 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
524 ret = silc_config_get_token(line, &config->listen_port->host);
529 ret = silc_config_get_token(line, &config->listen_port->remote_ip);
534 ret = silc_config_get_token(line, &tmp);
539 config->listen_port->port = 0;
541 config->listen_port->port = atoi(tmp);
546 checkmask |= (1L << pc->section->type);
549 case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
551 if (!config->identity)
552 config->identity = silc_calloc(1, sizeof(*config->identity));
555 ret = silc_config_get_token(line, &config->identity->user);
559 ret = silc_config_get_token(line, &config->identity->group);
564 checkmask |= (1L << pc->section->type);
566 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
568 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
570 /* Get class number */
571 ret = silc_config_get_token(line, &tmp);
575 /* Class number not defined */
578 config->conn_class->class = atoi(tmp);
581 /* Get ping frequency */
582 ret = silc_config_get_token(line, &tmp);
585 config->conn_class->ping_freq = atoi(tmp);
588 /* Get connect frequency */
589 ret = silc_config_get_token(line, &tmp);
592 config->conn_class->connect_freq = atoi(tmp);
596 ret = silc_config_get_token(line, &tmp);
599 config->conn_class->max_links = atoi(tmp);
603 checkmask |= (1L << pc->section->type);
606 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
608 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
610 /* Get log section type and check it */
611 ret = silc_config_get_token(line, &config->logging->logtype);
615 fprintf(stderr, "%s:%d: Log file section not defined\n",
616 config->filename, pc->linenum);
619 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
620 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
621 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
622 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
623 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
624 config->filename, pc->linenum, config->logging->logtype);
628 /* Get log filename */
629 ret = silc_config_get_token(line, &config->logging->filename);
633 fprintf(stderr, "%s:%d: Log file name not defined\n",
634 config->filename, pc->linenum);
638 /* Get max byte size */
639 ret = silc_config_get_token(line, &tmp);
643 config->logging->maxsize = atoi(tmp);
648 checkmask |= (1L << pc->section->type);
651 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
653 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
656 ret = silc_config_get_token(line, &config->clients->host);
661 config->clients->host = strdup("*");
663 /* Get authentication method */
664 ret = silc_config_get_token(line, &tmp);
668 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
669 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
670 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
671 config->filename, pc->linenum, tmp);
675 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
676 config->clients->auth_meth = SILC_AUTH_PASSWORD;
678 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
679 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
684 /* Get authentication data */
685 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
689 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
690 config->clients->auth_data_len = strlen(config->clients->auth_data);
691 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
692 /* Get the public key */
693 SilcPublicKey public_key;
695 if (!silc_pkcs_load_public_key(config->clients->auth_data,
696 &public_key, SILC_PKCS_FILE_PEM))
697 if (!silc_pkcs_load_public_key(config->clients->auth_data,
698 &public_key, SILC_PKCS_FILE_BIN)) {
699 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
700 config->filename, pc->linenum,
701 (char *)config->clients->auth_data);
705 silc_free(config->clients->auth_data);
706 config->clients->auth_data = (void *)public_key;
707 config->clients->auth_data_len = 0;
711 ret = silc_config_get_token(line, &tmp);
715 config->clients->port = atoi(tmp);
719 /* Get class number */
720 ret = silc_config_get_token(line, &tmp);
724 config->clients->class = atoi(tmp);
729 checkmask |= (1L << pc->section->type);
732 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
734 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
737 ret = silc_config_get_token(line, &config->servers->host);
742 config->servers->host = strdup("*");
744 /* Get authentication method */
745 ret = silc_config_get_token(line, &tmp);
749 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
750 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
751 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
752 config->filename, pc->linenum, tmp);
756 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
757 config->servers->auth_meth = SILC_AUTH_PASSWORD;
759 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
760 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
765 /* Get authentication data */
766 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
770 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
771 config->servers->auth_data_len = strlen(config->servers->auth_data);
772 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
773 /* Get the public key */
774 SilcPublicKey public_key;
776 if (!silc_pkcs_load_public_key(config->servers->auth_data,
777 &public_key, SILC_PKCS_FILE_PEM))
778 if (!silc_pkcs_load_public_key(config->servers->auth_data,
779 &public_key, SILC_PKCS_FILE_BIN)) {
780 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
781 config->filename, pc->linenum,
782 (char *)config->servers->auth_data);
786 silc_free(config->servers->auth_data);
787 config->servers->auth_data = (void *)public_key;
788 config->servers->auth_data_len = 0;
792 ret = silc_config_get_token(line, &tmp);
796 config->servers->port = atoi(tmp);
801 ret = silc_config_get_token(line, &config->servers->version);
805 /* Get class number */
806 ret = silc_config_get_token(line, &tmp);
810 config->servers->class = atoi(tmp);
815 checkmask |= (1L << pc->section->type);
818 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
820 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
823 ret = silc_config_get_token(line, &config->routers->host);
828 // config->routers->host = strdup("*");
830 /* Get authentication method */
831 ret = silc_config_get_token(line, &tmp);
835 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
836 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
837 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
838 config->filename, pc->linenum, tmp);
842 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
843 config->routers->auth_meth = SILC_AUTH_PASSWORD;
845 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
846 config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
851 /* Get authentication data */
852 ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
856 if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
857 config->routers->auth_data_len = strlen(config->routers->auth_data);
858 } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
859 /* Get the public key */
860 SilcPublicKey public_key;
862 if (!silc_pkcs_load_public_key(config->routers->auth_data,
863 &public_key, SILC_PKCS_FILE_PEM))
864 if (!silc_pkcs_load_public_key(config->routers->auth_data,
865 &public_key, SILC_PKCS_FILE_BIN)) {
866 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
867 config->filename, pc->linenum,
868 (char *)config->routers->auth_data);
872 silc_free(config->routers->auth_data);
873 config->routers->auth_data = (void *)public_key;
874 config->routers->auth_data_len = 0;
878 ret = silc_config_get_token(line, &tmp);
882 config->routers->port = atoi(tmp);
887 ret = silc_config_get_token(line, &config->routers->version);
891 /* Get class number */
892 ret = silc_config_get_token(line, &tmp);
896 config->routers->class = atoi(tmp);
900 /* Get whether we are initiator or not */
901 ret = silc_config_get_token(line, &tmp);
905 config->routers->initiator = atoi(tmp);
906 if (config->routers->initiator != 0)
907 config->routers->initiator = TRUE;
912 checkmask |= (1L << pc->section->type);
915 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
917 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
920 ret = silc_config_get_token(line, &config->admins->host);
925 config->admins->host = strdup("*");
928 ret = silc_config_get_token(line, &config->admins->username);
933 config->admins->username = strdup("*");
936 ret = silc_config_get_token(line, &config->admins->nickname);
941 config->admins->nickname = strdup("*");
943 /* Get authentication method */
944 ret = silc_config_get_token(line, &tmp);
948 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
949 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
950 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
951 config->filename, pc->linenum, tmp);
955 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
956 config->admins->auth_meth = SILC_AUTH_PASSWORD;
958 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
959 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
964 /* Get authentication data */
965 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
969 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
970 config->admins->auth_data_len = strlen(config->admins->auth_data);
971 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
972 /* Get the public key */
973 SilcPublicKey public_key;
975 if (!silc_pkcs_load_public_key(config->admins->auth_data,
976 &public_key, SILC_PKCS_FILE_PEM))
977 if (!silc_pkcs_load_public_key(config->admins->auth_data,
978 &public_key, SILC_PKCS_FILE_BIN)) {
979 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
980 config->filename, pc->linenum,
981 (char *)config->admins->auth_data);
985 silc_free(config->admins->auth_data);
986 config->admins->auth_data = (void *)public_key;
987 config->admins->auth_data_len = 0;
991 checkmask |= (1L << pc->section->type);
994 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
995 /* Not implemented yet */
999 case SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT:
1000 /* Not implemented yet */
1004 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1007 config->motd = silc_calloc(1, sizeof(*config->motd));
1010 ret = silc_config_get_token(line, &config->motd->motd_file);
1015 checkmask |= (1L << pc->section->type);
1018 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1024 /* Check for error */
1025 if (check == FALSE) {
1026 /* Line could not be parsed */
1027 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1033 // silc_free(pc->prev);
1040 /* Check that all mandatory sections really were found. If not, the server
1041 cannot function and we return error. */
1042 ret = silc_server_config_check_sections(checkmask);
1048 /* Before returning all the lists in the config object must be set
1049 to their first values (the last value is first here). */
1050 while (config->cipher && config->cipher->prev)
1051 config->cipher = config->cipher->prev;
1052 while (config->pkcs && config->pkcs->prev)
1053 config->pkcs = config->pkcs->prev;
1054 while (config->hash_func && config->hash_func->prev)
1055 config->hash_func = config->hash_func->prev;
1056 while (config->hmac && config->hmac->prev)
1057 config->hmac = config->hmac->prev;
1058 while (config->listen_port && config->listen_port->prev)
1059 config->listen_port = config->listen_port->prev;
1060 while (config->logging && config->logging->prev)
1061 config->logging = config->logging->prev;
1062 while (config->conn_class && config->conn_class->prev)
1063 config->conn_class = config->conn_class->prev;
1064 while (config->clients && config->clients->prev)
1065 config->clients = config->clients->prev;
1066 while (config->servers && config->servers->prev)
1067 config->servers = config->servers->prev;
1068 while (config->routers && config->routers->prev)
1069 config->routers = config->routers->prev;
1071 SILC_LOG_DEBUG(("Done"));
1076 /* This function checks that the mask sent as argument includes all the
1077 sections that are mandatory in SILC server. */
1079 int silc_server_config_check_sections(unsigned int checkmask)
1081 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1085 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1089 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1093 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1098 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1103 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1111 /* Sets log files where log messages is saved by the server. */
1113 void silc_server_config_setlogfiles(SilcServerConfig config)
1115 SilcServerConfigSectionLogging *log;
1116 char *info, *warning, *error, *fatal;
1117 unsigned int info_size, warning_size, error_size, fatal_size;
1119 SILC_LOG_DEBUG(("Setting configured log file names"));
1121 /* Set default files before checking configuration */
1122 info = SILC_LOG_FILE_INFO;
1123 warning = SILC_LOG_FILE_WARNING;
1124 error = SILC_LOG_FILE_ERROR;
1125 fatal = SILC_LOG_FILE_FATAL;
1131 log = config->logging;
1133 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1134 info = log->filename;
1135 info_size = log->maxsize;
1137 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1138 warning = log->filename;
1139 warning_size = log->maxsize;
1141 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1142 error = log->filename;
1143 error_size = log->maxsize;
1145 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1146 fatal = log->filename;
1147 fatal_size = log->maxsize;
1153 silc_log_set_files(info, info_size, warning, warning_size,
1154 error, error_size, fatal, fatal_size);
1157 /* Registers configured ciphers. These can then be allocated by the
1158 server when needed. */
1160 void silc_server_config_register_ciphers(SilcServerConfig config)
1162 SilcServerConfigSectionAlg *alg;
1163 SilcServer server = (SilcServer)config->server;
1165 SILC_LOG_DEBUG(("Registering configured ciphers"));
1167 alg = config->cipher;
1170 if (!alg->sim_name) {
1171 /* Crypto module is supposed to be built in. Nothing to be done
1172 here except to test that the cipher really is built in. */
1173 SilcCipher tmp = NULL;
1175 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1176 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1177 silc_server_stop(server);
1180 silc_cipher_free(tmp);
1184 /* Load (try at least) the crypto SIM module */
1185 SilcCipherObject cipher;
1186 SilcSimContext *sim;
1189 memset(&cipher, 0, sizeof(cipher));
1190 cipher.name = alg->alg_name;
1191 cipher.block_len = alg->block_len;
1192 cipher.key_len = alg->key_len * 8;
1194 sim = silc_sim_alloc();
1195 sim->type = SILC_SIM_CIPHER;
1196 sim->libname = alg->sim_name;
1198 alg_name = strdup(alg->alg_name);
1199 if (strchr(alg_name, '-'))
1200 *strchr(alg_name, '-') = '\0';
1202 if ((silc_sim_load(sim))) {
1204 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1205 SILC_CIPHER_SIM_SET_KEY));
1206 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1207 cipher.set_key_with_string =
1208 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1209 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1210 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1212 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1213 SILC_CIPHER_SIM_ENCRYPT_CBC));
1214 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1216 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1217 SILC_CIPHER_SIM_DECRYPT_CBC));
1218 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1219 cipher.context_len =
1220 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1221 SILC_CIPHER_SIM_CONTEXT_LEN));
1222 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1224 /* Put the SIM to the list of all SIM's in server */
1225 silc_dlist_add(server->sim, sim);
1227 silc_free(alg_name);
1229 SILC_LOG_ERROR(("Error configuring ciphers"));
1230 silc_server_stop(server);
1234 /* Register the cipher */
1235 silc_cipher_register(&cipher);
1243 /* Registers configured PKCS's. */
1244 /* XXX: This really doesn't do anything now since we have statically
1245 registered our PKCS's. This should be implemented when PKCS works
1246 as SIM's. This checks now only that the PKCS user requested is
1247 really out there. */
1249 void silc_server_config_register_pkcs(SilcServerConfig config)
1251 SilcServerConfigSectionAlg *alg = config->pkcs;
1252 SilcServer server = (SilcServer)config->server;
1253 SilcPKCS tmp = NULL;
1255 SILC_LOG_DEBUG(("Registering configured PKCS"));
1259 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1260 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1261 silc_server_stop(server);
1270 /* Registers configured hash functions. These can then be allocated by the
1271 server when needed. */
1273 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1275 SilcServerConfigSectionAlg *alg;
1276 SilcServer server = (SilcServer)config->server;
1278 SILC_LOG_DEBUG(("Registering configured hash functions"));
1280 alg = config->hash_func;
1283 if (!alg->sim_name) {
1284 /* Hash module is supposed to be built in. Nothing to be done
1285 here except to test that the hash function really is built in. */
1286 SilcHash tmp = NULL;
1288 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1289 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1290 silc_server_stop(server);
1293 silc_hash_free(tmp);
1297 /* Load (try at least) the hash SIM module */
1298 SilcHashObject hash;
1299 SilcSimContext *sim;
1301 memset(&hash, 0, sizeof(hash));
1302 hash.name = alg->alg_name;
1303 hash.block_len = alg->block_len;
1304 hash.hash_len = alg->key_len;
1306 sim = silc_sim_alloc();
1307 sim->type = SILC_SIM_HASH;
1308 sim->libname = alg->sim_name;
1310 if ((silc_sim_load(sim))) {
1312 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1313 SILC_HASH_SIM_INIT));
1314 SILC_LOG_DEBUG(("init=%p", hash.init));
1316 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1317 SILC_HASH_SIM_UPDATE));
1318 SILC_LOG_DEBUG(("update=%p", hash.update));
1320 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1321 SILC_HASH_SIM_FINAL));
1322 SILC_LOG_DEBUG(("final=%p", hash.final));
1324 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1325 SILC_HASH_SIM_CONTEXT_LEN));
1326 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1328 /* Put the SIM to the table of all SIM's in server */
1329 silc_dlist_add(server->sim, sim);
1331 SILC_LOG_ERROR(("Error configuring hash functions"));
1332 silc_server_stop(server);
1336 /* Register the hash function */
1337 silc_hash_register(&hash);
1345 /* Registers configure HMACs. These can then be allocated by the server
1348 void silc_server_config_register_hmacs(SilcServerConfig config)
1350 SilcServerConfigSectionAlg *alg;
1351 SilcServer server = (SilcServer)config->server;
1353 SILC_LOG_DEBUG(("Registering configured HMACs"));
1355 if (!config->hmac) {
1356 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1358 silc_server_stop(server);
1364 SilcHmacObject hmac;
1366 if (!silc_hash_is_supported(alg->sim_name)) {
1367 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1368 silc_server_stop(server);
1372 /* Register the HMAC */
1373 memset(&hmac, 0, sizeof(hmac));
1374 hmac.name = alg->alg_name;
1375 hmac.len = alg->key_len;
1376 silc_hmac_register(&hmac);
1382 /* Returns client authentication information from server configuration
1383 by host (name or ip). */
1385 SilcServerConfigSectionClientConnection *
1386 silc_server_config_find_client_conn(SilcServerConfig config,
1387 char *host, int port)
1390 SilcServerConfigSectionClientConnection *client = NULL;
1395 if (!config->clients)
1398 client = config->clients;
1400 for (i = 0; client; i++) {
1401 if (silc_string_compare(client->host, host))
1403 client = client->next;
1412 /* Returns server connection info from server configuartion by host
1415 SilcServerConfigSectionServerConnection *
1416 silc_server_config_find_server_conn(SilcServerConfig config,
1417 char *host, int port)
1420 SilcServerConfigSectionServerConnection *serv = NULL;
1425 if (!config->servers)
1428 serv = config->servers;
1429 for (i = 0; serv; i++) {
1430 if (silc_string_compare(serv->host, host))
1441 /* Returns router connection info from server configuartion by
1442 host (name or ip). */
1444 SilcServerConfigSectionServerConnection *
1445 silc_server_config_find_router_conn(SilcServerConfig config,
1446 char *host, int port)
1449 SilcServerConfigSectionServerConnection *serv = NULL;
1454 if (!config->routers)
1457 serv = config->routers;
1458 for (i = 0; serv; i++) {
1459 if (silc_string_compare(serv->host, host))
1470 /* Returns Admin connection configuration by host, username and/or
1473 SilcServerConfigSectionAdminConnection *
1474 silc_server_config_find_admin(SilcServerConfig config,
1475 char *host, char *username, char *nickname)
1477 SilcServerConfigSectionAdminConnection *admin = NULL;
1480 if (!config->admins)
1490 admin = config->admins;
1491 for (i = 0; admin; i++) {
1492 if (silc_string_compare(admin->host, host) &&
1493 silc_string_compare(admin->username, username) &&
1494 silc_string_compare(admin->nickname, nickname))
1497 admin = admin->next;
1506 /* Prints out example configuration file with default built in
1507 configuration values. */
1509 void silc_server_config_print()
1515 # Automatically generated example SILCd configuration file with default\n\
1516 # built in values. Use this as a guide to configure your SILCd configuration\n\
1517 # file for your system. For detailed description of different configuration\n\
1518 # sections refer to silcd(8) manual page.\n\
1533 +lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333
1536 +Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
1539 +10.2.1.6:10.2.1.6:1333
1542 +infologfile:silcd.log:10000
1543 #+warninglogfile:/var/log/silcd_warning.log:10000
1544 #+errorlogfile:ERROR.log:10000
1545 #+fatallogfile:/var/log/silcd_error.log:
1552 +10.2.1.199:priikone:333:1
1555 +10.2.1.199:priikone:priikone:1
1565 fprintf(stdout, "%s\n", buf);