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 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
665 config->filename, pc->linenum, config->logging->logtype);
669 /* Get log filename */
670 ret = silc_config_get_token(line, &config->logging->filename);
674 fprintf(stderr, "%s:%d: Log file name not defined\n",
675 config->filename, pc->linenum);
679 /* Get max byte size */
680 ret = silc_config_get_token(line, &tmp);
684 config->logging->maxsize = atoi(tmp);
689 checkmask |= (1L << pc->section->type);
692 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
694 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
697 ret = silc_config_get_token(line, &config->clients->host);
702 config->clients->host = strdup("*");
704 /* Get authentication method */
705 ret = silc_config_get_token(line, &tmp);
709 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
710 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
711 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
712 config->filename, pc->linenum, tmp);
716 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
717 config->clients->auth_meth = SILC_AUTH_PASSWORD;
719 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
720 config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
725 /* Get authentication data */
726 ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
730 if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
731 config->clients->auth_data_len = strlen(config->clients->auth_data);
732 } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
733 /* Get the public key */
734 SilcPublicKey public_key;
736 if (!silc_pkcs_load_public_key(config->clients->auth_data,
737 &public_key, SILC_PKCS_FILE_PEM))
738 if (!silc_pkcs_load_public_key(config->clients->auth_data,
739 &public_key, SILC_PKCS_FILE_BIN)) {
740 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
741 config->filename, pc->linenum,
742 (char *)config->clients->auth_data);
746 silc_free(config->clients->auth_data);
747 config->clients->auth_data = (void *)public_key;
748 config->clients->auth_data_len = 0;
752 ret = silc_config_get_token(line, &tmp);
756 config->clients->port = atoi(tmp);
760 /* Get class number */
761 ret = silc_config_get_token(line, &tmp);
765 config->clients->class = atoi(tmp);
770 checkmask |= (1L << pc->section->type);
773 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
775 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
778 ret = silc_config_get_token(line, &config->servers->host);
783 config->servers->host = strdup("*");
785 /* Get authentication method */
786 ret = silc_config_get_token(line, &tmp);
790 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
791 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
792 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
793 config->filename, pc->linenum, tmp);
797 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
798 config->servers->auth_meth = SILC_AUTH_PASSWORD;
800 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
801 config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
806 /* Get authentication data */
807 ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
811 if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
812 config->servers->auth_data_len = strlen(config->servers->auth_data);
813 } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
814 /* Get the public key */
815 SilcPublicKey public_key;
817 if (!silc_pkcs_load_public_key(config->servers->auth_data,
818 &public_key, SILC_PKCS_FILE_PEM))
819 if (!silc_pkcs_load_public_key(config->servers->auth_data,
820 &public_key, SILC_PKCS_FILE_BIN)) {
821 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
822 config->filename, pc->linenum,
823 (char *)config->servers->auth_data);
827 silc_free(config->servers->auth_data);
828 config->servers->auth_data = (void *)public_key;
829 config->servers->auth_data_len = 0;
833 ret = silc_config_get_token(line, &tmp);
837 config->servers->port = atoi(tmp);
842 ret = silc_config_get_token(line, &config->servers->version);
846 /* Get class number */
847 ret = silc_config_get_token(line, &tmp);
851 config->servers->class = atoi(tmp);
855 /* Check whether this connection is backup router connection */
856 ret = silc_config_get_token(line, &tmp);
858 config->servers->backup_router = atoi(tmp);
859 if (config->servers->backup_router != 0)
860 config->servers->backup_router = TRUE;
865 checkmask |= (1L << pc->section->type);
868 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
870 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
873 ret = silc_config_get_token(line, &config->routers->host);
877 /* Get authentication method */
878 ret = silc_config_get_token(line, &tmp);
882 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
883 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
884 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
885 config->filename, pc->linenum, tmp);
889 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
890 config->routers->auth_meth = SILC_AUTH_PASSWORD;
892 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
893 config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
898 /* Get authentication data */
899 ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
903 if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
904 config->routers->auth_data_len = strlen(config->routers->auth_data);
905 } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
906 /* Get the public key */
907 SilcPublicKey public_key;
909 if (!silc_pkcs_load_public_key(config->routers->auth_data,
910 &public_key, SILC_PKCS_FILE_PEM))
911 if (!silc_pkcs_load_public_key(config->routers->auth_data,
912 &public_key, SILC_PKCS_FILE_BIN)) {
913 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
914 config->filename, pc->linenum,
915 (char *)config->routers->auth_data);
919 silc_free(config->routers->auth_data);
920 config->routers->auth_data = (void *)public_key;
921 config->routers->auth_data_len = 0;
925 ret = silc_config_get_token(line, &tmp);
929 config->routers->port = atoi(tmp);
934 ret = silc_config_get_token(line, &config->routers->version);
938 /* Get class number */
939 ret = silc_config_get_token(line, &tmp);
943 config->routers->class = atoi(tmp);
947 /* Get whether we are initiator or not */
948 ret = silc_config_get_token(line, &tmp);
952 config->routers->initiator = atoi(tmp);
953 if (config->routers->initiator != 0)
954 config->routers->initiator = TRUE;
958 /* Get backup replace IP */
959 ret = silc_config_get_token(line, &config->routers->backup_replace_ip);
961 config->routers->backup_router = TRUE;
963 if (config->routers->backup_router) {
964 /* Get backup replace port */
965 ret = silc_config_get_token(line, &tmp);
967 config->routers->backup_replace_port = atoi(tmp);
971 /* Check whether the backup connection is local */
972 ret = silc_config_get_token(line, &tmp);
974 config->routers->backup_local = atoi(tmp);
975 if (config->routers->backup_local != 0)
976 config->routers->backup_local = TRUE;
982 checkmask |= (1L << pc->section->type);
985 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
987 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
990 ret = silc_config_get_token(line, &config->admins->host);
995 config->admins->host = strdup("*");
998 ret = silc_config_get_token(line, &config->admins->username);
1003 config->admins->username = strdup("*");
1006 ret = silc_config_get_token(line, &config->admins->nickname);
1011 config->admins->nickname = strdup("*");
1013 /* Get authentication method */
1014 ret = silc_config_get_token(line, &tmp);
1018 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
1019 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
1020 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
1021 config->filename, pc->linenum, tmp);
1025 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
1026 config->admins->auth_meth = SILC_AUTH_PASSWORD;
1028 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
1029 config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
1034 /* Get authentication data */
1035 ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
1039 if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
1040 config->admins->auth_data_len = strlen(config->admins->auth_data);
1041 } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
1042 /* Get the public key */
1043 SilcPublicKey public_key;
1045 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1046 &public_key, SILC_PKCS_FILE_PEM))
1047 if (!silc_pkcs_load_public_key(config->admins->auth_data,
1048 &public_key, SILC_PKCS_FILE_BIN)) {
1049 fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
1050 config->filename, pc->linenum,
1051 (char *)config->admins->auth_data);
1055 silc_free(config->admins->auth_data);
1056 config->admins->auth_data = (void *)public_key;
1057 config->admins->auth_data_len = 0;
1061 checkmask |= (1L << pc->section->type);
1064 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
1066 SILC_SERVER_CONFIG_LIST_ALLOC(config->denied);
1069 ret = silc_config_get_token(line, &config->denied->host);
1074 config->denied->host = strdup("*");
1075 fprintf(stderr, "warning: %s:%d: Denying all connections",
1076 config->filename, pc->linenum);
1080 ret = silc_config_get_token(line, &tmp);
1085 config->denied->port = 0;
1087 config->denied->port = atoi(tmp);
1092 ret = silc_config_get_token(line, &config->denied->comment);
1097 checkmask |= (1L << pc->section->type);
1100 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1103 config->motd = silc_calloc(1, sizeof(*config->motd));
1106 ret = silc_config_get_token(line, &config->motd->motd_file);
1111 checkmask |= (1L << pc->section->type);
1114 case SILC_CONFIG_SERVER_SECTION_TYPE_PID:
1116 if (!config->pidfile)
1117 config->pidfile = silc_calloc(1, sizeof(*config->pidfile));
1119 ret = silc_config_get_token(line, &config->pidfile->pid_file);
1124 checkmask |= (1L << pc->section->type);
1127 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1133 /* Check for error */
1134 if (check == FALSE) {
1135 /* Line could not be parsed */
1136 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1146 /* Check that all mandatory sections really were found. If not, the server
1147 cannot function and we return error. */
1148 ret = silc_server_config_check_sections(checkmask);
1154 /* Before returning all the lists in the config object must be set
1155 to their first values (the last value is first here). */
1156 while (config->cipher && config->cipher->prev)
1157 config->cipher = config->cipher->prev;
1158 while (config->pkcs && config->pkcs->prev)
1159 config->pkcs = config->pkcs->prev;
1160 while (config->hash_func && config->hash_func->prev)
1161 config->hash_func = config->hash_func->prev;
1162 while (config->hmac && config->hmac->prev)
1163 config->hmac = config->hmac->prev;
1164 while (config->listen_port && config->listen_port->prev)
1165 config->listen_port = config->listen_port->prev;
1166 while (config->logging && config->logging->prev)
1167 config->logging = config->logging->prev;
1168 while (config->conn_class && config->conn_class->prev)
1169 config->conn_class = config->conn_class->prev;
1170 while (config->clients && config->clients->prev)
1171 config->clients = config->clients->prev;
1172 while (config->servers && config->servers->prev)
1173 config->servers = config->servers->prev;
1174 while (config->admins && config->admins->prev)
1175 config->admins = config->admins->prev;
1176 while (config->routers && config->routers->prev)
1177 config->routers = config->routers->prev;
1179 SILC_LOG_DEBUG(("Done"));
1184 /* This function checks that the mask sent as argument includes all the
1185 sections that are mandatory in SILC server. */
1187 int silc_server_config_check_sections(uint32 checkmask)
1189 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1193 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1197 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1202 (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1207 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1212 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1220 /* Sets log files where log messages is saved by the server. */
1222 void silc_server_config_setlogfiles(SilcServerConfig config, SilcSchedule sked)
1224 SilcServerConfigSectionLogging *log;
1226 SILC_LOG_DEBUG(("Setting configured log file names"));
1227 log = config->logging;
1229 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO))
1230 silc_log_set_file(SILC_LOG_INFO, log->filename, log->maxsize, sked);
1231 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING))
1232 silc_log_set_file(SILC_LOG_WARNING, log->filename, log->maxsize, sked);
1233 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR))
1234 silc_log_set_file(SILC_LOG_ERROR, log->filename, log->maxsize, sked);
1235 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL))
1236 silc_log_set_file(SILC_LOG_FATAL, log->filename, log->maxsize, sked);
1242 /* Registers configured ciphers. These can then be allocated by the
1243 server when needed. */
1245 bool silc_server_config_register_ciphers(SilcServerConfig config)
1247 SilcServerConfigSectionAlg *alg;
1248 SilcServer server = (SilcServer)config->server;
1250 SILC_LOG_DEBUG(("Registering configured ciphers"));
1252 if (!config->cipher)
1255 alg = config->cipher;
1258 if (!alg->sim_name) {
1261 for (i = 0; silc_default_ciphers[i].name; i++)
1262 if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
1263 silc_cipher_register(&silc_default_ciphers[i]);
1267 if (!silc_cipher_is_supported(alg->alg_name)) {
1268 SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
1269 silc_server_stop(server);
1274 /* Load (try at least) the crypto SIM module */
1275 SilcCipherObject cipher;
1276 SilcSimContext *sim;
1279 memset(&cipher, 0, sizeof(cipher));
1280 cipher.name = alg->alg_name;
1281 cipher.block_len = alg->block_len;
1282 cipher.key_len = alg->key_len * 8;
1284 sim = silc_sim_alloc();
1285 sim->type = SILC_SIM_CIPHER;
1286 sim->libname = alg->sim_name;
1288 alg_name = strdup(alg->alg_name);
1289 if (strchr(alg_name, '-'))
1290 *strchr(alg_name, '-') = '\0';
1292 if ((silc_sim_load(sim))) {
1294 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1295 SILC_CIPHER_SIM_SET_KEY));
1296 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1297 cipher.set_key_with_string =
1298 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1299 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1300 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1302 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1303 SILC_CIPHER_SIM_ENCRYPT_CBC));
1304 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1306 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1307 SILC_CIPHER_SIM_DECRYPT_CBC));
1308 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1309 cipher.context_len =
1310 silc_sim_getsym(sim, silc_sim_symname(alg_name,
1311 SILC_CIPHER_SIM_CONTEXT_LEN));
1312 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1314 /* Put the SIM to the list of all SIM's in server */
1315 silc_dlist_add(server->sim, sim);
1317 silc_free(alg_name);
1319 SILC_LOG_ERROR(("Error configuring ciphers"));
1320 silc_server_stop(server);
1324 /* Register the cipher */
1325 silc_cipher_register(&cipher);
1335 /* Registers configured PKCS's. */
1337 bool silc_server_config_register_pkcs(SilcServerConfig config)
1339 SilcServerConfigSectionAlg *alg = config->pkcs;
1340 SilcServer server = (SilcServer)config->server;
1342 SILC_LOG_DEBUG(("Registering configured PKCS"));
1350 for (i = 0; silc_default_pkcs[i].name; i++)
1351 if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
1352 silc_pkcs_register(&silc_default_pkcs[i]);
1356 if (!silc_pkcs_is_supported(alg->alg_name)) {
1357 SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
1358 silc_server_stop(server);
1368 /* Registers configured hash functions. These can then be allocated by the
1369 server when needed. */
1371 bool silc_server_config_register_hashfuncs(SilcServerConfig config)
1373 SilcServerConfigSectionAlg *alg;
1374 SilcServer server = (SilcServer)config->server;
1376 SILC_LOG_DEBUG(("Registering configured hash functions"));
1378 if (!config->hash_func)
1381 alg = config->hash_func;
1384 if (!alg->sim_name) {
1387 for (i = 0; silc_default_hash[i].name; i++)
1388 if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
1389 silc_hash_register(&silc_default_hash[i]);
1393 if (!silc_hash_is_supported(alg->alg_name)) {
1394 SILC_LOG_ERROR(("Unknown hash funtion `%s'", alg->alg_name));
1395 silc_server_stop(server);
1401 /* Load (try at least) the hash SIM module */
1402 SilcHashObject hash;
1403 SilcSimContext *sim;
1405 memset(&hash, 0, sizeof(hash));
1406 hash.name = alg->alg_name;
1407 hash.block_len = alg->block_len;
1408 hash.hash_len = alg->key_len;
1410 sim = silc_sim_alloc();
1411 sim->type = SILC_SIM_HASH;
1412 sim->libname = alg->sim_name;
1414 if ((silc_sim_load(sim))) {
1416 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1417 SILC_HASH_SIM_INIT));
1418 SILC_LOG_DEBUG(("init=%p", hash.init));
1420 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1421 SILC_HASH_SIM_UPDATE));
1422 SILC_LOG_DEBUG(("update=%p", hash.update));
1424 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1425 SILC_HASH_SIM_FINAL));
1426 SILC_LOG_DEBUG(("final=%p", hash.final));
1428 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1429 SILC_HASH_SIM_CONTEXT_LEN));
1430 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1432 /* Put the SIM to the table of all SIM's in server */
1433 silc_dlist_add(server->sim, sim);
1435 SILC_LOG_ERROR(("Error configuring hash functions"));
1436 silc_server_stop(server);
1440 /* Register the hash function */
1441 silc_hash_register(&hash);
1451 /* Registers configure HMACs. These can then be allocated by the server
1454 bool silc_server_config_register_hmacs(SilcServerConfig config)
1456 SilcServerConfigSectionAlg *alg;
1457 SilcServer server = (SilcServer)config->server;
1459 SILC_LOG_DEBUG(("Registering configured HMACs"));
1466 SilcHmacObject hmac;
1468 if (!silc_hash_is_supported(alg->sim_name)) {
1469 SILC_LOG_ERROR(("Unknown hash function `%s'", alg->sim_name));
1470 silc_server_stop(server);
1474 /* Register the HMAC */
1475 memset(&hmac, 0, sizeof(hmac));
1476 hmac.name = alg->alg_name;
1477 hmac.len = alg->key_len;
1478 silc_hmac_register(&hmac);
1486 /* Returns client authentication information from server configuration
1487 by host (name or ip). If `port' is non-null then both name or IP and
1488 the port must match. */
1490 SilcServerConfigSectionClientConnection *
1491 silc_server_config_find_client_conn(SilcServerConfig config,
1492 char *host, int port)
1495 SilcServerConfigSectionClientConnection *client = NULL;
1501 if (!config->clients)
1504 client = config->clients;
1506 for (i = 0; client; i++) {
1507 if (silc_string_compare(client->host, host))
1510 if (port && client->port && client->port != port)
1516 client = client->next;
1525 /* Returns server connection info from server configuartion by host
1526 (name or ip). If `port' is non-null then both name or IP and the port
1529 SilcServerConfigSectionServerConnection *
1530 silc_server_config_find_server_conn(SilcServerConfig config,
1531 char *host, int port)
1534 SilcServerConfigSectionServerConnection *serv = NULL;
1540 if (!config->servers)
1543 serv = config->servers;
1544 for (i = 0; serv; i++) {
1545 if (silc_string_compare(serv->host, host))
1548 if (port && serv->port && serv->port != port)
1563 /* Returns router connection info from server configuartion by
1564 host (name or ip). */
1566 SilcServerConfigSectionServerConnection *
1567 silc_server_config_find_router_conn(SilcServerConfig config,
1568 char *host, int port)
1571 SilcServerConfigSectionServerConnection *serv = NULL;
1577 if (!config->routers)
1580 serv = config->routers;
1581 for (i = 0; serv; i++) {
1582 if (silc_string_compare(serv->host, host))
1585 if (port && serv->port && serv->port != port)
1600 /* Returns TRUE if configuartion for a router connection that we are
1601 initiating exists. */
1603 bool silc_server_config_is_primary_route(SilcServerConfig config)
1606 SilcServerConfigSectionServerConnection *serv = NULL;
1609 serv = config->routers;
1610 for (i = 0; serv; i++) {
1611 if (serv->initiator == TRUE && serv->backup_router == FALSE) {
1622 /* Returns our primary connection configuration or NULL if we do not
1623 have primary router configured. */
1625 SilcServerConfigSectionServerConnection *
1626 silc_server_config_get_primary_router(SilcServerConfig config)
1629 SilcServerConfigSectionServerConnection *serv = NULL;
1631 serv = config->routers;
1632 for (i = 0; serv; i++) {
1633 if (serv->initiator == TRUE && serv->backup_router == FALSE)
1641 /* Returns Admin connection configuration by host, username and/or
1644 SilcServerConfigSectionAdminConnection *
1645 silc_server_config_find_admin(SilcServerConfig config,
1646 char *host, char *username, char *nickname)
1648 SilcServerConfigSectionAdminConnection *admin = NULL;
1651 if (!config->admins)
1661 admin = config->admins;
1662 for (i = 0; admin; i++) {
1663 if (silc_string_compare(admin->host, host) &&
1664 silc_string_compare(admin->username, username) &&
1665 silc_string_compare(admin->nickname, nickname))
1668 admin = admin->next;
1677 /* Returns the Denied connection configuration by host and port. */
1679 SilcServerConfigSectionDenyConnection *
1680 silc_server_config_denied_conn(SilcServerConfig config, char *host,
1684 SilcServerConfigSectionDenyConnection *deny = NULL;
1690 if (!config->denied)
1693 deny = config->denied;
1694 for (i = 0; deny; i++) {
1695 if (silc_string_compare(deny->host, host))
1698 if (port && deny->port && deny->port != port)