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, 4 },
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:
1044 /* Not implemented yet */
1048 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1051 config->motd = silc_calloc(1, sizeof(*config->motd));
1054 ret = silc_config_get_token(line, &config->motd->motd_file);
1059 checkmask |= (1L << pc->section->type);
1062 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1068 /* Check for error */
1069 if (check == FALSE) {
1070 /* Line could not be parsed */
1071 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1081 /* Check that all mandatory sections really were found. If not, the server
1082 cannot function and we return error. */
1083 ret = silc_server_config_check_sections(checkmask);
1089 /* Before returning all the lists in the config object must be set
1090 to their first values (the last value is first here). */
1091 while (config->cipher && config->cipher->prev)
1092 config->cipher = config->cipher->prev;
1093 while (config->pkcs && config->pkcs->prev)
1094 config->pkcs = config->pkcs->prev;
1095 while (config->hash_func && config->hash_func->prev)
1096 config->hash_func = config->hash_func->prev;
1097 while (config->hmac && config->hmac->prev)
1098 config->hmac = config->hmac->prev;
1099 while (config->listen_port && config->listen_port->prev)
1100 config->listen_port = config->listen_port->prev;
1101 while (config->logging && config->logging->prev)
1102 config->logging = config->logging->prev;
1103 while (config->conn_class && config->conn_class->prev)
1104 config->conn_class = config->conn_class->prev;
1105 while (config->clients && config->clients->prev)
1106 config->clients = config->clients->prev;
1107 while (config->servers && config->servers->prev)
1108 config->servers = config->servers->prev;
1109 while (config->admins && config->admins->prev)
1110 config->admins = config->admins->prev;
1111 while (config->routers && config->routers->prev)
1112 config->routers = config->routers->prev;
1114 SILC_LOG_DEBUG(("Done"));
1119 /* This function checks that the mask sent as argument includes all the
1120 sections that are mandatory in SILC server. */
1122 int silc_server_config_check_sections(uint32 checkmask)
1124 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1128 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1132 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1137 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1142 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1147 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1155 /* Sets log files where log messages is saved by the server. */
1157 void silc_server_config_setlogfiles(SilcServerConfig config)
1159 SilcServerConfigSectionLogging *log;
1160 char *info, *warning, *error, *fatal;
1161 uint32 info_size, warning_size, error_size, fatal_size;
1163 SILC_LOG_DEBUG(("Setting configured log file names"));
1165 /* Set default files before checking configuration */
1166 info = SILC_LOG_FILE_INFO;
1167 warning = SILC_LOG_FILE_WARNING;
1168 error = SILC_LOG_FILE_ERROR;
1169 fatal = SILC_LOG_FILE_FATAL;
1175 log = config->logging;
1177 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1178 info = log->filename;
1179 info_size = log->maxsize;
1181 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1182 warning = log->filename;
1183 warning_size = log->maxsize;
1185 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1186 error = log->filename;
1187 error_size = log->maxsize;
1189 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1190 fatal = log->filename;
1191 fatal_size = log->maxsize;
1197 silc_log_set_files(info, info_size, warning, warning_size,
1198 error, error_size, fatal, fatal_size);
1201 /* Registers configured ciphers. These can then be allocated by the
1202 server when needed. */
1204 void silc_server_config_register_ciphers(SilcServerConfig config)
1206 SilcServerConfigSectionAlg *alg;
1207 SilcServer server = (SilcServer)config->server;
1209 SILC_LOG_DEBUG(("Registering configured ciphers"));
1211 alg = config->cipher;
1214 if (!alg->sim_name) {
1215 /* Crypto module is supposed to be built in. Nothing to be done
1216 here except to test that the cipher really is built in. */
1217 SilcCipher tmp = NULL;
1219 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1220 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1221 silc_server_stop(server);
1224 silc_cipher_free(tmp);
1228 /* Load (try at least) the crypto SIM module */
1229 SilcCipherObject cipher;
1230 SilcSimContext *sim;
1233 memset(&cipher, 0, sizeof(cipher));
1234 cipher.name = alg->alg_name;
1235 cipher.block_len = alg->block_len;
1236 cipher.key_len = alg->key_len * 8;
1238 sim = silc_sim_alloc();
1239 sim->type = SILC_SIM_CIPHER;
1240 sim->libname = alg->sim_name;
1242 alg_name = strdup(alg->alg_name);
1243 if (strchr(alg_name, '-'))
1244 *strchr(alg_name, '-') = '\0';
1246 if ((silc_sim_load(sim))) {
1248 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1249 SILC_CIPHER_SIM_SET_KEY));
1250 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1251 cipher.set_key_with_string =
1252 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1253 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1254 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1256 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1257 SILC_CIPHER_SIM_ENCRYPT_CBC));
1258 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1260 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1261 SILC_CIPHER_SIM_DECRYPT_CBC));
1262 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1263 cipher.context_len =
1264 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1265 SILC_CIPHER_SIM_CONTEXT_LEN));
1266 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1268 /* Put the SIM to the list of all SIM's in server */
1269 silc_dlist_add(server->sim, sim);
1271 silc_free(alg_name);
1273 SILC_LOG_ERROR(("Error configuring ciphers"));
1274 silc_server_stop(server);
1278 /* Register the cipher */
1279 silc_cipher_register(&cipher);
1287 /* Registers configured PKCS's. */
1288 /* XXX: This really doesn't do anything now since we have statically
1289 registered our PKCS's. This should be implemented when PKCS works
1290 as SIM's. This checks now only that the PKCS user requested is
1291 really out there. */
1293 void silc_server_config_register_pkcs(SilcServerConfig config)
1295 SilcServerConfigSectionAlg *alg = config->pkcs;
1296 SilcServer server = (SilcServer)config->server;
1297 SilcPKCS tmp = NULL;
1299 SILC_LOG_DEBUG(("Registering configured PKCS"));
1303 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1304 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1305 silc_server_stop(server);
1314 /* Registers configured hash functions. These can then be allocated by the
1315 server when needed. */
1317 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1319 SilcServerConfigSectionAlg *alg;
1320 SilcServer server = (SilcServer)config->server;
1322 SILC_LOG_DEBUG(("Registering configured hash functions"));
1324 alg = config->hash_func;
1327 if (!alg->sim_name) {
1328 /* Hash module is supposed to be built in. Nothing to be done
1329 here except to test that the hash function really is built in. */
1330 SilcHash tmp = NULL;
1332 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1333 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1334 silc_server_stop(server);
1337 silc_hash_free(tmp);
1341 /* Load (try at least) the hash SIM module */
1342 SilcHashObject hash;
1343 SilcSimContext *sim;
1345 memset(&hash, 0, sizeof(hash));
1346 hash.name = alg->alg_name;
1347 hash.block_len = alg->block_len;
1348 hash.hash_len = alg->key_len;
1350 sim = silc_sim_alloc();
1351 sim->type = SILC_SIM_HASH;
1352 sim->libname = alg->sim_name;
1354 if ((silc_sim_load(sim))) {
1356 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1357 SILC_HASH_SIM_INIT));
1358 SILC_LOG_DEBUG(("init=%p", hash.init));
1360 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1361 SILC_HASH_SIM_UPDATE));
1362 SILC_LOG_DEBUG(("update=%p", hash.update));
1364 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1365 SILC_HASH_SIM_FINAL));
1366 SILC_LOG_DEBUG(("final=%p", hash.final));
1368 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1369 SILC_HASH_SIM_CONTEXT_LEN));
1370 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1372 /* Put the SIM to the table of all SIM's in server */
1373 silc_dlist_add(server->sim, sim);
1375 SILC_LOG_ERROR(("Error configuring hash functions"));
1376 silc_server_stop(server);
1380 /* Register the hash function */
1381 silc_hash_register(&hash);
1389 /* Registers configure HMACs. These can then be allocated by the server
1392 void silc_server_config_register_hmacs(SilcServerConfig config)
1394 SilcServerConfigSectionAlg *alg;
1395 SilcServer server = (SilcServer)config->server;
1397 SILC_LOG_DEBUG(("Registering configured HMACs"));
1399 if (!config->hmac) {
1400 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1402 silc_server_stop(server);
1408 SilcHmacObject hmac;
1410 if (!silc_hash_is_supported(alg->sim_name)) {
1411 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1412 silc_server_stop(server);
1416 /* Register the HMAC */
1417 memset(&hmac, 0, sizeof(hmac));
1418 hmac.name = alg->alg_name;
1419 hmac.len = alg->key_len;
1420 silc_hmac_register(&hmac);
1426 /* Returns client authentication information from server configuration
1427 by host (name or ip). If `port' is non-null then both name or IP and
1428 the port must match. */
1430 SilcServerConfigSectionClientConnection *
1431 silc_server_config_find_client_conn(SilcServerConfig config,
1432 char *host, int port)
1435 SilcServerConfigSectionClientConnection *client = NULL;
1441 if (!config->clients)
1444 client = config->clients;
1446 for (i = 0; client; i++) {
1447 if (silc_string_compare(client->host, host))
1450 if (port && client->port != port)
1456 client = client->next;
1465 /* Returns server connection info from server configuartion by host
1466 (name or ip). If `port' is non-null then both name or IP and the port
1469 SilcServerConfigSectionServerConnection *
1470 silc_server_config_find_server_conn(SilcServerConfig config,
1471 char *host, int port)
1474 SilcServerConfigSectionServerConnection *serv = NULL;
1480 if (!config->servers)
1483 serv = config->servers;
1484 for (i = 0; serv; i++) {
1485 if (silc_string_compare(serv->host, host))
1488 if (port && serv->port != port)
1503 /* Returns router connection info from server configuartion by
1504 host (name or ip). */
1506 SilcServerConfigSectionServerConnection *
1507 silc_server_config_find_router_conn(SilcServerConfig config,
1508 char *host, int port)
1511 SilcServerConfigSectionServerConnection *serv = NULL;
1517 if (!config->routers)
1520 serv = config->routers;
1521 for (i = 0; serv; i++) {
1522 if (silc_string_compare(serv->host, host))
1525 if (port && serv->port != port)
1540 /* Returns TRUE if configuartion for a router connection that we are
1541 initiating exists. */
1543 bool silc_server_config_is_primary_route(SilcServerConfig config)
1546 SilcServerConfigSectionServerConnection *serv = NULL;
1549 serv = config->routers;
1550 for (i = 0; serv; i++) {
1551 if (serv->initiator == TRUE) {
1562 /* Returns Admin connection configuration by host, username and/or
1565 SilcServerConfigSectionAdminConnection *
1566 silc_server_config_find_admin(SilcServerConfig config,
1567 char *host, char *username, char *nickname)
1569 SilcServerConfigSectionAdminConnection *admin = NULL;
1572 if (!config->admins)
1582 admin = config->admins;
1583 for (i = 0; admin; i++) {
1584 if (silc_string_compare(admin->host, host) &&
1585 silc_string_compare(admin->username, username) &&
1586 silc_string_compare(admin->nickname, nickname))
1589 admin = admin->next;