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_KEYS, 2 },
37 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 },
39 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 },
41 SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 },
43 SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY, 2 },
45 SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 },
46 { "[ConnectionClass]",
47 SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 },
48 { "[ClientConnection]",
49 SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION, 5 },
50 { "[ServerConnection]",
51 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION, 6 },
52 { "[RouterConnection]",
53 SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION, 7 },
54 { "[AdminConnection]",
55 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 },
57 SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 },
59 SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
61 { NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
64 /* Allocates a new configuration object, opens configuration file and
65 parses the file. The parsed data is returned to the newly allocated
66 configuration object. */
68 SilcServerConfig silc_server_config_alloc(char *filename)
72 SilcServerConfigParse config_parse;
74 SILC_LOG_DEBUG(("Allocating new configuration object"));
76 new = silc_calloc(1, sizeof(*new));
78 fprintf(stderr, "Could not allocate new configuration object");
82 new->filename = filename;
84 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
86 /* Open configuration file and parse it */
89 silc_config_open(filename, &buffer);
92 if ((silc_server_config_parse(new, buffer, &config_parse)) == FALSE)
94 if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
106 /* Free's a configuration object. */
108 void silc_server_config_free(SilcServerConfig config)
111 silc_free(config->filename);
112 silc_free(config->server_keys);
113 silc_free(config->server_info);
114 silc_free(config->admin_info);
115 silc_free(config->listen_port);
116 silc_free(config->identity);
117 silc_free(config->conn_class);
118 silc_free(config->clients);
119 silc_free(config->admins);
120 silc_free(config->servers);
121 silc_free(config->routers);
122 silc_free(config->denied);
123 silc_free(config->motd);
128 /* Parses the the buffer and returns the parsed lines into return_config
129 argument. The return_config argument doesn't have to be initialized
130 before calling this. It will be initialized during the parsing. The
131 buffer sent as argument can be safely free'd after this function has
132 succesfully returned. */
134 int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
135 SilcServerConfigParse *return_config)
137 int i, begin, linenum;
138 char line[1024], *cp;
139 SilcServerConfigSection *cptr = NULL;
140 SilcServerConfigParse parse = *return_config, first = NULL;
142 SILC_LOG_DEBUG(("Parsing configuration file"));
146 while((begin = silc_gets(line, sizeof(line),
147 buffer->data, buffer->len, begin)) != EOF) {
151 /* Check for bad line */
152 if (silc_check_line(cp))
155 /* Remove tabs and whitespaces from the line */
156 if (strchr(cp, '\t')) {
158 while(strchr(cp + i, '\t')) {
159 *strchr(cp + i, '\t') = ' ';
163 for (i = 0; i < strlen(cp); i++) {
179 /* Remove new line sign */
180 if (strchr(cp, '\n'))
181 *strchr(cp, '\n') = '\0';
183 /* Check for matching sections */
184 for (cptr = silc_server_config_sections; cptr->section; cptr++)
185 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
188 if (!cptr->section) {
189 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
190 config->filename, linenum, cp);
197 * Start of a configuration line
200 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
202 if (strchr(cp, '\n'))
203 *strchr(cp, '\n') = ':';
206 parse = silc_calloc(1, sizeof(*parse));
208 parse->section = NULL;
212 if (parse->next == NULL) {
213 parse->next = silc_calloc(1, sizeof(*parse->next));
214 parse->next->line = NULL;
215 parse->next->section = NULL;
216 parse->next->next = NULL;
217 parse->next->prev = parse;
225 /* Add the line to parsing structure for further parsing. */
227 parse->section = cptr;
228 parse->line = silc_buffer_alloc(strlen(cp) + 1);
229 parse->linenum = linenum;
230 silc_buffer_pull_tail(parse->line, strlen(cp));
231 silc_buffer_put(parse->line, cp, strlen(cp));
238 /* Set the return_config argument to its first value so that further
239 parsing can be started from the first line. */
240 *return_config = first;
245 /* Parses the lines earlier read from configuration file. The config object
246 must not be initialized, it will be initialized in this function. The
247 parse_config argument is uninitialized automatically during this
250 int silc_server_config_parse_lines(SilcServerConfig config,
251 SilcServerConfigParse parse_config)
253 int ret, check = FALSE;
256 SilcServerConfigParse pc = parse_config;
259 SILC_LOG_DEBUG(("Parsing configuration lines"));
269 /* Get number of tokens in line */
270 ret = silc_config_check_num_token(line);
271 if (ret != pc->section->maxfields) {
273 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
274 config->filename, pc->linenum, ret,
275 pc->section->maxfields);
280 switch(pc->section->type) {
281 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
283 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
285 /* Get cipher name */
286 ret = silc_config_get_token(line, &config->cipher->alg_name);
290 fprintf(stderr, "%s:%d: Cipher name not defined\n",
291 config->filename, pc->linenum);
295 /* Get module name */
296 config->cipher->sim_name = NULL;
297 ret = silc_config_get_token(line, &config->cipher->sim_name);
302 ret = silc_config_get_token(line, &tmp);
306 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
307 config->filename, pc->linenum);
310 config->cipher->key_len = atoi(tmp);
313 /* Get block length */
314 ret = silc_config_get_token(line, &tmp);
318 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
319 config->filename, pc->linenum);
322 config->cipher->block_len = atoi(tmp);
326 checkmask |= (1L << pc->section->type);
329 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
331 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
334 ret = silc_config_get_token(line, &config->pkcs->alg_name);
338 fprintf(stderr, "%s:%d: PKCS name not defined\n",
339 config->filename, pc->linenum);
344 ret = silc_config_get_token(line, &tmp);
348 fprintf(stderr, "%s:%d: PKCS key length not defined\n",
349 config->filename, pc->linenum);
352 config->pkcs->key_len = atoi(tmp);
356 checkmask |= (1L << pc->section->type);
359 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
361 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
363 /* Get Hash function name */
364 ret = silc_config_get_token(line, &config->hash_func->alg_name);
368 fprintf(stderr, "%s:%d: Hash function name not defined\n",
369 config->filename, pc->linenum);
373 /* Get Hash function module name */
374 config->hash_func->sim_name = NULL;
375 ret = silc_config_get_token(line, &config->hash_func->sim_name);
379 /* Get block length */
380 ret = silc_config_get_token(line, &tmp);
384 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
385 config->filename, pc->linenum);
388 config->hash_func->block_len = atoi(tmp);
391 /* Get hash length */
392 ret = silc_config_get_token(line, &tmp);
396 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
397 config->filename, pc->linenum);
400 config->hash_func->key_len = atoi(tmp);
404 checkmask |= (1L << pc->section->type);
407 case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
409 SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
412 ret = silc_config_get_token(line, &config->hmac->alg_name);
416 fprintf(stderr, "%s:%d: HMAC name not defined\n",
417 config->filename, pc->linenum);
422 ret = silc_config_get_token(line, &config->hmac->sim_name);
426 fprintf(stderr, "%s:%d: Hash function name not defined\n",
427 config->filename, pc->linenum);
432 ret = silc_config_get_token(line, &tmp);
436 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
437 config->filename, pc->linenum);
440 config->hmac->key_len = atoi(tmp);
444 checkmask |= (1L << pc->section->type);
447 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS:
449 if (!config->server_keys)
450 config->server_keys = silc_calloc(1, sizeof(*config->server_keys));
452 ret = silc_config_get_token(line, &tmp);
456 fprintf(stderr, "%s:%d: Public key name not defined\n",
457 config->filename, pc->linenum);
461 if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
463 if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
464 SILC_PKCS_FILE_BIN)) {
465 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
466 config->filename, pc->linenum, tmp);
471 ret = silc_config_get_token(line, &tmp);
475 fprintf(stderr, "%s:%d: Private key name not defined\n",
476 config->filename, pc->linenum);
480 if (!silc_pkcs_load_private_key(tmp, &config->server_keys->private_key,
482 if (!silc_pkcs_load_private_key(tmp,
483 &config->server_keys->private_key,
484 SILC_PKCS_FILE_PEM)) {
485 fprintf(stderr, "%s:%d: Could not load private key file `%s'\n",
486 config->filename, pc->linenum, tmp);
492 checkmask |= (1L << pc->section->type);
495 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
497 if (!config->server_info)
498 config->server_info = silc_calloc(1, sizeof(*config->server_info));
500 /* Get server name */
501 ret = silc_config_get_token(line, &config->server_info->server_name);
505 /* Server name not defined */
510 ret = silc_config_get_token(line, &config->server_info->server_ip);
514 /* Server IP not defined */
518 /* Get server location */
519 ret = silc_config_get_token(line, &config->server_info->location);
523 /* Get server port */
524 /* XXX: Need port here??? */
525 ret = silc_config_get_token(line, &tmp);
529 /* Port not defined */
532 config->server_info->port = atoi(tmp);
536 checkmask |= (1L << pc->section->type);
539 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
541 if (!config->admin_info)
542 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
545 ret = silc_config_get_token(line, &config->admin_info->location);
549 /* Get server type */
550 ret = silc_config_get_token(line, &config->admin_info->server_type);
554 /* Get admins name */
555 ret = silc_config_get_token(line, &config->admin_info->admin_name);
559 /* Get admins email address */
560 ret = silc_config_get_token(line, &config->admin_info->admin_email);
565 checkmask |= (1L << pc->section->type);
568 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
570 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
573 ret = silc_config_get_token(line, &config->listen_port->host);
578 ret = silc_config_get_token(line, &config->listen_port->remote_ip);
583 ret = silc_config_get_token(line, &tmp);
588 config->listen_port->port = 0;
590 config->listen_port->port = atoi(tmp);
595 checkmask |= (1L << pc->section->type);
598 case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
600 if (!config->identity)
601 config->identity = silc_calloc(1, sizeof(*config->identity));
604 ret = silc_config_get_token(line, &config->identity->user);
608 ret = silc_config_get_token(line, &config->identity->group);
613 checkmask |= (1L << pc->section->type);
615 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
617 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
619 /* Get class number */
620 ret = silc_config_get_token(line, &tmp);
624 /* Class number not defined */
627 config->conn_class->class = atoi(tmp);
630 /* Get ping frequency */
631 ret = silc_config_get_token(line, &tmp);
634 config->conn_class->ping_freq = atoi(tmp);
637 /* Get connect frequency */
638 ret = silc_config_get_token(line, &tmp);
641 config->conn_class->connect_freq = atoi(tmp);
645 ret = silc_config_get_token(line, &tmp);
648 config->conn_class->max_links = atoi(tmp);
652 checkmask |= (1L << pc->section->type);
655 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
657 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
659 /* Get log section type and check it */
660 ret = silc_config_get_token(line, &config->logging->logtype);
664 fprintf(stderr, "%s:%d: Log file section not defined\n",
665 config->filename, pc->linenum);
668 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
669 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
670 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
671 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
672 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
673 config->filename, pc->linenum, config->logging->logtype);
677 /* Get log filename */
678 ret = silc_config_get_token(line, &config->logging->filename);
682 fprintf(stderr, "%s:%d: Log file name not defined\n",
683 config->filename, pc->linenum);
687 /* Get max byte size */
688 ret = silc_config_get_token(line, &tmp);
692 config->logging->maxsize = atoi(tmp);
697 checkmask |= (1L << pc->section->type);
700 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
702 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
705 ret = silc_config_get_token(line, &config->clients->host);
710 config->clients->host = strdup("*");
712 /* Get authentication method */
713 ret = silc_config_get_token(line, &tmp);
717 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
718 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
719 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
720 config->filename, pc->linenum, tmp);
724 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
725 config->clients->auth_meth = SILC_AUTH_PASSWORD;
727 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
728 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
733 /* Get authentication data */
734 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
738 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
739 config->clients->auth_data_len = strlen(config->clients->auth_data);
740 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
741 /* Get the public key */
742 SilcPublicKey public_key;
744 if (!silc_pkcs_load_public_key(config->clients->auth_data,
745 &public_key, SILC_PKCS_FILE_PEM))
746 if (!silc_pkcs_load_public_key(config->clients->auth_data,
747 &public_key, SILC_PKCS_FILE_BIN)) {
748 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
749 config->filename, pc->linenum,
750 (char *)config->clients->auth_data);
754 silc_free(config->clients->auth_data);
755 config->clients->auth_data = (void *)public_key;
756 config->clients->auth_data_len = 0;
760 ret = silc_config_get_token(line, &tmp);
764 config->clients->port = atoi(tmp);
768 /* Get class number */
769 ret = silc_config_get_token(line, &tmp);
773 config->clients->class = atoi(tmp);
778 checkmask |= (1L << pc->section->type);
781 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
783 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
786 ret = silc_config_get_token(line, &config->servers->host);
791 config->servers->host = strdup("*");
793 /* Get authentication method */
794 ret = silc_config_get_token(line, &tmp);
798 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
799 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
800 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
801 config->filename, pc->linenum, tmp);
805 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
806 config->servers->auth_meth = SILC_AUTH_PASSWORD;
808 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
809 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
814 /* Get authentication data */
815 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
819 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
820 config->servers->auth_data_len = strlen(config->servers->auth_data);
821 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
822 /* Get the public key */
823 SilcPublicKey public_key;
825 if (!silc_pkcs_load_public_key(config->servers->auth_data,
826 &public_key, SILC_PKCS_FILE_PEM))
827 if (!silc_pkcs_load_public_key(config->servers->auth_data,
828 &public_key, SILC_PKCS_FILE_BIN)) {
829 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
830 config->filename, pc->linenum,
831 (char *)config->servers->auth_data);
835 silc_free(config->servers->auth_data);
836 config->servers->auth_data = (void *)public_key;
837 config->servers->auth_data_len = 0;
841 ret = silc_config_get_token(line, &tmp);
845 config->servers->port = atoi(tmp);
850 ret = silc_config_get_token(line, &config->servers->version);
854 /* Get class number */
855 ret = silc_config_get_token(line, &tmp);
859 config->servers->class = atoi(tmp);
864 checkmask |= (1L << pc->section->type);
867 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
869 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
872 ret = silc_config_get_token(line, &config->routers->host);
877 // config->routers->host = strdup("*");
879 /* Get authentication method */
880 ret = silc_config_get_token(line, &tmp);
884 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
885 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
886 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
887 config->filename, pc->linenum, tmp);
891 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
892 config->routers->auth_meth = SILC_AUTH_PASSWORD;
894 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
895 config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
900 /* Get authentication data */
901 ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
905 if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
906 config->routers->auth_data_len = strlen(config->routers->auth_data);
907 } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
908 /* Get the public key */
909 SilcPublicKey public_key;
911 if (!silc_pkcs_load_public_key(config->routers->auth_data,
912 &public_key, SILC_PKCS_FILE_PEM))
913 if (!silc_pkcs_load_public_key(config->routers->auth_data,
914 &public_key, SILC_PKCS_FILE_BIN)) {
915 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
916 config->filename, pc->linenum,
917 (char *)config->routers->auth_data);
921 silc_free(config->routers->auth_data);
922 config->routers->auth_data = (void *)public_key;
923 config->routers->auth_data_len = 0;
927 ret = silc_config_get_token(line, &tmp);
931 config->routers->port = atoi(tmp);
936 ret = silc_config_get_token(line, &config->routers->version);
940 /* Get class number */
941 ret = silc_config_get_token(line, &tmp);
945 config->routers->class = atoi(tmp);
949 /* Get whether we are initiator or not */
950 ret = silc_config_get_token(line, &tmp);
954 config->routers->initiator = atoi(tmp);
955 if (config->routers->initiator != 0)
956 config->routers->initiator = TRUE;
961 checkmask |= (1L << pc->section->type);
964 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
966 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
969 ret = silc_config_get_token(line, &config->admins->host);
974 config->admins->host = strdup("*");
977 ret = silc_config_get_token(line, &config->admins->username);
982 config->admins->username = strdup("*");
985 ret = silc_config_get_token(line, &config->admins->nickname);
990 config->admins->nickname = strdup("*");
992 /* Get authentication method */
993 ret = silc_config_get_token(line, &tmp);
997 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
998 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
999 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
1000 config->filename, pc->linenum, tmp);
1004 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
1005 config->admins->auth_meth = SILC_AUTH_PASSWORD;
1007 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
1008 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
1013 /* Get authentication data */
1014 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
1018 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
1019 config->admins->auth_data_len = strlen(config->admins->auth_data);
1020 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
1021 /* Get the public key */
1022 SilcPublicKey public_key;
1024 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1025 &public_key, SILC_PKCS_FILE_PEM))
1026 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1027 &public_key, SILC_PKCS_FILE_BIN)) {
1028 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
1029 config->filename, pc->linenum,
1030 (char *)config->admins->auth_data);
1034 silc_free(config->admins->auth_data);
1035 config->admins->auth_data = (void *)public_key;
1036 config->admins->auth_data_len = 0;
1040 checkmask |= (1L << pc->section->type);
1043 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
1045 SILC_SERVER_CONFIG_LIST_ALLOC(config->denied);
1048 ret = silc_config_get_token(line, &config->denied->host);
1053 config->denied->host = strdup("*");
1054 fprintf(stderr, "warning: %s:%d: Denying all connections",
1055 config->filename, pc->linenum);
1059 ret = silc_config_get_token(line, &tmp);
1064 config->denied->port = 0;
1066 config->denied->port = atoi(tmp);
1071 ret = silc_config_get_token(line, &config->denied->comment);
1076 checkmask |= (1L << pc->section->type);
1079 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1082 config->motd = silc_calloc(1, sizeof(*config->motd));
1085 ret = silc_config_get_token(line, &config->motd->motd_file);
1090 checkmask |= (1L << pc->section->type);
1093 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1099 /* Check for error */
1100 if (check == FALSE) {
1101 /* Line could not be parsed */
1102 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1112 /* Check that all mandatory sections really were found. If not, the server
1113 cannot function and we return error. */
1114 ret = silc_server_config_check_sections(checkmask);
1120 /* Before returning all the lists in the config object must be set
1121 to their first values (the last value is first here). */
1122 while (config->cipher && config->cipher->prev)
1123 config->cipher = config->cipher->prev;
1124 while (config->pkcs && config->pkcs->prev)
1125 config->pkcs = config->pkcs->prev;
1126 while (config->hash_func && config->hash_func->prev)
1127 config->hash_func = config->hash_func->prev;
1128 while (config->hmac && config->hmac->prev)
1129 config->hmac = config->hmac->prev;
1130 while (config->listen_port && config->listen_port->prev)
1131 config->listen_port = config->listen_port->prev;
1132 while (config->logging && config->logging->prev)
1133 config->logging = config->logging->prev;
1134 while (config->conn_class && config->conn_class->prev)
1135 config->conn_class = config->conn_class->prev;
1136 while (config->clients && config->clients->prev)
1137 config->clients = config->clients->prev;
1138 while (config->servers && config->servers->prev)
1139 config->servers = config->servers->prev;
1140 while (config->admins && config->admins->prev)
1141 config->admins = config->admins->prev;
1142 while (config->routers && config->routers->prev)
1143 config->routers = config->routers->prev;
1145 SILC_LOG_DEBUG(("Done"));
1150 /* This function checks that the mask sent as argument includes all the
1151 sections that are mandatory in SILC server. */
1153 int silc_server_config_check_sections(uint32 checkmask)
1155 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1159 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1163 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1168 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1173 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1178 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1186 /* Sets log files where log messages is saved by the server. */
1188 void silc_server_config_setlogfiles(SilcServerConfig config)
1190 SilcServerConfigSectionLogging *log;
1191 char *info, *warning, *error, *fatal;
1192 uint32 info_size, warning_size, error_size, fatal_size;
1194 SILC_LOG_DEBUG(("Setting configured log file names"));
1196 /* Set default files before checking configuration */
1197 info = SILC_LOG_FILE_INFO;
1198 warning = SILC_LOG_FILE_WARNING;
1199 error = SILC_LOG_FILE_ERROR;
1200 fatal = SILC_LOG_FILE_FATAL;
1206 log = config->logging;
1208 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1209 info = log->filename;
1210 info_size = log->maxsize;
1212 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1213 warning = log->filename;
1214 warning_size = log->maxsize;
1216 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1217 error = log->filename;
1218 error_size = log->maxsize;
1220 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1221 fatal = log->filename;
1222 fatal_size = log->maxsize;
1228 silc_log_set_files(info, info_size, warning, warning_size,
1229 error, error_size, fatal, fatal_size);
1232 /* Registers configured ciphers. These can then be allocated by the
1233 server when needed. */
1235 void silc_server_config_register_ciphers(SilcServerConfig config)
1237 SilcServerConfigSectionAlg *alg;
1238 SilcServer server = (SilcServer)config->server;
1240 SILC_LOG_DEBUG(("Registering configured ciphers"));
1242 alg = config->cipher;
1245 if (!alg->sim_name) {
1246 /* Crypto module is supposed to be built in. Nothing to be done
1247 here except to test that the cipher really is built in. */
1248 SilcCipher tmp = NULL;
1250 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1251 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1252 silc_server_stop(server);
1255 silc_cipher_free(tmp);
1259 /* Load (try at least) the crypto SIM module */
1260 SilcCipherObject cipher;
1261 SilcSimContext *sim;
1264 memset(&cipher, 0, sizeof(cipher));
1265 cipher.name = alg->alg_name;
1266 cipher.block_len = alg->block_len;
1267 cipher.key_len = alg->key_len * 8;
1269 sim = silc_sim_alloc();
1270 sim->type = SILC_SIM_CIPHER;
1271 sim->libname = alg->sim_name;
1273 alg_name = strdup(alg->alg_name);
1274 if (strchr(alg_name, '-'))
1275 *strchr(alg_name, '-') = '\0';
1277 if ((silc_sim_load(sim))) {
1279 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1280 SILC_CIPHER_SIM_SET_KEY));
1281 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1282 cipher.set_key_with_string =
1283 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1284 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1285 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1287 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1288 SILC_CIPHER_SIM_ENCRYPT_CBC));
1289 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1291 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1292 SILC_CIPHER_SIM_DECRYPT_CBC));
1293 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1294 cipher.context_len =
1295 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1296 SILC_CIPHER_SIM_CONTEXT_LEN));
1297 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1299 /* Put the SIM to the list of all SIM's in server */
1300 silc_dlist_add(server->sim, sim);
1302 silc_free(alg_name);
1304 SILC_LOG_ERROR(("Error configuring ciphers"));
1305 silc_server_stop(server);
1309 /* Register the cipher */
1310 silc_cipher_register(&cipher);
1318 /* Registers configured PKCS's. */
1319 /* XXX: This really doesn't do anything now since we have statically
1320 registered our PKCS's. This should be implemented when PKCS works
1321 as SIM's. This checks now only that the PKCS user requested is
1322 really out there. */
1324 void silc_server_config_register_pkcs(SilcServerConfig config)
1326 SilcServerConfigSectionAlg *alg = config->pkcs;
1327 SilcServer server = (SilcServer)config->server;
1328 SilcPKCS tmp = NULL;
1330 SILC_LOG_DEBUG(("Registering configured PKCS"));
1334 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1335 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1336 silc_server_stop(server);
1345 /* Registers configured hash functions. These can then be allocated by the
1346 server when needed. */
1348 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1350 SilcServerConfigSectionAlg *alg;
1351 SilcServer server = (SilcServer)config->server;
1353 SILC_LOG_DEBUG(("Registering configured hash functions"));
1355 alg = config->hash_func;
1358 if (!alg->sim_name) {
1359 /* Hash module is supposed to be built in. Nothing to be done
1360 here except to test that the hash function really is built in. */
1361 SilcHash tmp = NULL;
1363 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1364 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1365 silc_server_stop(server);
1368 silc_hash_free(tmp);
1372 /* Load (try at least) the hash SIM module */
1373 SilcHashObject hash;
1374 SilcSimContext *sim;
1376 memset(&hash, 0, sizeof(hash));
1377 hash.name = alg->alg_name;
1378 hash.block_len = alg->block_len;
1379 hash.hash_len = alg->key_len;
1381 sim = silc_sim_alloc();
1382 sim->type = SILC_SIM_HASH;
1383 sim->libname = alg->sim_name;
1385 if ((silc_sim_load(sim))) {
1387 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1388 SILC_HASH_SIM_INIT));
1389 SILC_LOG_DEBUG(("init=%p", hash.init));
1391 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1392 SILC_HASH_SIM_UPDATE));
1393 SILC_LOG_DEBUG(("update=%p", hash.update));
1395 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1396 SILC_HASH_SIM_FINAL));
1397 SILC_LOG_DEBUG(("final=%p", hash.final));
1399 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1400 SILC_HASH_SIM_CONTEXT_LEN));
1401 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1403 /* Put the SIM to the table of all SIM's in server */
1404 silc_dlist_add(server->sim, sim);
1406 SILC_LOG_ERROR(("Error configuring hash functions"));
1407 silc_server_stop(server);
1411 /* Register the hash function */
1412 silc_hash_register(&hash);
1420 /* Registers configure HMACs. These can then be allocated by the server
1423 void silc_server_config_register_hmacs(SilcServerConfig config)
1425 SilcServerConfigSectionAlg *alg;
1426 SilcServer server = (SilcServer)config->server;
1428 SILC_LOG_DEBUG(("Registering configured HMACs"));
1430 if (!config->hmac) {
1431 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1433 silc_server_stop(server);
1439 SilcHmacObject hmac;
1441 if (!silc_hash_is_supported(alg->sim_name)) {
1442 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1443 silc_server_stop(server);
1447 /* Register the HMAC */
1448 memset(&hmac, 0, sizeof(hmac));
1449 hmac.name = alg->alg_name;
1450 hmac.len = alg->key_len;
1451 silc_hmac_register(&hmac);
1457 /* Returns client authentication information from server configuration
1458 by host (name or ip). If `port' is non-null then both name or IP and
1459 the port must match. */
1461 SilcServerConfigSectionClientConnection *
1462 silc_server_config_find_client_conn(SilcServerConfig config,
1463 char *host, int port)
1466 SilcServerConfigSectionClientConnection *client = NULL;
1472 if (!config->clients)
1475 client = config->clients;
1477 for (i = 0; client; i++) {
1478 if (silc_string_compare(client->host, host))
1481 if (port && client->port && client->port != port)
1487 client = client->next;
1496 /* Returns server connection info from server configuartion by host
1497 (name or ip). If `port' is non-null then both name or IP and the port
1500 SilcServerConfigSectionServerConnection *
1501 silc_server_config_find_server_conn(SilcServerConfig config,
1502 char *host, int port)
1505 SilcServerConfigSectionServerConnection *serv = NULL;
1511 if (!config->servers)
1514 serv = config->servers;
1515 for (i = 0; serv; i++) {
1516 if (silc_string_compare(serv->host, host))
1519 if (port && serv->port && serv->port != port)
1534 /* Returns router connection info from server configuartion by
1535 host (name or ip). */
1537 SilcServerConfigSectionServerConnection *
1538 silc_server_config_find_router_conn(SilcServerConfig config,
1539 char *host, int port)
1542 SilcServerConfigSectionServerConnection *serv = NULL;
1548 if (!config->routers)
1551 serv = config->routers;
1552 for (i = 0; serv; i++) {
1553 if (silc_string_compare(serv->host, host))
1556 if (port && serv->port && serv->port != port)
1571 /* Returns TRUE if configuartion for a router connection that we are
1572 initiating exists. */
1574 bool silc_server_config_is_primary_route(SilcServerConfig config)
1577 SilcServerConfigSectionServerConnection *serv = NULL;
1580 serv = config->routers;
1581 for (i = 0; serv; i++) {
1582 if (serv->initiator == TRUE) {
1593 /* Returns Admin connection configuration by host, username and/or
1596 SilcServerConfigSectionAdminConnection *
1597 silc_server_config_find_admin(SilcServerConfig config,
1598 char *host, char *username, char *nickname)
1600 SilcServerConfigSectionAdminConnection *admin = NULL;
1603 if (!config->admins)
1613 admin = config->admins;
1614 for (i = 0; admin; i++) {
1615 if (silc_string_compare(admin->host, host) &&
1616 silc_string_compare(admin->username, username) &&
1617 silc_string_compare(admin->nickname, nickname))
1620 admin = admin->next;
1629 /* Returns the Denied connection configuration by host and port. */
1631 SilcServerConfigSectionDenyConnection *
1632 silc_server_config_denied_conn(SilcServerConfig config, char *host,
1636 SilcServerConfigSectionDenyConnection *deny = NULL;
1642 if (!config->denied)
1645 deny = config->denied;
1646 for (i = 0; deny; i++) {
1647 if (silc_string_compare(deny->host, host))
1650 if (port && deny->port && deny->port != port)