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);
1037 /* Check that all mandatory sections really were found. If not, the server
1038 cannot function and we return error. */
1039 ret = silc_server_config_check_sections(checkmask);
1045 /* Before returning all the lists in the config object must be set
1046 to their first values (the last value is first here). */
1047 while (config->cipher && config->cipher->prev)
1048 config->cipher = config->cipher->prev;
1049 while (config->pkcs && config->pkcs->prev)
1050 config->pkcs = config->pkcs->prev;
1051 while (config->hash_func && config->hash_func->prev)
1052 config->hash_func = config->hash_func->prev;
1053 while (config->hmac && config->hmac->prev)
1054 config->hmac = config->hmac->prev;
1055 while (config->listen_port && config->listen_port->prev)
1056 config->listen_port = config->listen_port->prev;
1057 while (config->logging && config->logging->prev)
1058 config->logging = config->logging->prev;
1059 while (config->conn_class && config->conn_class->prev)
1060 config->conn_class = config->conn_class->prev;
1061 while (config->clients && config->clients->prev)
1062 config->clients = config->clients->prev;
1063 while (config->servers && config->servers->prev)
1064 config->servers = config->servers->prev;
1065 while (config->routers && config->routers->prev)
1066 config->routers = config->routers->prev;
1068 SILC_LOG_DEBUG(("Done"));
1073 /* This function checks that the mask sent as argument includes all the
1074 sections that are mandatory in SILC server. */
1076 int silc_server_config_check_sections(unsigned int checkmask)
1078 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1082 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1086 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1091 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1096 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1101 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1109 /* Sets log files where log messages is saved by the server. */
1111 void silc_server_config_setlogfiles(SilcServerConfig config)
1113 SilcServerConfigSectionLogging *log;
1114 char *info, *warning, *error, *fatal;
1115 unsigned int info_size, warning_size, error_size, fatal_size;
1117 SILC_LOG_DEBUG(("Setting configured log file names"));
1119 /* Set default files before checking configuration */
1120 info = SILC_LOG_FILE_INFO;
1121 warning = SILC_LOG_FILE_WARNING;
1122 error = SILC_LOG_FILE_ERROR;
1123 fatal = SILC_LOG_FILE_FATAL;
1129 log = config->logging;
1131 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1132 info = log->filename;
1133 info_size = log->maxsize;
1135 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1136 warning = log->filename;
1137 warning_size = log->maxsize;
1139 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1140 error = log->filename;
1141 error_size = log->maxsize;
1143 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1144 fatal = log->filename;
1145 fatal_size = log->maxsize;
1151 silc_log_set_files(info, info_size, warning, warning_size,
1152 error, error_size, fatal, fatal_size);
1155 /* Registers configured ciphers. These can then be allocated by the
1156 server when needed. */
1158 void silc_server_config_register_ciphers(SilcServerConfig config)
1160 SilcServerConfigSectionAlg *alg;
1161 SilcServer server = (SilcServer)config->server;
1163 SILC_LOG_DEBUG(("Registering configured ciphers"));
1165 alg = config->cipher;
1168 if (!alg->sim_name) {
1169 /* Crypto module is supposed to be built in. Nothing to be done
1170 here except to test that the cipher really is built in. */
1171 SilcCipher tmp = NULL;
1173 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1174 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1175 silc_server_stop(server);
1178 silc_cipher_free(tmp);
1182 /* Load (try at least) the crypto SIM module */
1183 SilcCipherObject cipher;
1184 SilcSimContext *sim;
1187 memset(&cipher, 0, sizeof(cipher));
1188 cipher.name = alg->alg_name;
1189 cipher.block_len = alg->block_len;
1190 cipher.key_len = alg->key_len * 8;
1192 sim = silc_sim_alloc();
1193 sim->type = SILC_SIM_CIPHER;
1194 sim->libname = alg->sim_name;
1196 alg_name = strdup(alg->alg_name);
1197 if (strchr(alg_name, '-'))
1198 *strchr(alg_name, '-') = '\0';
1200 if ((silc_sim_load(sim))) {
1202 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1203 SILC_CIPHER_SIM_SET_KEY));
1204 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1205 cipher.set_key_with_string =
1206 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1207 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1208 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1210 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1211 SILC_CIPHER_SIM_ENCRYPT_CBC));
1212 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1214 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1215 SILC_CIPHER_SIM_DECRYPT_CBC));
1216 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1217 cipher.context_len =
1218 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1219 SILC_CIPHER_SIM_CONTEXT_LEN));
1220 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1222 /* Put the SIM to the list of all SIM's in server */
1223 silc_dlist_add(server->sim, sim);
1225 silc_free(alg_name);
1227 SILC_LOG_ERROR(("Error configuring ciphers"));
1228 silc_server_stop(server);
1232 /* Register the cipher */
1233 silc_cipher_register(&cipher);
1241 /* Registers configured PKCS's. */
1242 /* XXX: This really doesn't do anything now since we have statically
1243 registered our PKCS's. This should be implemented when PKCS works
1244 as SIM's. This checks now only that the PKCS user requested is
1245 really out there. */
1247 void silc_server_config_register_pkcs(SilcServerConfig config)
1249 SilcServerConfigSectionAlg *alg = config->pkcs;
1250 SilcServer server = (SilcServer)config->server;
1251 SilcPKCS tmp = NULL;
1253 SILC_LOG_DEBUG(("Registering configured PKCS"));
1257 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1258 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1259 silc_server_stop(server);
1268 /* Registers configured hash functions. These can then be allocated by the
1269 server when needed. */
1271 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1273 SilcServerConfigSectionAlg *alg;
1274 SilcServer server = (SilcServer)config->server;
1276 SILC_LOG_DEBUG(("Registering configured hash functions"));
1278 alg = config->hash_func;
1281 if (!alg->sim_name) {
1282 /* Hash module is supposed to be built in. Nothing to be done
1283 here except to test that the hash function really is built in. */
1284 SilcHash tmp = NULL;
1286 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1287 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1288 silc_server_stop(server);
1291 silc_hash_free(tmp);
1295 /* Load (try at least) the hash SIM module */
1296 SilcHashObject hash;
1297 SilcSimContext *sim;
1299 memset(&hash, 0, sizeof(hash));
1300 hash.name = alg->alg_name;
1301 hash.block_len = alg->block_len;
1302 hash.hash_len = alg->key_len;
1304 sim = silc_sim_alloc();
1305 sim->type = SILC_SIM_HASH;
1306 sim->libname = alg->sim_name;
1308 if ((silc_sim_load(sim))) {
1310 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1311 SILC_HASH_SIM_INIT));
1312 SILC_LOG_DEBUG(("init=%p", hash.init));
1314 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1315 SILC_HASH_SIM_UPDATE));
1316 SILC_LOG_DEBUG(("update=%p", hash.update));
1318 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1319 SILC_HASH_SIM_FINAL));
1320 SILC_LOG_DEBUG(("final=%p", hash.final));
1322 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1323 SILC_HASH_SIM_CONTEXT_LEN));
1324 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1326 /* Put the SIM to the table of all SIM's in server */
1327 silc_dlist_add(server->sim, sim);
1329 SILC_LOG_ERROR(("Error configuring hash functions"));
1330 silc_server_stop(server);
1334 /* Register the hash function */
1335 silc_hash_register(&hash);
1343 /* Registers configure HMACs. These can then be allocated by the server
1346 void silc_server_config_register_hmacs(SilcServerConfig config)
1348 SilcServerConfigSectionAlg *alg;
1349 SilcServer server = (SilcServer)config->server;
1351 SILC_LOG_DEBUG(("Registering configured HMACs"));
1353 if (!config->hmac) {
1354 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1356 silc_server_stop(server);
1362 SilcHmacObject hmac;
1364 if (!silc_hash_is_supported(alg->sim_name)) {
1365 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1366 silc_server_stop(server);
1370 /* Register the HMAC */
1371 memset(&hmac, 0, sizeof(hmac));
1372 hmac.name = alg->alg_name;
1373 hmac.len = alg->key_len;
1374 silc_hmac_register(&hmac);
1380 /* Returns client authentication information from server configuration
1381 by host (name or ip). */
1383 SilcServerConfigSectionClientConnection *
1384 silc_server_config_find_client_conn(SilcServerConfig config,
1385 char *host, int port)
1388 SilcServerConfigSectionClientConnection *client = NULL;
1393 if (!config->clients)
1396 client = config->clients;
1398 for (i = 0; client; i++) {
1399 if (silc_string_compare(client->host, host))
1401 client = client->next;
1410 /* Returns server connection info from server configuartion by host
1413 SilcServerConfigSectionServerConnection *
1414 silc_server_config_find_server_conn(SilcServerConfig config,
1415 char *host, int port)
1418 SilcServerConfigSectionServerConnection *serv = NULL;
1423 if (!config->servers)
1426 serv = config->servers;
1427 for (i = 0; serv; i++) {
1428 if (silc_string_compare(serv->host, host))
1439 /* Returns router connection info from server configuartion by
1440 host (name or ip). */
1442 SilcServerConfigSectionServerConnection *
1443 silc_server_config_find_router_conn(SilcServerConfig config,
1444 char *host, int port)
1447 SilcServerConfigSectionServerConnection *serv = NULL;
1452 if (!config->routers)
1455 serv = config->routers;
1456 for (i = 0; serv; i++) {
1457 if (silc_string_compare(serv->host, host))
1468 /* Returns Admin connection configuration by host, username and/or
1471 SilcServerConfigSectionAdminConnection *
1472 silc_server_config_find_admin(SilcServerConfig config,
1473 char *host, char *username, char *nickname)
1475 SilcServerConfigSectionAdminConnection *admin = NULL;
1478 if (!config->admins)
1488 admin = config->admins;
1489 for (i = 0; admin; i++) {
1490 if (silc_string_compare(admin->host, host) &&
1491 silc_string_compare(admin->username, username) &&
1492 silc_string_compare(admin->nickname, nickname))
1495 admin = admin->next;
1504 /* Prints out example configuration file with default built in
1505 configuration values. */
1507 void silc_server_config_print()
1513 # Automatically generated example SILCd configuration file with default\n\
1514 # built in values. Use this as a guide to configure your SILCd configuration\n\
1515 # file for your system. For detailed description of different configuration\n\
1516 # sections refer to silcd(8) manual page.\n\
1531 +lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333
1534 +Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
1537 +10.2.1.6:10.2.1.6:1333
1540 +infologfile:silcd.log:10000
1541 #+warninglogfile:/var/log/silcd_warning.log:10000
1542 #+errorlogfile:ERROR.log:10000
1543 #+fatallogfile:/var/log/silcd_error.log:
1550 +10.2.1.199:priikone:333:1
1553 +10.2.1.199:priikone:priikone:1
1563 fprintf(stdout, "%s\n", buf);