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, 1 },
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 SILC_CONFIG_SERVER_SECTION_TYPE_PID, 1},
63 { NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
66 /* Allocates a new configuration object, opens configuration file and
67 parses the file. The parsed data is returned to the newly allocated
68 configuration object. */
70 SilcServerConfig silc_server_config_alloc(char *filename)
74 SilcServerConfigParse config_parse;
76 SILC_LOG_DEBUG(("Allocating new configuration object"));
78 new = silc_calloc(1, sizeof(*new));
80 fprintf(stderr, "Could not allocate new configuration object");
84 new->filename = filename;
86 SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
88 /* Open configuration file and parse it */
91 silc_config_open(filename, &buffer);
94 if ((silc_server_config_parse(new, buffer, &config_parse)) == FALSE)
96 if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
99 silc_buffer_free(buffer);
104 silc_buffer_free(buffer);
109 /* Free's a configuration object. */
111 void silc_server_config_free(SilcServerConfig config)
114 silc_free(config->filename);
115 silc_free(config->server_keys);
116 silc_free(config->server_info);
117 silc_free(config->admin_info);
118 silc_free(config->listen_port);
119 silc_free(config->identity);
120 silc_free(config->conn_class);
121 silc_free(config->clients);
122 silc_free(config->admins);
123 silc_free(config->servers);
124 silc_free(config->routers);
125 silc_free(config->denied);
126 silc_free(config->motd);
127 silc_free(config->pidfile);
132 /* Parses the the buffer and returns the parsed lines into return_config
133 argument. The return_config argument doesn't have to be initialized
134 before calling this. It will be initialized during the parsing. The
135 buffer sent as argument can be safely free'd after this function has
136 succesfully returned. */
138 int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
139 SilcServerConfigParse *return_config)
141 int i, begin, linenum;
142 char line[1024], *cp;
143 SilcServerConfigSection *cptr = NULL;
144 SilcServerConfigParse parse = *return_config, first = NULL;
146 SILC_LOG_DEBUG(("Parsing configuration file"));
150 while((begin = silc_gets(line, sizeof(line),
151 buffer->data, buffer->len, begin)) != EOF) {
155 /* Check for bad line */
156 if (silc_check_line(cp))
159 /* Remove tabs and whitespaces from the line */
160 if (strchr(cp, '\t')) {
162 while(strchr(cp + i, '\t')) {
163 *strchr(cp + i, '\t') = ' ';
167 for (i = 0; i < strlen(cp); i++) {
183 /* Remove new line sign */
184 if (strchr(cp, '\n'))
185 *strchr(cp, '\n') = '\0';
187 /* Check for matching sections */
188 for (cptr = silc_server_config_sections; cptr->section; cptr++)
189 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
192 if (!cptr->section) {
193 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
194 config->filename, linenum, cp);
201 * Start of a configuration line
204 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
206 if (strchr(cp, '\n'))
207 *strchr(cp, '\n') = ':';
210 parse = silc_calloc(1, sizeof(*parse));
212 parse->section = NULL;
216 if (parse->next == NULL) {
217 parse->next = silc_calloc(1, sizeof(*parse->next));
218 parse->next->line = NULL;
219 parse->next->section = NULL;
220 parse->next->next = NULL;
221 parse->next->prev = parse;
229 /* Add the line to parsing structure for further parsing. */
231 parse->section = cptr;
232 parse->line = silc_buffer_alloc(strlen(cp) + 1);
233 parse->linenum = linenum;
234 silc_buffer_pull_tail(parse->line, strlen(cp));
235 silc_buffer_put(parse->line, cp, strlen(cp));
242 /* Set the return_config argument to its first value so that further
243 parsing can be started from the first line. */
244 *return_config = first;
249 /* Parses the lines earlier read from configuration file. The config object
250 must not be initialized, it will be initialized in this function. The
251 parse_config argument is uninitialized automatically during this
254 int silc_server_config_parse_lines(SilcServerConfig config,
255 SilcServerConfigParse parse_config)
257 int ret, check = FALSE;
260 SilcServerConfigParse pc = parse_config;
263 SILC_LOG_DEBUG(("Parsing configuration lines"));
273 /* Get number of tokens in line */
274 ret = silc_config_check_num_token(line);
275 if (ret < pc->section->maxfields) {
277 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
278 config->filename, pc->linenum, ret,
279 pc->section->maxfields);
284 switch(pc->section->type) {
285 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
287 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
289 /* Get cipher name */
290 ret = silc_config_get_token(line, &config->cipher->alg_name);
294 fprintf(stderr, "%s:%d: Cipher name not defined\n",
295 config->filename, pc->linenum);
299 /* Get module name */
300 config->cipher->sim_name = NULL;
301 ret = silc_config_get_token(line, &config->cipher->sim_name);
306 ret = silc_config_get_token(line, &tmp);
310 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
311 config->filename, pc->linenum);
314 config->cipher->key_len = atoi(tmp);
317 /* Get block length */
318 ret = silc_config_get_token(line, &tmp);
322 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
323 config->filename, pc->linenum);
326 config->cipher->block_len = atoi(tmp);
330 checkmask |= (1L << pc->section->type);
333 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
335 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
338 ret = silc_config_get_token(line, &config->pkcs->alg_name);
342 fprintf(stderr, "%s:%d: PKCS name not defined\n",
343 config->filename, pc->linenum);
348 checkmask |= (1L << pc->section->type);
351 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
353 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
355 /* Get Hash function name */
356 ret = silc_config_get_token(line, &config->hash_func->alg_name);
360 fprintf(stderr, "%s:%d: Hash function name not defined\n",
361 config->filename, pc->linenum);
365 /* Get Hash function module name */
366 config->hash_func->sim_name = NULL;
367 ret = silc_config_get_token(line, &config->hash_func->sim_name);
371 /* Get block length */
372 ret = silc_config_get_token(line, &tmp);
376 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
377 config->filename, pc->linenum);
380 config->hash_func->block_len = atoi(tmp);
383 /* Get hash length */
384 ret = silc_config_get_token(line, &tmp);
388 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
389 config->filename, pc->linenum);
392 config->hash_func->key_len = atoi(tmp);
396 checkmask |= (1L << pc->section->type);
399 case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
401 SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
404 ret = silc_config_get_token(line, &config->hmac->alg_name);
408 fprintf(stderr, "%s:%d: HMAC name not defined\n",
409 config->filename, pc->linenum);
414 ret = silc_config_get_token(line, &config->hmac->sim_name);
418 fprintf(stderr, "%s:%d: Hash function name not defined\n",
419 config->filename, pc->linenum);
424 ret = silc_config_get_token(line, &tmp);
428 fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
429 config->filename, pc->linenum);
432 config->hmac->key_len = atoi(tmp);
436 checkmask |= (1L << pc->section->type);
439 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS:
441 if (!config->server_keys)
442 config->server_keys = silc_calloc(1, sizeof(*config->server_keys));
444 ret = silc_config_get_token(line, &tmp);
448 fprintf(stderr, "%s:%d: Public key name not defined\n",
449 config->filename, pc->linenum);
453 if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
455 if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
456 SILC_PKCS_FILE_BIN)) {
457 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
458 config->filename, pc->linenum, tmp);
463 ret = silc_config_get_token(line, &tmp);
467 fprintf(stderr, "%s:%d: Private key name not defined\n",
468 config->filename, pc->linenum);
472 if (!silc_pkcs_load_private_key(tmp, &config->server_keys->private_key,
474 if (!silc_pkcs_load_private_key(tmp,
475 &config->server_keys->private_key,
476 SILC_PKCS_FILE_PEM)) {
477 fprintf(stderr, "%s:%d: Could not load private key file `%s'\n",
478 config->filename, pc->linenum, tmp);
484 checkmask |= (1L << pc->section->type);
487 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
489 if (!config->server_info)
490 config->server_info = silc_calloc(1, sizeof(*config->server_info));
492 /* Get server name */
493 ret = silc_config_get_token(line, &config->server_info->server_name);
497 /* Server name not defined */
502 ret = silc_config_get_token(line, &config->server_info->server_ip);
506 /* Server IP not defined */
510 /* Get server location */
511 ret = silc_config_get_token(line, &config->server_info->location);
515 /* Get server port */
516 /* XXX: Need port here??? */
517 ret = silc_config_get_token(line, &tmp);
521 /* Port not defined */
524 config->server_info->port = atoi(tmp);
528 checkmask |= (1L << pc->section->type);
531 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
533 if (!config->admin_info)
534 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
537 ret = silc_config_get_token(line, &config->admin_info->location);
541 /* Get server type */
542 ret = silc_config_get_token(line, &config->admin_info->server_type);
546 /* Get admins name */
547 ret = silc_config_get_token(line, &config->admin_info->admin_name);
551 /* Get admins email address */
552 ret = silc_config_get_token(line, &config->admin_info->admin_email);
557 checkmask |= (1L << pc->section->type);
560 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
562 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
565 ret = silc_config_get_token(line, &config->listen_port->local_ip);
569 /* Get listener IP */
570 ret = silc_config_get_token(line, &config->listen_port->listener_ip);
575 ret = silc_config_get_token(line, &tmp);
580 config->listen_port->port = 0;
582 config->listen_port->port = atoi(tmp);
587 checkmask |= (1L << pc->section->type);
590 case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
592 if (!config->identity)
593 config->identity = silc_calloc(1, sizeof(*config->identity));
596 ret = silc_config_get_token(line, &config->identity->user);
600 ret = silc_config_get_token(line, &config->identity->group);
605 checkmask |= (1L << pc->section->type);
607 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
609 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
611 /* Get class number */
612 ret = silc_config_get_token(line, &tmp);
616 /* Class number not defined */
619 config->conn_class->class = atoi(tmp);
622 /* Get ping frequency */
623 ret = silc_config_get_token(line, &tmp);
626 config->conn_class->ping_freq = atoi(tmp);
629 /* Get connect frequency */
630 ret = silc_config_get_token(line, &tmp);
633 config->conn_class->connect_freq = atoi(tmp);
637 ret = silc_config_get_token(line, &tmp);
640 config->conn_class->max_links = atoi(tmp);
644 checkmask |= (1L << pc->section->type);
647 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
649 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
651 /* Get log section type and check it */
652 ret = silc_config_get_token(line, &config->logging->logtype);
656 fprintf(stderr, "%s:%d: Log file section not defined\n",
657 config->filename, pc->linenum);
660 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
661 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
662 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
663 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)
664 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_QUICK)
665 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) {
666 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
667 config->filename, pc->linenum, config->logging->logtype);
671 /* Get log filename */
672 ret = silc_config_get_token(line, &config->logging->filename);
676 fprintf(stderr, "%s:%d: Log file name not defined\n",
677 config->filename, pc->linenum);
681 /* Get max byte size */
682 ret = silc_config_get_token(line, &tmp);
686 config->logging->maxsize = atoi(tmp);
691 checkmask |= (1L << pc->section->type);
694 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
696 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
699 ret = silc_config_get_token(line, &config->clients->host);
704 config->clients->host = strdup("*");
706 /* Get authentication method */
707 ret = silc_config_get_token(line, &tmp);
711 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
712 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
713 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
714 config->filename, pc->linenum, tmp);
718 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
719 config->clients->auth_meth = SILC_AUTH_PASSWORD;
721 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
722 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
727 /* Get authentication data */
728 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
732 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
733 config->clients->auth_data_len = strlen(config->clients->auth_data);
734 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
735 /* Get the public key */
736 SilcPublicKey public_key;
738 if (!silc_pkcs_load_public_key(config->clients->auth_data,
739 &public_key, SILC_PKCS_FILE_PEM))
740 if (!silc_pkcs_load_public_key(config->clients->auth_data,
741 &public_key, SILC_PKCS_FILE_BIN)) {
742 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
743 config->filename, pc->linenum,
744 (char *)config->clients->auth_data);
748 silc_free(config->clients->auth_data);
749 config->clients->auth_data = (void *)public_key;
750 config->clients->auth_data_len = 0;
754 ret = silc_config_get_token(line, &tmp);
758 config->clients->port = atoi(tmp);
762 /* Get class number */
763 ret = silc_config_get_token(line, &tmp);
767 config->clients->class = atoi(tmp);
772 checkmask |= (1L << pc->section->type);
775 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
777 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
780 ret = silc_config_get_token(line, &config->servers->host);
785 config->servers->host = strdup("*");
787 /* Get authentication method */
788 ret = silc_config_get_token(line, &tmp);
792 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
793 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
794 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
795 config->filename, pc->linenum, tmp);
799 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
800 config->servers->auth_meth = SILC_AUTH_PASSWORD;
802 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
803 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
808 /* Get authentication data */
809 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
813 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
814 config->servers->auth_data_len = strlen(config->servers->auth_data);
815 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
816 /* Get the public key */
817 SilcPublicKey public_key;
819 if (!silc_pkcs_load_public_key(config->servers->auth_data,
820 &public_key, SILC_PKCS_FILE_PEM))
821 if (!silc_pkcs_load_public_key(config->servers->auth_data,
822 &public_key, SILC_PKCS_FILE_BIN)) {
823 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
824 config->filename, pc->linenum,
825 (char *)config->servers->auth_data);
829 silc_free(config->servers->auth_data);
830 config->servers->auth_data = (void *)public_key;
831 config->servers->auth_data_len = 0;
835 ret = silc_config_get_token(line, &tmp);
839 config->servers->port = atoi(tmp);
844 ret = silc_config_get_token(line, &config->servers->version);
848 /* Get class number */
849 ret = silc_config_get_token(line, &tmp);
853 config->servers->class = atoi(tmp);
857 /* Check whether this connection is backup router connection */
858 ret = silc_config_get_token(line, &tmp);
860 config->servers->backup_router = atoi(tmp);
861 if (config->servers->backup_router != 0)
862 config->servers->backup_router = TRUE;
867 checkmask |= (1L << pc->section->type);
870 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
872 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
875 ret = silc_config_get_token(line, &config->routers->host);
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;
960 /* Get backup replace IP */
961 ret = silc_config_get_token(line, &config->routers->backup_replace_ip);
963 config->routers->backup_router = TRUE;
965 if (config->routers->backup_router) {
966 /* Get backup replace port */
967 ret = silc_config_get_token(line, &tmp);
969 config->routers->backup_replace_port = atoi(tmp);
973 /* Check whether the backup connection is local */
974 ret = silc_config_get_token(line, &tmp);
976 config->routers->backup_local = atoi(tmp);
977 if (config->routers->backup_local != 0)
978 config->routers->backup_local = TRUE;
984 checkmask |= (1L << pc->section->type);
987 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
989 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
992 ret = silc_config_get_token(line, &config->admins->host);
997 config->admins->host = strdup("*");
1000 ret = silc_config_get_token(line, &config->admins->username);
1005 config->admins->username = strdup("*");
1008 ret = silc_config_get_token(line, &config->admins->nickname);
1013 config->admins->nickname = strdup("*");
1015 /* Get authentication method */
1016 ret = silc_config_get_token(line, &tmp);
1020 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
1021 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
1022 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
1023 config->filename, pc->linenum, tmp);
1027 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
1028 config->admins->auth_meth = SILC_AUTH_PASSWORD;
1030 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
1031 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
1036 /* Get authentication data */
1037 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
1041 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
1042 config->admins->auth_data_len = strlen(config->admins->auth_data);
1043 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
1044 /* Get the public key */
1045 SilcPublicKey public_key;
1047 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1048 &public_key, SILC_PKCS_FILE_PEM))
1049 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1050 &public_key, SILC_PKCS_FILE_BIN)) {
1051 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
1052 config->filename, pc->linenum,
1053 (char *)config->admins->auth_data);
1057 silc_free(config->admins->auth_data);
1058 config->admins->auth_data = (void *)public_key;
1059 config->admins->auth_data_len = 0;
1063 checkmask |= (1L << pc->section->type);
1066 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
1068 SILC_SERVER_CONFIG_LIST_ALLOC(config->denied);
1071 ret = silc_config_get_token(line, &config->denied->host);
1076 config->denied->host = strdup("*");
1077 fprintf(stderr, "warning: %s:%d: Denying all connections",
1078 config->filename, pc->linenum);
1082 ret = silc_config_get_token(line, &tmp);
1087 config->denied->port = 0;
1089 config->denied->port = atoi(tmp);
1094 ret = silc_config_get_token(line, &config->denied->comment);
1099 checkmask |= (1L << pc->section->type);
1102 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1105 config->motd = silc_calloc(1, sizeof(*config->motd));
1108 ret = silc_config_get_token(line, &config->motd->motd_file);
1113 checkmask |= (1L << pc->section->type);
1116 case SILC_CONFIG_SERVER_SECTION_TYPE_PID:
1118 if (!config->pidfile)
1119 config->pidfile = silc_calloc(1, sizeof(*config->pidfile));
1121 ret = silc_config_get_token(line, &config->pidfile->pid_file);
1126 checkmask |= (1L << pc->section->type);
1129 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1135 /* Check for error */
1136 if (check == FALSE) {
1137 /* Line could not be parsed */
1138 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1148 /* Check that all mandatory sections really were found. If not, the server
1149 cannot function and we return error. */
1150 ret = silc_server_config_check_sections(checkmask);
1156 /* Before returning all the lists in the config object must be set
1157 to their first values (the last value is first here). */
1158 while (config->cipher && config->cipher->prev)
1159 config->cipher = config->cipher->prev;
1160 while (config->pkcs && config->pkcs->prev)
1161 config->pkcs = config->pkcs->prev;
1162 while (config->hash_func && config->hash_func->prev)
1163 config->hash_func = config->hash_func->prev;
1164 while (config->hmac && config->hmac->prev)
1165 config->hmac = config->hmac->prev;
1166 while (config->listen_port && config->listen_port->prev)
1167 config->listen_port = config->listen_port->prev;
1168 while (config->logging && config->logging->prev)
1169 config->logging = config->logging->prev;
1170 while (config->conn_class && config->conn_class->prev)
1171 config->conn_class = config->conn_class->prev;
1172 while (config->clients && config->clients->prev)
1173 config->clients = config->clients->prev;
1174 while (config->servers && config->servers->prev)
1175 config->servers = config->servers->prev;
1176 while (config->admins && config->admins->prev)
1177 config->admins = config->admins->prev;
1178 while (config->routers && config->routers->prev)
1179 config->routers = config->routers->prev;
1181 SILC_LOG_DEBUG(("Done"));
1186 /* This function checks that the mask sent as argument includes all the
1187 sections that are mandatory in SILC server. */
1189 int silc_server_config_check_sections(uint32 checkmask)
1191 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1195 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1199 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1204 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1209 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1214 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1222 /* Sets log files where log messages is saved by the server. */
1224 void silc_server_config_setlogfiles(SilcServerConfig config, SilcSchedule sked)
1227 SilcServerConfigSectionLogging *log;
1229 SILC_LOG_DEBUG(("Setting configured log file names"));
1230 log = config->logging;
1233 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO))
1234 silc_log_set_file(SILC_LOG_INFO, log->filename, log->maxsize, sked);
1235 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING))
1236 silc_log_set_file(SILC_LOG_WARNING, log->filename, log->maxsize, sked);
1237 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR))
1238 silc_log_set_file(SILC_LOG_ERROR, log->filename, log->maxsize, sked);
1239 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL))
1240 silc_log_set_file(SILC_LOG_FATAL, log->filename, log->maxsize, sked);
1241 /* Logging Options */
1242 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_QUICK)) {
1243 if (!strcasecmp(log->filename, "yes") ||
1244 !strcasecmp(log->filename, "on"))
1245 silc_log_quick = TRUE;
1247 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) {
1248 tmp = atol(log->filename);
1250 silc_log_flushdelay = tmp;
1252 fprintf(stderr, "config: invalid flushdelay value, use quicklogs if "
1253 "you want real-time logging.\n");
1262 /* Registers configured ciphers. These can then be allocated by the
1263 server when needed. */
1265 bool silc_server_config_register_ciphers(SilcServerConfig config)
1267 SilcServerConfigSectionAlg *alg;
1268 SilcServer server = (SilcServer)config->server;
1270 SILC_LOG_DEBUG(("Registering configured ciphers"));
1272 if (!config->cipher)
1275 alg = config->cipher;
1278 if (!alg->sim_name) {
1281 for (i = 0; silc_default_ciphers[i].name; i++)
1282 if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
1283 silc_cipher_register(&silc_default_ciphers[i]);
1287 if (!silc_cipher_is_supported(alg->alg_name)) {
1288 SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
1289 silc_server_stop(server);
1294 /* Load (try at least) the crypto SIM module */
1295 SilcCipherObject cipher;
1296 SilcSimContext *sim;
1299 memset(&cipher, 0, sizeof(cipher));
1300 cipher.name = alg->alg_name;
1301 cipher.block_len = alg->block_len;
1302 cipher.key_len = alg->key_len * 8;
1304 sim = silc_sim_alloc();
1305 sim->type = SILC_SIM_CIPHER;
1306 sim->libname = alg->sim_name;
1308 alg_name = strdup(alg->alg_name);
1309 if (strchr(alg_name, '-'))
1310 *strchr(alg_name, '-') = '\0';
1312 if ((silc_sim_load(sim))) {
1314 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1315 SILC_CIPHER_SIM_SET_KEY));
1316 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1317 cipher.set_key_with_string =
1318 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1319 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1320 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1322 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1323 SILC_CIPHER_SIM_ENCRYPT_CBC));
1324 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1326 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1327 SILC_CIPHER_SIM_DECRYPT_CBC));
1328 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1329 cipher.context_len =
1330 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1331 SILC_CIPHER_SIM_CONTEXT_LEN));
1332 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1334 /* Put the SIM to the list of all SIM's in server */
1335 silc_dlist_add(server->sim, sim);
1337 silc_free(alg_name);
1339 SILC_LOG_ERROR(("Error configuring ciphers"));
1340 silc_server_stop(server);
1344 /* Register the cipher */
1345 silc_cipher_register(&cipher);
1355 /* Registers configured PKCS's. */
1357 bool silc_server_config_register_pkcs(SilcServerConfig config)
1359 SilcServerConfigSectionAlg *alg = config->pkcs;
1360 SilcServer server = (SilcServer)config->server;
1362 SILC_LOG_DEBUG(("Registering configured PKCS"));
1370 for (i = 0; silc_default_pkcs[i].name; i++)
1371 if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
1372 silc_pkcs_register(&silc_default_pkcs[i]);
1376 if (!silc_pkcs_is_supported(alg->alg_name)) {
1377 SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
1378 silc_server_stop(server);
1388 /* Registers configured hash functions. These can then be allocated by the
1389 server when needed. */
1391 bool silc_server_config_register_hashfuncs(SilcServerConfig config)
1393 SilcServerConfigSectionAlg *alg;
1394 SilcServer server = (SilcServer)config->server;
1396 SILC_LOG_DEBUG(("Registering configured hash functions"));
1398 if (!config->hash_func)
1401 alg = config->hash_func;
1404 if (!alg->sim_name) {
1407 for (i = 0; silc_default_hash[i].name; i++)
1408 if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
1409 silc_hash_register(&silc_default_hash[i]);
1413 if (!silc_hash_is_supported(alg->alg_name)) {
1414 SILC_LOG_ERROR(("Unknown hash funtion `%s'", alg->alg_name));
1415 silc_server_stop(server);
1421 /* Load (try at least) the hash SIM module */
1422 SilcHashObject hash;
1423 SilcSimContext *sim;
1425 memset(&hash, 0, sizeof(hash));
1426 hash.name = alg->alg_name;
1427 hash.block_len = alg->block_len;
1428 hash.hash_len = alg->key_len;
1430 sim = silc_sim_alloc();
1431 sim->type = SILC_SIM_HASH;
1432 sim->libname = alg->sim_name;
1434 if ((silc_sim_load(sim))) {
1436 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1437 SILC_HASH_SIM_INIT));
1438 SILC_LOG_DEBUG(("init=%p", hash.init));
1440 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1441 SILC_HASH_SIM_UPDATE));
1442 SILC_LOG_DEBUG(("update=%p", hash.update));
1444 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1445 SILC_HASH_SIM_FINAL));
1446 SILC_LOG_DEBUG(("final=%p", hash.final));
1448 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1449 SILC_HASH_SIM_CONTEXT_LEN));
1450 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1452 /* Put the SIM to the table of all SIM's in server */
1453 silc_dlist_add(server->sim, sim);
1455 SILC_LOG_ERROR(("Error configuring hash functions"));
1456 silc_server_stop(server);
1460 /* Register the hash function */
1461 silc_hash_register(&hash);
1471 /* Registers configure HMACs. These can then be allocated by the server
1474 bool silc_server_config_register_hmacs(SilcServerConfig config)
1476 SilcServerConfigSectionAlg *alg;
1477 SilcServer server = (SilcServer)config->server;
1479 SILC_LOG_DEBUG(("Registering configured HMACs"));
1486 SilcHmacObject hmac;
1488 if (!silc_hash_is_supported(alg->sim_name)) {
1489 SILC_LOG_ERROR(("Unknown hash function `%s'", alg->sim_name));
1490 silc_server_stop(server);
1494 /* Register the HMAC */
1495 memset(&hmac, 0, sizeof(hmac));
1496 hmac.name = alg->alg_name;
1497 hmac.len = alg->key_len;
1498 silc_hmac_register(&hmac);
1506 /* Returns client authentication information from server configuration
1507 by host (name or ip). If `port' is non-null then both name or IP and
1508 the port must match. */
1510 SilcServerConfigSectionClientConnection *
1511 silc_server_config_find_client_conn(SilcServerConfig config,
1512 char *host, int port)
1515 SilcServerConfigSectionClientConnection *client = NULL;
1521 if (!config->clients)
1524 client = config->clients;
1526 for (i = 0; client; i++) {
1527 if (silc_string_compare(client->host, host))
1530 if (port && client->port && client->port != port)
1536 client = client->next;
1545 /* Returns server connection info from server configuartion by host
1546 (name or ip). If `port' is non-null then both name or IP and the port
1549 SilcServerConfigSectionServerConnection *
1550 silc_server_config_find_server_conn(SilcServerConfig config,
1551 char *host, int port)
1554 SilcServerConfigSectionServerConnection *serv = NULL;
1560 if (!config->servers)
1563 serv = config->servers;
1564 for (i = 0; serv; i++) {
1565 if (silc_string_compare(serv->host, host))
1568 if (port && serv->port && serv->port != port)
1583 /* Returns router connection info from server configuartion by
1584 host (name or ip). */
1586 SilcServerConfigSectionServerConnection *
1587 silc_server_config_find_router_conn(SilcServerConfig config,
1588 char *host, int port)
1591 SilcServerConfigSectionServerConnection *serv = NULL;
1597 if (!config->routers)
1600 serv = config->routers;
1601 for (i = 0; serv; i++) {
1602 if (silc_string_compare(serv->host, host))
1605 if (port && serv->port && serv->port != port)
1620 /* Returns TRUE if configuartion for a router connection that we are
1621 initiating exists. */
1623 bool silc_server_config_is_primary_route(SilcServerConfig config)
1626 SilcServerConfigSectionServerConnection *serv = NULL;
1629 serv = config->routers;
1630 for (i = 0; serv; i++) {
1631 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1642 /* Returns our primary connection configuration or NULL if we do not
1643 have primary router configured. */
1645 SilcServerConfigSectionServerConnection *
1646 silc_server_config_get_primary_router(SilcServerConfig config)
1649 SilcServerConfigSectionServerConnection *serv = NULL;
1651 serv = config->routers;
1652 for (i = 0; serv; i++) {
1653 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1661 /* Returns Admin connection configuration by host, username and/or
1664 SilcServerConfigSectionAdminConnection *
1665 silc_server_config_find_admin(SilcServerConfig config,
1666 char *host, char *username, char *nickname)
1668 SilcServerConfigSectionAdminConnection *admin = NULL;
1671 if (!config->admins)
1681 admin = config->admins;
1682 for (i = 0; admin; i++) {
1683 if (silc_string_compare(admin->host, host) &&
1684 silc_string_compare(admin->username, username) &&
1685 silc_string_compare(admin->nickname, nickname))
1688 admin = admin->next;
1697 /* Returns the Denied connection configuration by host and port. */
1699 SilcServerConfigSectionDenyConnection *
1700 silc_server_config_denied_conn(SilcServerConfig config, char *host,
1704 SilcServerConfigSectionDenyConnection *deny = NULL;
1710 if (!config->denied)
1713 deny = config->denied;
1714 for (i = 0; deny; i++) {
1715 if (silc_string_compare(deny->host, host))
1718 if (port && deny->port && deny->port != port)