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->routers && config->routers->prev)
1110 config->routers = config->routers->prev;
1112 SILC_LOG_DEBUG(("Done"));
1117 /* This function checks that the mask sent as argument includes all the
1118 sections that are mandatory in SILC server. */
1120 int silc_server_config_check_sections(uint32 checkmask)
1122 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1126 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1130 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1135 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1140 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1145 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1153 /* Sets log files where log messages is saved by the server. */
1155 void silc_server_config_setlogfiles(SilcServerConfig config)
1157 SilcServerConfigSectionLogging *log;
1158 char *info, *warning, *error, *fatal;
1159 uint32 info_size, warning_size, error_size, fatal_size;
1161 SILC_LOG_DEBUG(("Setting configured log file names"));
1163 /* Set default files before checking configuration */
1164 info = SILC_LOG_FILE_INFO;
1165 warning = SILC_LOG_FILE_WARNING;
1166 error = SILC_LOG_FILE_ERROR;
1167 fatal = SILC_LOG_FILE_FATAL;
1173 log = config->logging;
1175 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1176 info = log->filename;
1177 info_size = log->maxsize;
1179 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1180 warning = log->filename;
1181 warning_size = log->maxsize;
1183 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1184 error = log->filename;
1185 error_size = log->maxsize;
1187 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1188 fatal = log->filename;
1189 fatal_size = log->maxsize;
1195 silc_log_set_files(info, info_size, warning, warning_size,
1196 error, error_size, fatal, fatal_size);
1199 /* Registers configured ciphers. These can then be allocated by the
1200 server when needed. */
1202 void silc_server_config_register_ciphers(SilcServerConfig config)
1204 SilcServerConfigSectionAlg *alg;
1205 SilcServer server = (SilcServer)config->server;
1207 SILC_LOG_DEBUG(("Registering configured ciphers"));
1209 alg = config->cipher;
1212 if (!alg->sim_name) {
1213 /* Crypto module is supposed to be built in. Nothing to be done
1214 here except to test that the cipher really is built in. */
1215 SilcCipher tmp = NULL;
1217 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1218 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1219 silc_server_stop(server);
1222 silc_cipher_free(tmp);
1226 /* Load (try at least) the crypto SIM module */
1227 SilcCipherObject cipher;
1228 SilcSimContext *sim;
1231 memset(&cipher, 0, sizeof(cipher));
1232 cipher.name = alg->alg_name;
1233 cipher.block_len = alg->block_len;
1234 cipher.key_len = alg->key_len * 8;
1236 sim = silc_sim_alloc();
1237 sim->type = SILC_SIM_CIPHER;
1238 sim->libname = alg->sim_name;
1240 alg_name = strdup(alg->alg_name);
1241 if (strchr(alg_name, '-'))
1242 *strchr(alg_name, '-') = '\0';
1244 if ((silc_sim_load(sim))) {
1246 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1247 SILC_CIPHER_SIM_SET_KEY));
1248 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1249 cipher.set_key_with_string =
1250 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1251 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1252 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1254 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1255 SILC_CIPHER_SIM_ENCRYPT_CBC));
1256 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1258 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1259 SILC_CIPHER_SIM_DECRYPT_CBC));
1260 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1261 cipher.context_len =
1262 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1263 SILC_CIPHER_SIM_CONTEXT_LEN));
1264 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1266 /* Put the SIM to the list of all SIM's in server */
1267 silc_dlist_add(server->sim, sim);
1269 silc_free(alg_name);
1271 SILC_LOG_ERROR(("Error configuring ciphers"));
1272 silc_server_stop(server);
1276 /* Register the cipher */
1277 silc_cipher_register(&cipher);
1285 /* Registers configured PKCS's. */
1286 /* XXX: This really doesn't do anything now since we have statically
1287 registered our PKCS's. This should be implemented when PKCS works
1288 as SIM's. This checks now only that the PKCS user requested is
1289 really out there. */
1291 void silc_server_config_register_pkcs(SilcServerConfig config)
1293 SilcServerConfigSectionAlg *alg = config->pkcs;
1294 SilcServer server = (SilcServer)config->server;
1295 SilcPKCS tmp = NULL;
1297 SILC_LOG_DEBUG(("Registering configured PKCS"));
1301 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1302 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1303 silc_server_stop(server);
1312 /* Registers configured hash functions. These can then be allocated by the
1313 server when needed. */
1315 void silc_server_config_register_hashfuncs(SilcServerConfig config)
1317 SilcServerConfigSectionAlg *alg;
1318 SilcServer server = (SilcServer)config->server;
1320 SILC_LOG_DEBUG(("Registering configured hash functions"));
1322 alg = config->hash_func;
1325 if (!alg->sim_name) {
1326 /* Hash module is supposed to be built in. Nothing to be done
1327 here except to test that the hash function really is built in. */
1328 SilcHash tmp = NULL;
1330 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1331 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1332 silc_server_stop(server);
1335 silc_hash_free(tmp);
1339 /* Load (try at least) the hash SIM module */
1340 SilcHashObject hash;
1341 SilcSimContext *sim;
1343 memset(&hash, 0, sizeof(hash));
1344 hash.name = alg->alg_name;
1345 hash.block_len = alg->block_len;
1346 hash.hash_len = alg->key_len;
1348 sim = silc_sim_alloc();
1349 sim->type = SILC_SIM_HASH;
1350 sim->libname = alg->sim_name;
1352 if ((silc_sim_load(sim))) {
1354 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1355 SILC_HASH_SIM_INIT));
1356 SILC_LOG_DEBUG(("init=%p", hash.init));
1358 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1359 SILC_HASH_SIM_UPDATE));
1360 SILC_LOG_DEBUG(("update=%p", hash.update));
1362 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1363 SILC_HASH_SIM_FINAL));
1364 SILC_LOG_DEBUG(("final=%p", hash.final));
1366 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1367 SILC_HASH_SIM_CONTEXT_LEN));
1368 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1370 /* Put the SIM to the table of all SIM's in server */
1371 silc_dlist_add(server->sim, sim);
1373 SILC_LOG_ERROR(("Error configuring hash functions"));
1374 silc_server_stop(server);
1378 /* Register the hash function */
1379 silc_hash_register(&hash);
1387 /* Registers configure HMACs. These can then be allocated by the server
1390 void silc_server_config_register_hmacs(SilcServerConfig config)
1392 SilcServerConfigSectionAlg *alg;
1393 SilcServer server = (SilcServer)config->server;
1395 SILC_LOG_DEBUG(("Registering configured HMACs"));
1397 if (!config->hmac) {
1398 SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
1400 silc_server_stop(server);
1406 SilcHmacObject hmac;
1408 if (!silc_hash_is_supported(alg->sim_name)) {
1409 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
1410 silc_server_stop(server);
1414 /* Register the HMAC */
1415 memset(&hmac, 0, sizeof(hmac));
1416 hmac.name = alg->alg_name;
1417 hmac.len = alg->key_len;
1418 silc_hmac_register(&hmac);
1424 /* Returns client authentication information from server configuration
1425 by host (name or ip). */
1427 SilcServerConfigSectionClientConnection *
1428 silc_server_config_find_client_conn(SilcServerConfig config,
1429 char *host, int port)
1432 SilcServerConfigSectionClientConnection *client = NULL;
1437 if (!config->clients)
1440 client = config->clients;
1442 for (i = 0; client; i++) {
1443 if (silc_string_compare(client->host, host))
1445 client = client->next;
1454 /* Returns server connection info from server configuartion by host
1457 SilcServerConfigSectionServerConnection *
1458 silc_server_config_find_server_conn(SilcServerConfig config,
1459 char *host, int port)
1462 SilcServerConfigSectionServerConnection *serv = NULL;
1467 if (!config->servers)
1470 serv = config->servers;
1471 for (i = 0; serv; i++) {
1472 if (silc_string_compare(serv->host, host))
1483 /* Returns router connection info from server configuartion by
1484 host (name or ip). */
1486 SilcServerConfigSectionServerConnection *
1487 silc_server_config_find_router_conn(SilcServerConfig config,
1488 char *host, int port)
1491 SilcServerConfigSectionServerConnection *serv = NULL;
1496 if (!config->routers)
1499 serv = config->routers;
1500 for (i = 0; serv; i++) {
1501 if (silc_string_compare(serv->host, host))
1512 /* Returns Admin connection configuration by host, username and/or
1515 SilcServerConfigSectionAdminConnection *
1516 silc_server_config_find_admin(SilcServerConfig config,
1517 char *host, char *username, char *nickname)
1519 SilcServerConfigSectionAdminConnection *admin = NULL;
1522 if (!config->admins)
1532 admin = config->admins;
1533 for (i = 0; admin; i++) {
1534 if (silc_string_compare(admin->host, host) &&
1535 silc_string_compare(admin->username, username) &&
1536 silc_string_compare(admin->nickname, nickname))
1539 admin = admin->next;