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.
23 * Revision 1.5 2000/11/02 22:15:23 priikone
25 * Changed server->sim to SilcDList and code accordingly.
26 * Changes SilcClientEntry->channel to SilcList and added
27 * back-pointer to SilcChannelClientEntry which is now used by both
28 * client entry and channel entry
30 * Revision 1.4 2000/10/06 08:10:23 priikone
31 * Added WHOIS to send multiple replies if multiple nicknames are
33 * Added MOTD command and [motd] config section and server also sends
34 * motd to client on connection now.
35 * Fixed TOPIC command some more.
37 * Revision 1.3 2000/07/10 05:41:20 priikone
38 * Added missing token to administrative information.
40 * Revision 1.2 2000/07/05 06:14:01 priikone
41 * Global costemic changes.
43 * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
44 * Imported from internal CVS/Added Log headers.
49 #include "serverincludes.h"
50 #include "server_internal.h"
53 All possible configuration sections for SILC server.
59 +<Cipher name>:<SIM path>
65 +<PKCS name>:<key length>
71 +<Hash function name>:<SIM path>
75 This section is used to set the server informations.
79 +<Server DNS name>:<Server IP>:<Geographic location>:<Port>
83 This section is used to set the server's administrative information.
87 +<Location>:<Server type>:<Admin's name>:<Admin's email address>
91 This section is used to set ports the server is listenning.
95 +<Local IP/UNIX socket path>:<Remote IP>:<Port>
99 This section is used to set various logging files, their paths
100 and maximum sizes. All the other directives except those defined
101 below are ignored in this section. Log files are purged after they
102 reach the maximum set byte size.
106 +infologfile:<path>:<max byte size>
107 +errorlogfile:<path>:<max byte size>
111 This section is used to define connection classes. These can be
112 used to optimize the server and the connections.
116 +<Class number>:<Ping freq>:<Connect freq>:<Max links>
120 This section is used to define client authentications.
124 +<Remote address or name>:<auth method>:<password/cert/key/???>:<Port>:<Class>
128 This section is used to define the server's administration
133 +<Hostname>:<auth method>:<password/cert/key/???>:<Nickname hash>:<Class>
137 This section is used to define the server connections to this
138 server/router. Only routers can have normal server connections.
139 Normal servers leave this section epmty. The remote server cannot be
140 older than specified Version ID.
144 +<Remote address or name>:<auth method>:<password/key/???>:<Port>:<Version ID>:<Class>
148 This section is used to define the router connections to this
149 server/router. Both normal server and router can have router
150 connections. Normal server usually has only one connection while
151 a router can have multiple. The remote server cannot be older than
152 specified Version ID.
156 +<Remote address or name>:<auth method>:<password/key/???>:<Port>:<Version ID>:<Class>
160 This section is used to deny specific connections to your server. This
161 can be used to deny both clients and servers.
165 +<Remote address or name or nickname>:<Time interval>:<Comment>:<Port>
169 This section is used to set the alternate servers that clients will be
170 redirected to when our server is full.
174 +<Remote address or name>:<Port>
177 SilcConfigServerSection silc_config_server_sections[] = {
179 SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 },
181 SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 2 },
183 SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 },
185 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 },
187 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 },
189 SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 },
191 SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 },
192 { "[ConnectionClass]",
193 SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 },
194 { "[ClientConnection]",
195 SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION, 5 },
196 { "[ServerConnection]",
197 SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION, 6 },
198 { "[RouterConnection]",
199 SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION, 6 },
200 { "[AdminConnection]",
201 SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 },
202 { "[DenyConnection]",
203 SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 4 },
204 { "[RedirectClient]",
205 SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT, 2 },
207 SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
209 { NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
212 /* Allocates a new configuration object, opens configuration file and
213 parses the file. The parsed data is returned to the newly allocated
214 configuration object. */
216 SilcConfigServer silc_config_server_alloc(char *filename)
218 SilcConfigServer new;
220 SilcConfigServerParse config_parse;
222 SILC_LOG_DEBUG(("Allocating new configuration object"));
224 new = silc_calloc(1, sizeof(*new));
226 fprintf(stderr, "Could not allocate new configuration object");
230 new->filename = filename;
232 /* Open configuration file and parse it */
235 silc_config_open(filename, &buffer);
238 if ((silc_config_server_parse(new, buffer, &config_parse)) == FALSE)
240 if ((silc_config_server_parse_lines(new, config_parse)) == FALSE)
252 /* Free's a configuration object. */
254 void silc_config_server_free(SilcConfigServer config)
257 silc_free(config->filename);
258 silc_free(config->server_info);
259 silc_free(config->admin_info);
260 silc_free(config->listen_port);
261 silc_free(config->conn_class);
262 silc_free(config->clients);
263 silc_free(config->admins);
264 silc_free(config->servers);
265 silc_free(config->routers);
266 silc_free(config->denied);
267 silc_free(config->redirect);
268 silc_free(config->motd);
273 /* Parses the the buffer and returns the parsed lines into return_config
274 argument. The return_config argument doesn't have to be initialized
275 before calling this. It will be initialized during the parsing. The
276 buffer sent as argument can be safely free'd after this function has
277 succesfully returned. */
279 int silc_config_server_parse(SilcConfigServer config, SilcBuffer buffer,
280 SilcConfigServerParse *return_config)
283 unsigned int linenum;
284 char line[1024], *cp;
285 SilcConfigServerSection *cptr = NULL;
286 SilcConfigServerParse parse = *return_config, first = NULL;
288 SILC_LOG_DEBUG(("Parsing configuration file"));
292 while((begin = silc_gets(line, sizeof(line),
293 buffer->data, buffer->len, begin)) != EOF) {
297 /* Check for bad line */
298 if (silc_check_line(cp))
301 /* Remove tabs and whitespaces from the line */
302 if (strchr(cp, '\t')) {
304 while(strchr(cp + i, '\t')) {
305 *strchr(cp + i, '\t') = ' ';
309 for (i = 0; i < strlen(cp); i++) {
325 /* Remove new line sign */
326 if (strchr(cp, '\n'))
327 *strchr(cp, '\n') = '\0';
329 /* Check for matching sections */
330 for (cptr = silc_config_server_sections; cptr->section; cptr++)
331 if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
334 if (!cptr->section) {
335 fprintf(stderr, "%s:%d: Unknown section `%s'\n",
336 config->filename, linenum, cp);
343 * Start of a configuration line
346 if (cptr->type != SILC_CONFIG_SERVER_SECTION_TYPE_NONE) {
348 if (strchr(cp, '\n'))
349 *strchr(cp, '\n') = ':';
352 parse = silc_calloc(1, sizeof(*parse));
354 parse->section = NULL;
358 if (parse->next == NULL) {
359 parse->next = silc_calloc(1, sizeof(*parse->next));
360 parse->next->line = NULL;
361 parse->next->section = NULL;
362 parse->next->next = NULL;
363 parse->next->prev = parse;
371 /* Add the line to parsing structure for further parsing. */
373 parse->section = cptr;
374 parse->line = silc_buffer_alloc(strlen(cp) + 1);
375 parse->linenum = linenum;
376 silc_buffer_pull_tail(parse->line, strlen(cp));
377 silc_buffer_put(parse->line, cp, strlen(cp));
384 /* Set the return_config argument to its first value so that further
385 parsing can be started from the first line. */
386 *return_config = first;
391 /* Parses the lines earlier read from configuration file. The config object
392 must not be initialized, it will be initialized in this function. The
393 parse_config argument is uninitialized automatically during this
396 int silc_config_server_parse_lines(SilcConfigServer config,
397 SilcConfigServerParse parse_config)
399 int ret, check = FALSE;
400 unsigned int checkmask;
402 SilcConfigServerParse pc = parse_config;
405 SILC_LOG_DEBUG(("Parsing configuration lines"));
415 /* Get number of tokens in line */
416 ret = silc_config_check_num_token(line);
417 if (ret != pc->section->maxfields) {
419 fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
420 config->filename, pc->linenum, ret,
421 pc->section->maxfields);
426 switch(pc->section->type) {
427 case SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER:
429 SILC_SERVER_CONFIG_LIST_ALLOC(config->cipher);
431 /* Get cipher name */
432 ret = silc_config_get_token(line, &config->cipher->alg_name);
436 fprintf(stderr, "%s:%d: Cipher name not defined\n",
437 config->filename, pc->linenum);
441 /* Get module name */
442 config->cipher->sim_name = NULL;
443 ret = silc_config_get_token(line, &config->cipher->sim_name);
447 /* Get block length */
448 ret = silc_config_get_token(line, &tmp);
452 fprintf(stderr, "%s:%d: Cipher block length not defined\n",
453 config->filename, pc->linenum);
456 config->cipher->block_len = atoi(tmp);
460 ret = silc_config_get_token(line, &tmp);
464 fprintf(stderr, "%s:%d: Cipher key length not defined\n",
465 config->filename, pc->linenum);
468 config->cipher->key_len = atoi(tmp);
472 checkmask |= (1L << pc->section->type);
475 case SILC_CONFIG_SERVER_SECTION_TYPE_PKCS:
477 SILC_SERVER_CONFIG_LIST_ALLOC(config->pkcs);
480 ret = silc_config_get_token(line, &config->pkcs->alg_name);
484 fprintf(stderr, "%s:%d: PKCS name not defined\n",
485 config->filename, pc->linenum);
490 ret = silc_config_get_token(line, &tmp);
494 fprintf(stderr, "%s:%d: PKCS key length not defined\n",
495 config->filename, pc->linenum);
498 config->pkcs->key_len = atoi(tmp);
502 checkmask |= (1L << pc->section->type);
505 case SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION:
507 SILC_SERVER_CONFIG_LIST_ALLOC(config->hash_func);
509 /* Get Hash function name */
510 ret = silc_config_get_token(line, &config->hash_func->alg_name);
514 fprintf(stderr, "%s:%d: Hash function name not defined\n",
515 config->filename, pc->linenum);
519 /* Get Hash function module name */
520 config->hash_func->sim_name = NULL;
521 ret = silc_config_get_token(line, &config->hash_func->sim_name);
525 /* Get block length */
526 ret = silc_config_get_token(line, &tmp);
530 fprintf(stderr, "%s:%d: Hash function block length not defined\n",
531 config->filename, pc->linenum);
534 config->hash_func->block_len = atoi(tmp);
537 /* Get hash length */
538 ret = silc_config_get_token(line, &tmp);
542 fprintf(stderr, "%s:%d: Hash function hash length not defined\n",
543 config->filename, pc->linenum);
546 config->hash_func->key_len = atoi(tmp);
550 checkmask |= (1L << pc->section->type);
553 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
555 if (!config->server_info)
556 config->server_info = silc_calloc(1, sizeof(*config->server_info));
558 /* Get server name */
559 ret = silc_config_get_token(line, &config->server_info->server_name);
563 /* Server name not defined */
568 ret = silc_config_get_token(line, &config->server_info->server_ip);
572 /* Server IP not defined */
576 /* Get server location */
577 ret = silc_config_get_token(line, &config->server_info->location);
581 /* Get server port */
582 /* XXX: Need port here??? */
583 ret = silc_config_get_token(line, &tmp);
587 /* Port not defined */
590 config->server_info->port = atoi(tmp);
594 checkmask |= (1L << pc->section->type);
597 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO:
599 if (!config->admin_info)
600 config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
603 ret = silc_config_get_token(line, &config->admin_info->location);
607 /* Get server type */
608 ret = silc_config_get_token(line, &config->admin_info->server_type);
612 /* Get admins name */
613 ret = silc_config_get_token(line, &config->admin_info->admin_name);
617 /* Get admins email address */
618 ret = silc_config_get_token(line, &config->admin_info->admin_email);
623 checkmask |= (1L << pc->section->type);
626 case SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT:
628 SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
631 ret = silc_config_get_token(line, &config->listen_port->host);
636 ret = silc_config_get_token(line, &config->listen_port->remote_ip);
641 ret = silc_config_get_token(line, &tmp);
646 config->listen_port->port = 0;
648 config->listen_port->port = atoi(tmp);
653 checkmask |= (1L << pc->section->type);
656 case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
658 SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
660 /* Get class number */
661 ret = silc_config_get_token(line, &tmp);
665 /* Class number not defined */
668 config->conn_class->class = atoi(tmp);
671 /* Get ping frequency */
672 ret = silc_config_get_token(line, &tmp);
675 config->conn_class->ping_freq = atoi(tmp);
678 /* Get connect frequency */
679 ret = silc_config_get_token(line, &tmp);
682 config->conn_class->connect_freq = atoi(tmp);
686 ret = silc_config_get_token(line, &tmp);
689 config->conn_class->max_links = atoi(tmp);
693 checkmask |= (1L << pc->section->type);
696 case SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING:
698 SILC_SERVER_CONFIG_LIST_ALLOC(config->logging);
700 /* Get log section type and check it */
701 ret = silc_config_get_token(line, &config->logging->logtype);
705 fprintf(stderr, "%s:%d: Log file section not defined\n",
706 config->filename, pc->linenum);
709 if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
710 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
711 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
712 && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
713 fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
714 config->filename, pc->linenum, config->logging->logtype);
718 /* Get log filename */
719 ret = silc_config_get_token(line, &config->logging->filename);
723 fprintf(stderr, "%s:%d: Log file name not defined\n",
724 config->filename, pc->linenum);
728 /* Get max byte size */
729 ret = silc_config_get_token(line, &tmp);
733 config->logging->maxsize = atoi(tmp);
738 checkmask |= (1L << pc->section->type);
741 case SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION:
743 SILC_SERVER_CONFIG_LIST_ALLOC(config->clients);
746 ret = silc_config_get_token(line, &config->clients->host);
751 config->clients->host = strdup("*");
753 /* Get authentication method */
754 ret = silc_config_get_token(line, &tmp);
758 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
759 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
760 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
761 config->filename, pc->linenum, tmp);
765 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
766 config->clients->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
768 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
769 config->clients->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
774 /* Get authentication data */
775 ret = silc_config_get_token(line, &config->clients->auth_data);
780 config->clients->host = strdup("*");
783 ret = silc_config_get_token(line, &tmp);
787 config->clients->port = atoi(tmp);
791 /* Get class number */
792 ret = silc_config_get_token(line, &tmp);
796 config->clients->class = atoi(tmp);
801 checkmask |= (1L << pc->section->type);
804 case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION:
806 SILC_SERVER_CONFIG_LIST_ALLOC(config->servers);
809 ret = silc_config_get_token(line, &config->servers->host);
814 config->servers->host = strdup("*");
816 /* Get authentication method */
817 ret = silc_config_get_token(line, &tmp);
821 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
822 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
823 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
824 config->filename, pc->linenum, tmp);
828 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
829 config->servers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
831 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
832 config->servers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
837 /* Get authentication data */
838 ret = silc_config_get_token(line, &config->servers->auth_data);
843 ret = silc_config_get_token(line, &tmp);
847 config->servers->port = atoi(tmp);
852 ret = silc_config_get_token(line, &config->servers->version);
856 /* Get class number */
857 ret = silc_config_get_token(line, &tmp);
861 config->servers->class = atoi(tmp);
866 checkmask |= (1L << pc->section->type);
869 case SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION:
871 SILC_SERVER_CONFIG_LIST_ALLOC(config->routers);
874 ret = silc_config_get_token(line, &config->routers->host);
879 // config->routers->host = strdup("*");
881 /* Get authentication method */
882 ret = silc_config_get_token(line, &tmp);
886 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
887 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
888 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
889 config->filename, pc->linenum, tmp);
893 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
894 config->routers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
896 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
897 config->routers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
902 /* Get authentication data */
903 ret = silc_config_get_token(line, &config->routers->auth_data);
908 ret = silc_config_get_token(line, &tmp);
912 config->routers->port = atoi(tmp);
917 ret = silc_config_get_token(line, &config->routers->version);
921 /* Get class number */
922 ret = silc_config_get_token(line, &tmp);
926 config->routers->class = atoi(tmp);
931 checkmask |= (1L << pc->section->type);
934 case SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION:
936 SILC_SERVER_CONFIG_LIST_ALLOC(config->admins);
939 ret = silc_config_get_token(line, &config->admins->host);
944 config->admins->host = strdup("*");
946 /* Get authentication method */
947 ret = silc_config_get_token(line, &tmp);
951 if (strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD) &&
952 strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY)) {
953 fprintf(stderr, "%s:%d: Unknown authentication method '%s'\n",
954 config->filename, pc->linenum, tmp);
958 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
959 config->admins->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
961 if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
962 config->admins->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
967 /* Get authentication data */
968 ret = silc_config_get_token(line, &config->admins->auth_data);
973 ret = silc_config_get_token(line, &config->admins->nickname);
977 /* Get class number */
978 ret = silc_config_get_token(line, &tmp);
982 config->admins->class = atoi(tmp);
987 checkmask |= (1L << pc->section->type);
990 case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
991 /* Not implemented yet */
995 case SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT:
996 /* Not implemented yet */
1000 case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
1003 config->motd = silc_calloc(1, sizeof(*config->motd));
1006 ret = silc_config_get_token(line, &config->motd->motd_file);
1011 checkmask |= (1L << pc->section->type);
1014 case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
1020 /* Check for error */
1021 if (check == FALSE) {
1022 /* Line could not be parsed */
1023 fprintf(stderr, "%s:%d: Parse error\n", config->filename, pc->linenum);
1029 // silc_free(pc->prev);
1036 /* Check that all mandatory sections really were found. If not, the server
1037 cannot function and we return error. */
1038 ret = silc_config_server_check_sections(checkmask);
1044 /* Before returning all the lists in the config object must be set
1045 to their first values (the last value is first here). */
1046 while (config->cipher && config->cipher->prev)
1047 config->cipher = config->cipher->prev;
1048 while (config->pkcs && config->pkcs->prev)
1049 config->pkcs = config->pkcs->prev;
1050 while (config->hash_func && config->hash_func->prev)
1051 config->hash_func = config->hash_func->prev;
1052 while (config->listen_port && config->listen_port->prev)
1053 config->listen_port = config->listen_port->prev;
1054 while (config->logging && config->logging->prev)
1055 config->logging = config->logging->prev;
1056 while (config->conn_class && config->conn_class->prev)
1057 config->conn_class = config->conn_class->prev;
1058 while (config->clients && config->clients->prev)
1059 config->clients = config->clients->prev;
1060 while (config->servers && config->servers->prev)
1061 config->servers = config->servers->prev;
1062 while (config->routers && config->routers->prev)
1063 config->routers = config->routers->prev;
1065 SILC_LOG_DEBUG(("Done"));
1070 /* This function checks that the mask sent as argument includes all the
1071 sections that are mandatory in SILC server. */
1073 int silc_config_server_check_sections(unsigned int checkmask)
1075 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
1079 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO))) {
1083 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT))) {
1087 if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
1092 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION))) {
1097 & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
1105 /* Sets log files where log messages is saved by the server. */
1107 void silc_config_server_setlogfiles(SilcConfigServer config)
1109 SilcConfigServerSectionLogging *log;
1110 char *info, *warning, *error, *fatal;
1111 unsigned int info_size, warning_size, error_size, fatal_size;
1113 SILC_LOG_DEBUG(("Setting configured log file names"));
1115 /* Set default files before checking configuration */
1116 info = SILC_LOG_FILE_INFO;
1117 warning = SILC_LOG_FILE_WARNING;
1118 error = SILC_LOG_FILE_ERROR;
1119 fatal = SILC_LOG_FILE_FATAL;
1125 log = config->logging;
1127 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
1128 info = log->filename;
1129 info_size = log->maxsize;
1131 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
1132 warning = log->filename;
1133 warning_size = log->maxsize;
1135 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
1136 error = log->filename;
1137 error_size = log->maxsize;
1139 if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
1140 fatal = log->filename;
1141 fatal_size = log->maxsize;
1147 silc_log_set_files(info, info_size, warning, warning_size,
1148 error, error_size, fatal, fatal_size);
1151 /* Registers configured ciphers. These can then be allocated by the
1152 server when needed. */
1154 void silc_config_server_register_ciphers(SilcConfigServer config)
1156 SilcConfigServerSectionAlg *alg;
1157 SilcServer server = (SilcServer)config->server;
1159 SILC_LOG_DEBUG(("Registering configured ciphers"));
1161 alg = config->cipher;
1164 if (!alg->sim_name) {
1165 /* Crypto module is supposed to be built in. Nothing to be done
1166 here except to test that the cipher really is built in. */
1167 SilcCipher tmp = NULL;
1169 if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
1170 SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
1171 silc_server_stop(server);
1174 silc_cipher_free(tmp);
1178 /* Load (try at least) the crypto SIM module */
1179 SilcCipherObject cipher;
1180 SilcSimContext *sim;
1182 memset(&cipher, 0, sizeof(cipher));
1183 cipher.name = alg->alg_name;
1184 cipher.block_len = alg->block_len;
1185 cipher.key_len = alg->key_len * 8;
1187 sim = silc_sim_alloc();
1188 sim->type = SILC_SIM_CIPHER;
1189 sim->libname = alg->sim_name;
1191 if ((silc_sim_load(sim))) {
1193 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1194 SILC_CIPHER_SIM_SET_KEY));
1195 SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
1196 cipher.set_key_with_string =
1197 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1198 SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
1199 SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
1201 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1202 SILC_CIPHER_SIM_ENCRYPT_CBC));
1203 SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
1205 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1206 SILC_CIPHER_SIM_DECRYPT_CBC));
1207 SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
1208 cipher.context_len =
1209 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1210 SILC_CIPHER_SIM_CONTEXT_LEN));
1211 SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
1213 /* Put the SIM to the list of all SIM's in server */
1214 silc_dlist_add(server->sim, sim);
1216 SILC_LOG_ERROR(("Error configuring ciphers"));
1217 silc_server_stop(server);
1221 /* Register the cipher */
1222 silc_cipher_register(&cipher);
1230 /* Registers configured PKCS's. */
1231 /* XXX: This really doesn't do anything now since we have statically
1232 registered our PKCS's. This should be implemented when PKCS works
1233 as SIM's. This checks now only that the PKCS user requested is
1234 really out there. */
1236 void silc_config_server_register_pkcs(SilcConfigServer config)
1238 SilcConfigServerSectionAlg *alg = config->pkcs;
1239 SilcServer server = (SilcServer)config->server;
1240 SilcPKCS tmp = NULL;
1242 SILC_LOG_DEBUG(("Registering configured PKCS"));
1246 if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
1247 SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
1248 silc_server_stop(server);
1257 /* Registers configured hash functions. These can then be allocated by the
1258 server when needed. */
1260 void silc_config_server_register_hashfuncs(SilcConfigServer config)
1262 SilcConfigServerSectionAlg *alg;
1263 SilcServer server = (SilcServer)config->server;
1265 SILC_LOG_DEBUG(("Registering configured hash functions"));
1267 alg = config->hash_func;
1270 if (!alg->sim_name) {
1271 /* Hash module is supposed to be built in. Nothing to be done
1272 here except to test that the hash function really is built in. */
1273 SilcHash tmp = NULL;
1275 if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
1276 SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
1277 silc_server_stop(server);
1284 /* Load (try at least) the hash SIM module */
1285 SilcHashObject hash;
1286 SilcSimContext *sim;
1288 memset(&hash, 0, sizeof(hash));
1289 hash.name = alg->alg_name;
1290 hash.block_len = alg->block_len;
1291 hash.hash_len = alg->key_len;
1293 sim = silc_sim_alloc();
1294 sim->type = SILC_SIM_HASH;
1295 sim->libname = alg->sim_name;
1297 if ((silc_sim_load(sim))) {
1299 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1300 SILC_HASH_SIM_INIT));
1301 SILC_LOG_DEBUG(("init=%p", hash.init));
1303 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1304 SILC_HASH_SIM_UPDATE));
1305 SILC_LOG_DEBUG(("update=%p", hash.update));
1307 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1308 SILC_HASH_SIM_FINAL));
1309 SILC_LOG_DEBUG(("final=%p", hash.final));
1311 silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
1312 SILC_HASH_SIM_CONTEXT_LEN));
1313 SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
1315 /* Put the SIM to the table of all SIM's in server */
1316 silc_dlist_add(server->sim, sim);
1318 SILC_LOG_ERROR(("Error configuring hash functions"));
1319 silc_server_stop(server);
1323 /* Register the cipher */
1324 silc_hash_register(&hash);
1332 /* Returns client authentication information from server configuration
1333 by host (name or ip). */
1335 SilcConfigServerSectionClientConnection *
1336 silc_config_server_find_client_conn(SilcConfigServer config,
1337 char *host, int port)
1340 SilcConfigServerSectionClientConnection *client = NULL;
1345 if (!config->clients)
1348 client = config->clients;
1350 for (i = 0; client; i++) {
1351 if (silc_string_compare(client->host, host))
1353 client = client->next;
1362 /* Returns server connection info from server configuartion by host
1365 SilcConfigServerSectionServerConnection *
1366 silc_config_server_find_server_conn(SilcConfigServer config,
1367 char *host, int port)
1370 SilcConfigServerSectionServerConnection *serv = NULL;
1375 if (!config->servers)
1378 serv = config->servers;
1379 for (i = 0; serv; i++) {
1380 if (silc_string_compare(serv->host, host))
1391 /* Returns router connection info from server configuartion by
1392 host (name or ip). */
1394 SilcConfigServerSectionServerConnection *
1395 silc_config_server_find_router_conn(SilcConfigServer config,
1396 char *host, int port)
1399 SilcConfigServerSectionServerConnection *serv = NULL;
1404 if (!config->routers)
1407 serv = config->routers;
1408 for (i = 0; serv; i++) {
1409 if (silc_string_compare(serv->host, host))
1420 /* Prints out example configuration file with default built in
1421 configuration values. */
1423 void silc_config_server_print()
1429 # Automatically generated example SILCd configuration file with default\n\
1430 # built in values. Use this as a guide to configure your SILCd configuration\n\
1431 # file for your system. For detailed description of different configuration\n\
1432 # sections refer to silcd(8) manual page.\n\
1447 +lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333
1450 +Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
1453 +10.2.1.6:10.2.1.6:1333
1456 +infologfile:silcd.log:10000
1457 #+warninglogfile:/var/log/silcd_warning.log:10000
1458 #+errorlogfile:ERROR.log:10000
1459 #+fatallogfile:/var/log/silcd_error.log:
1466 +10.2.1.199:priikone:333:1
1469 +10.2.1.199:priikone:priikone:1
1479 fprintf(stdout, "%s\n", buf);