GNU General Public License for more details.
*/
-/*
- * $Id$
- * $Log$
- * Revision 1.1.1.1 2000/06/27 11:36:56 priikone
- * Importet from internal CVS/Added Log headers.
- *
- *
- */
+/* $Id$ */
#include "serverincludes.h"
#include "server_internal.h"
-/* XXX
- All possible configuration sections for SILC server.
-
- <Cipher>
-
- Format:
-
- +<Cipher name>:<SIM path>
-
- <PKCS>
-
- Format:
-
- +<PKCS name>:<key length>
-
- <HashFunction>
-
- Format:
-
- +<Hash function name>:<SIM path>
-
- <ServerInfo>
-
- This section is used to set the server informations.
-
- Format:
-
- +<Server DNS name>:<Server IP>:<Geographic location>:<Port>
-
- <AdminInfo>
-
- This section is used to set the server's administrative information.
-
- Format:
-
- +<Location>:<Server type>:<Admin's name>:<Admin's email address>
-
- <ListenPort>
-
- This section is used to set ports the server is listenning.
-
- Format:
-
- +<Local IP/UNIX socket path>:<Remote IP>:<Port>
-
- <Logging>
-
- This section is used to set various logging files, their paths
- and maximum sizes. All the other directives except those defined
- below are ignored in this section. Log files are purged after they
- reach the maximum set byte size.
-
- Format:
-
- +infologfile:<path>:<max byte size>
- +errorlogfile:<path>:<max byte size>
-
- <ConnectionClass>
-
- This section is used to define connection classes. These can be
- used to optimize the server and the connections.
-
- Format:
-
- +<Class number>:<Ping freq>:<Connect freq>:<Max links>
-
- <ClientAuth>
-
- This section is used to define client authentications.
-
- Format:
-
- +<Remote address or name>:<auth method>:<password/cert/key/???>:<Port>:<Class>
-
- <AdminAuth>
-
- This section is used to define the server's administration
- authentications.
-
- Format:
-
- +<Hostname>:<auth method>:<password/cert/key/???>:<Nickname hash>:<Class>
-
- <ServerConnection>
-
- This section is used to define the server connections to this
- server/router. Only routers can have normal server connections.
- Normal servers leave this section epmty. The remote server cannot be
- older than specified Version ID.
-
- Format:
-
- +<Remote address or name>:<auth method>:<password/key/???>:<Port>:<Version ID>:<Class>
-
- <RouterConnection>
-
- This section is used to define the router connections to this
- server/router. Both normal server and router can have router
- connections. Normal server usually has only one connection while
- a router can have multiple. The remote server cannot be older than
- specified Version ID.
-
- Format:
-
- +<Remote address or name>:<auth method>:<password/key/???>:<Port>:<Version ID>:<Class>
-
- <DenyConnection>
-
- This section is used to deny specific connections to your server. This
- can be used to deny both clients and servers.
-
- Format:
-
- +<Remote address or name or nickname>:<Time interval>:<Comment>:<Port>
-
- <RedirectClient>
-
- This section is used to set the alternate servers that clients will be
- redirected to when our server is full.
-
- Format:
-
- +<Remote address or name>:<Port>
-
-*/
-SilcConfigServerSection silc_config_server_sections[] = {
- { "[Cipher]",
+SilcServerConfigSection silc_server_config_sections[] = {
+ { "[Cipher]",
SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 },
- { "[PKCS]",
- SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 2 },
- { "[HashFunction]",
+ { "[PKCS]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 1 },
+ { "[Hash]",
SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 },
- { "[ServerInfo]",
+ { "[hmac]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 },
+ { "[ServerKeys]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, 2 },
+ { "[ServerInfo]",
SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 },
- { "[AdminInfo]",
+ { "[AdminInfo]",
SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, 4 },
- { "[ListenPort]",
+ { "[ListenPort]",
SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, 3 },
- { "[Logging]",
+ { "[Identity]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY, 2 },
+ { "[Logging]",
SILC_CONFIG_SERVER_SECTION_TYPE_LOGGING, 3 },
{ "[ConnectionClass]",
SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS, 4 },
{ "[ServerConnection]",
SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_CONNECTION, 6 },
{ "[RouterConnection]",
- SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION, 6 },
+ SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION, 7 },
{ "[AdminConnection]",
SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 },
{ "[DenyConnection]",
- SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 4 },
- { "[RedirectClient]",
- SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT, 2 },
+ SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 },
+ { "[motd]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
+ { "[pid]",
+ SILC_CONFIG_SERVER_SECTION_TYPE_PID, 1},
{ NULL, SILC_CONFIG_SERVER_SECTION_TYPE_NONE, 0 }
};
parses the file. The parsed data is returned to the newly allocated
configuration object. */
-SilcConfigServer silc_config_server_alloc(char *filename)
+SilcServerConfig silc_server_config_alloc(char *filename)
{
- SilcConfigServer new;
+ SilcServerConfig new;
SilcBuffer buffer;
- SilcConfigServerParse config_parse;
+ SilcServerConfigParse config_parse;
SILC_LOG_DEBUG(("Allocating new configuration object"));
new->filename = filename;
+ SILC_LOG_DEBUG(("Loading config data from `%s'", filename));
+
/* Open configuration file and parse it */
config_parse = NULL;
buffer = NULL;
silc_config_open(filename, &buffer);
if (!buffer)
goto fail;
- if ((silc_config_server_parse(new, buffer, &config_parse)) == FALSE)
+ if ((silc_server_config_parse(new, buffer, &config_parse)) == FALSE)
goto fail;
- if ((silc_config_server_parse_lines(new, config_parse)) == FALSE)
+ if ((silc_server_config_parse_lines(new, config_parse)) == FALSE)
goto fail;
- silc_free(buffer);
+ silc_buffer_free(buffer);
return new;
fail:
+ silc_buffer_free(buffer);
silc_free(new);
return NULL;
}
/* Free's a configuration object. */
-void silc_config_server_free(SilcConfigServer config)
+void silc_server_config_free(SilcServerConfig config)
{
if (config) {
silc_free(config->filename);
+ silc_free(config->server_keys);
silc_free(config->server_info);
silc_free(config->admin_info);
silc_free(config->listen_port);
+ silc_free(config->identity);
silc_free(config->conn_class);
silc_free(config->clients);
silc_free(config->admins);
silc_free(config->servers);
silc_free(config->routers);
silc_free(config->denied);
- silc_free(config->redirect);
+ silc_free(config->motd);
+ silc_free(config->pidfile);
silc_free(config);
}
}
buffer sent as argument can be safely free'd after this function has
succesfully returned. */
-int silc_config_server_parse(SilcConfigServer config, SilcBuffer buffer,
- SilcConfigServerParse *return_config)
+int silc_server_config_parse(SilcServerConfig config, SilcBuffer buffer,
+ SilcServerConfigParse *return_config)
{
- int i, begin;
- unsigned int linenum;
+ int i, begin, linenum;
char line[1024], *cp;
- SilcConfigServerSection *cptr = NULL;
- SilcConfigServerParse parse = *return_config, first = NULL;
+ SilcServerConfigSection *cptr = NULL;
+ SilcServerConfigParse parse = *return_config, first = NULL;
SILC_LOG_DEBUG(("Parsing configuration file"));
begin = 0;
linenum = 0;
- while((begin = silc_gets(line, sizeof(line),
+ while((begin = silc_gets(line, sizeof(line),
buffer->data, buffer->len, begin)) != EOF) {
cp = line;
linenum++;
*strchr(cp, '\n') = '\0';
/* Check for matching sections */
- for (cptr = silc_config_server_sections; cptr->section; cptr++)
- if (!strcmp(cp, cptr->section))
+ for (cptr = silc_server_config_sections; cptr->section; cptr++)
+ if (!strncasecmp(cp, cptr->section, strlen(cptr->section)))
break;
if (!cptr->section) {
parse_config argument is uninitialized automatically during this
function. */
-int silc_config_server_parse_lines(SilcConfigServer config,
- SilcConfigServerParse parse_config)
+int silc_server_config_parse_lines(SilcServerConfig config,
+ SilcServerConfigParse parse_config)
{
int ret, check = FALSE;
- unsigned int checkmask;
+ uint32 checkmask;
char *tmp;
- SilcConfigServerParse pc = parse_config;
+ SilcServerConfigParse pc = parse_config;
SilcBuffer line;
SILC_LOG_DEBUG(("Parsing configuration lines"));
/* Get number of tokens in line */
ret = silc_config_check_num_token(line);
- if (ret != pc->section->maxfields) {
+ if (ret < pc->section->maxfields) {
/* Bad line */
fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
config->filename, pc->linenum, ret,
if (ret < 0)
break;
- /* Get block length */
+ /* Get key length */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
break;
if (ret == 0) {
- fprintf(stderr, "%s:%d: Cipher block length not defined\n",
+ fprintf(stderr, "%s:%d: Cipher key length not defined\n",
config->filename, pc->linenum);
break;
}
- config->cipher->block_len = atoi(tmp);
+ config->cipher->key_len = atoi(tmp);
silc_free(tmp);
- /* Get key length */
+ /* Get block length */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
break;
if (ret == 0) {
- fprintf(stderr, "%s:%d: Cipher key length not defined\n",
+ fprintf(stderr, "%s:%d: Cipher block length not defined\n",
config->filename, pc->linenum);
break;
}
- config->cipher->key_len = atoi(tmp);
+ config->cipher->block_len = atoi(tmp);
silc_free(tmp);
check = TRUE;
break;
}
- /* Get key length */
- ret = silc_config_get_token(line, &tmp);
- if (ret < 0)
- break;
- if (ret == 0) {
- fprintf(stderr, "%s:%d: PKCS key length not defined\n",
- config->filename, pc->linenum);
- break;
- }
- config->pkcs->key_len = atoi(tmp);
- silc_free(tmp);
-
check = TRUE;
checkmask |= (1L << pc->section->type);
break;
checkmask |= (1L << pc->section->type);
break;
+ case SILC_CONFIG_SERVER_SECTION_TYPE_HMAC:
+
+ SILC_SERVER_CONFIG_LIST_ALLOC(config->hmac);
+
+ /* Get HMAC name */
+ ret = silc_config_get_token(line, &config->hmac->alg_name);
+ if (ret < 0)
+ break;
+ if (ret == 0) {
+ fprintf(stderr, "%s:%d: HMAC name not defined\n",
+ config->filename, pc->linenum);
+ break;
+ }
+
+ /* Get hash name */
+ ret = silc_config_get_token(line, &config->hmac->sim_name);
+ if (ret < 0)
+ break;
+ if (ret == 0) {
+ fprintf(stderr, "%s:%d: Hash function name not defined\n",
+ config->filename, pc->linenum);
+ break;
+ }
+
+ /* Get MAC length */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret < 0)
+ break;
+ if (ret == 0) {
+ fprintf(stderr, "%s:%d: HMAC's MAC length not defined\n",
+ config->filename, pc->linenum);
+ break;
+ }
+ config->hmac->key_len = atoi(tmp);
+ silc_free(tmp);
+
+ check = TRUE;
+ checkmask |= (1L << pc->section->type);
+ break;
+
+ case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS:
+
+ if (!config->server_keys)
+ config->server_keys = silc_calloc(1, sizeof(*config->server_keys));
+
+ ret = silc_config_get_token(line, &tmp);
+ if (ret < 0)
+ break;
+ if (ret == 0) {
+ fprintf(stderr, "%s:%d: Public key name not defined\n",
+ config->filename, pc->linenum);
+ break;
+ }
+
+ if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
+ SILC_PKCS_FILE_PEM))
+ if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key,
+ SILC_PKCS_FILE_BIN)) {
+ fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
+ config->filename, pc->linenum, tmp);
+ break;
+ }
+ silc_free(tmp);
+
+ ret = silc_config_get_token(line, &tmp);
+ if (ret < 0)
+ break;
+ if (ret == 0) {
+ fprintf(stderr, "%s:%d: Private key name not defined\n",
+ config->filename, pc->linenum);
+ break;
+ }
+
+ if (!silc_pkcs_load_private_key(tmp, &config->server_keys->private_key,
+ SILC_PKCS_FILE_BIN))
+ if (!silc_pkcs_load_private_key(tmp,
+ &config->server_keys->private_key,
+ SILC_PKCS_FILE_PEM)) {
+ fprintf(stderr, "%s:%d: Could not load private key file `%s'\n",
+ config->filename, pc->linenum, tmp);
+ break;
+ }
+ silc_free(tmp);
+
+ check = TRUE;
+ checkmask |= (1L << pc->section->type);
+ break;
+
case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO:
if (!config->server_info)
if (!config->admin_info)
config->admin_info = silc_calloc(1, sizeof(*config->admin_info));
+ /* Get location */
+ ret = silc_config_get_token(line, &config->admin_info->location);
+ if (ret < 0)
+ break;
+
/* Get server type */
ret = silc_config_get_token(line, &config->admin_info->server_type);
if (ret < 0)
SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
- /* Get host */
- ret = silc_config_get_token(line, &config->listen_port->host);
+ /* Get local IP */
+ ret = silc_config_get_token(line, &config->listen_port->local_ip);
if (ret < 0)
break;
- /* Get remote IP */
- ret = silc_config_get_token(line, &config->listen_port->remote_ip);
+ /* Get listener IP */
+ ret = silc_config_get_token(line, &config->listen_port->listener_ip);
if (ret < 0)
break;
checkmask |= (1L << pc->section->type);
break;
+ case SILC_CONFIG_SERVER_SECTION_TYPE_IDENTITY:
+
+ if (!config->identity)
+ config->identity = silc_calloc(1, sizeof(*config->identity));
+
+ /* Get user */
+ ret = silc_config_get_token(line, &config->identity->user);
+ if (ret < 0)
+ break;
+ /* Get group */
+ ret = silc_config_get_token(line, &config->identity->group);
+ if (ret < 0)
+ break;
+
+ check = TRUE;
+ checkmask |= (1L << pc->section->type);
+
case SILC_CONFIG_SERVER_SECTION_TYPE_CONNECTION_CLASS:
SILC_SERVER_CONFIG_LIST_ALLOC(config->conn_class);
if (ret < 0)
break;
if (ret == 0) {
- fprintf(stderr, "%s:%d: Log file section not defined\n",
+ fprintf(stderr, "%s:%d: Log file section not defined\n",
config->filename, pc->linenum);
break;
}
if (strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_INFO)
&& strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_WARNING)
&& strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_ERROR)
- && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
+ && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LF_FATAL)
+ && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_QUICK)
+ && strcmp(config->logging->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) {
fprintf(stderr, "%s:%d: Unknown log file section '%s'\n",
config->filename, pc->linenum, config->logging->logtype);
break;
}
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
- config->clients->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+ config->clients->auth_meth = SILC_AUTH_PASSWORD;
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
- config->clients->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+ config->clients->auth_meth = SILC_AUTH_PUBLIC_KEY;
silc_free(tmp);
}
/* Get authentication data */
- ret = silc_config_get_token(line, &config->clients->auth_data);
+ ret = silc_config_get_token(line, (char **)&config->clients->auth_data);
if (ret < 0)
break;
- if (ret == 0)
- /* Any host */
- config->clients->host = strdup("*");
+
+ if (config->clients->auth_meth == SILC_AUTH_PASSWORD) {
+ config->clients->auth_data_len = strlen(config->clients->auth_data);
+ } else if (config->clients->auth_meth == SILC_AUTH_PUBLIC_KEY) {
+ /* Get the public key */
+ SilcPublicKey public_key;
+
+ if (!silc_pkcs_load_public_key(config->clients->auth_data,
+ &public_key, SILC_PKCS_FILE_PEM))
+ if (!silc_pkcs_load_public_key(config->clients->auth_data,
+ &public_key, SILC_PKCS_FILE_BIN)) {
+ fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
+ config->filename, pc->linenum,
+ (char *)config->clients->auth_data);
+ break;
+ }
+
+ silc_free(config->clients->auth_data);
+ config->clients->auth_data = (void *)public_key;
+ config->clients->auth_data_len = 0;
+ }
/* Get port */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
break;
- if (ret == 0) {
+ if (ret) {
config->clients->port = atoi(tmp);
silc_free(tmp);
}
}
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
- config->servers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+ config->servers->auth_meth = SILC_AUTH_PASSWORD;
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
- config->servers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+ config->servers->auth_meth = SILC_AUTH_PUBLIC_KEY;
silc_free(tmp);
}
/* Get authentication data */
- ret = silc_config_get_token(line, &config->servers->auth_data);
+ ret = silc_config_get_token(line, (char **)&config->servers->auth_data);
if (ret < 0)
break;
+ if (config->servers->auth_meth == SILC_AUTH_PASSWORD) {
+ config->servers->auth_data_len = strlen(config->servers->auth_data);
+ } else if (config->servers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
+ /* Get the public key */
+ SilcPublicKey public_key;
+
+ if (!silc_pkcs_load_public_key(config->servers->auth_data,
+ &public_key, SILC_PKCS_FILE_PEM))
+ if (!silc_pkcs_load_public_key(config->servers->auth_data,
+ &public_key, SILC_PKCS_FILE_BIN)) {
+ fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
+ config->filename, pc->linenum,
+ (char *)config->servers->auth_data);
+ break;
+ }
+
+ silc_free(config->servers->auth_data);
+ config->servers->auth_data = (void *)public_key;
+ config->servers->auth_data_len = 0;
+ }
+
/* Get port */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
silc_free(tmp);
}
+ /* Check whether this connection is backup router connection */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret != -1) {
+ config->servers->backup_router = atoi(tmp);
+ if (config->servers->backup_router != 0)
+ config->servers->backup_router = TRUE;
+ silc_free(tmp);
+ }
+
check = TRUE;
checkmask |= (1L << pc->section->type);
break;
ret = silc_config_get_token(line, &config->routers->host);
if (ret < 0)
break;
- // if (ret == 0)
- ///* Any host */
- // config->routers->host = strdup("*");
/* Get authentication method */
ret = silc_config_get_token(line, &tmp);
}
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
- config->routers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+ config->routers->auth_meth = SILC_AUTH_PASSWORD;
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
- config->routers->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+ config->routers->auth_meth = SILC_AUTH_PUBLIC_KEY;
silc_free(tmp);
}
/* Get authentication data */
- ret = silc_config_get_token(line, &config->routers->auth_data);
+ ret = silc_config_get_token(line, (char **)&config->routers->auth_data);
if (ret < 0)
break;
+ if (config->routers->auth_meth == SILC_AUTH_PASSWORD) {
+ config->routers->auth_data_len = strlen(config->routers->auth_data);
+ } else if (config->routers->auth_meth == SILC_AUTH_PUBLIC_KEY) {
+ /* Get the public key */
+ SilcPublicKey public_key;
+
+ if (!silc_pkcs_load_public_key(config->routers->auth_data,
+ &public_key, SILC_PKCS_FILE_PEM))
+ if (!silc_pkcs_load_public_key(config->routers->auth_data,
+ &public_key, SILC_PKCS_FILE_BIN)) {
+ fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
+ config->filename, pc->linenum,
+ (char *)config->routers->auth_data);
+ break;
+ }
+
+ silc_free(config->routers->auth_data);
+ config->routers->auth_data = (void *)public_key;
+ config->routers->auth_data_len = 0;
+ }
+
/* Get port */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
silc_free(tmp);
}
+ /* Get whether we are initiator or not */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret < 0)
+ break;
+ if (ret) {
+ config->routers->initiator = atoi(tmp);
+ if (config->routers->initiator != 0)
+ config->routers->initiator = TRUE;
+ silc_free(tmp);
+ }
+
+ /* Get backup replace IP */
+ ret = silc_config_get_token(line, &config->routers->backup_replace_ip);
+ if (ret != -1)
+ config->routers->backup_router = TRUE;
+
+ if (config->routers->backup_router) {
+ /* Get backup replace port */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret != -1) {
+ config->routers->backup_replace_port = atoi(tmp);
+ silc_free(tmp);
+ }
+
+ /* Check whether the backup connection is local */
+ ret = silc_config_get_token(line, &tmp);
+ if (ret != -1) {
+ config->routers->backup_local = atoi(tmp);
+ if (config->routers->backup_local != 0)
+ config->routers->backup_local = TRUE;
+ silc_free(tmp);
+ }
+ }
+
check = TRUE;
checkmask |= (1L << pc->section->type);
break;
/* Any host */
config->admins->host = strdup("*");
+ /* Get username */
+ ret = silc_config_get_token(line, &config->admins->username);
+ if (ret < 0)
+ break;
+ if (ret == 0)
+ /* Any username */
+ config->admins->username = strdup("*");
+
+ /* Get nickname */
+ ret = silc_config_get_token(line, &config->admins->nickname);
+ if (ret < 0)
+ break;
+ if (ret == 0)
+ /* Any nickname */
+ config->admins->nickname = strdup("*");
+
/* Get authentication method */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
}
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PASSWD))
- config->admins->auth_meth = SILC_PROTOCOL_CONN_AUTH_PASSWORD;
+ config->admins->auth_meth = SILC_AUTH_PASSWORD;
if (!strcmp(tmp, SILC_CONFIG_SERVER_AUTH_METH_PUBKEY))
- config->admins->auth_meth = SILC_PROTOCOL_CONN_AUTH_PUBLIC_KEY;
+ config->admins->auth_meth = SILC_AUTH_PUBLIC_KEY;
silc_free(tmp);
}
/* Get authentication data */
- ret = silc_config_get_token(line, &config->admins->auth_data);
+ ret = silc_config_get_token(line, (char **)&config->admins->auth_data);
if (ret < 0)
break;
- /* Get nickname */
- ret = silc_config_get_token(line, &config->admins->nickname);
+ if (config->admins->auth_meth == SILC_AUTH_PASSWORD) {
+ config->admins->auth_data_len = strlen(config->admins->auth_data);
+ } else if (config->admins->auth_meth == SILC_AUTH_PUBLIC_KEY) {
+ /* Get the public key */
+ SilcPublicKey public_key;
+
+ if (!silc_pkcs_load_public_key(config->admins->auth_data,
+ &public_key, SILC_PKCS_FILE_PEM))
+ if (!silc_pkcs_load_public_key(config->admins->auth_data,
+ &public_key, SILC_PKCS_FILE_BIN)) {
+ fprintf(stderr, "%s:%d: Could not load public key file `%s'\n",
+ config->filename, pc->linenum,
+ (char *)config->admins->auth_data);
+ break;
+ }
+
+ silc_free(config->admins->auth_data);
+ config->admins->auth_data = (void *)public_key;
+ config->admins->auth_data_len = 0;
+ }
+
+ check = TRUE;
+ checkmask |= (1L << pc->section->type);
+ break;
+
+ case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
+
+ SILC_SERVER_CONFIG_LIST_ALLOC(config->denied);
+
+ /* Get host */
+ ret = silc_config_get_token(line, &config->denied->host);
if (ret < 0)
break;
+ if (ret == 0) {
+ /* Any host */
+ config->denied->host = strdup("*");
+ fprintf(stderr, "warning: %s:%d: Denying all connections",
+ config->filename, pc->linenum);
+ }
- /* Get class number */
+ /* Get port */
ret = silc_config_get_token(line, &tmp);
if (ret < 0)
break;
- if (ret) {
- config->admins->class = atoi(tmp);
+ if (ret == 0) {
+ /* Any port */
+ config->denied->port = 0;
+ } else {
+ config->denied->port = atoi(tmp);
silc_free(tmp);
}
+ /* Get comment */
+ ret = silc_config_get_token(line, &config->denied->comment);
+ if (ret < 0)
+ break;
+
check = TRUE;
checkmask |= (1L << pc->section->type);
break;
- case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
- /* Not implemented yet */
- check = TRUE;
- break;
+ case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
+
+ if (!config->motd)
+ config->motd = silc_calloc(1, sizeof(*config->motd));
+
+ /* Get motd file */
+ ret = silc_config_get_token(line, &config->motd->motd_file);
+ if (ret < 0)
+ break;
- case SILC_CONFIG_SERVER_SECTION_TYPE_REDIRECT_CLIENT:
- /* Not implemented yet */
check = TRUE;
+ checkmask |= (1L << pc->section->type);
break;
+ case SILC_CONFIG_SERVER_SECTION_TYPE_PID:
+
+ if (!config->pidfile)
+ config->pidfile = silc_calloc(1, sizeof(*config->pidfile));
+
+ ret = silc_config_get_token(line, &config->pidfile->pid_file);
+ if (ret < 0)
+ break;
+
+ check = TRUE;
+ checkmask |= (1L << pc->section->type);
+ break;
+
case SILC_CONFIG_SERVER_SECTION_TYPE_NONE:
default:
/* Error */
}
pc = pc->next;
- /* XXXX */
- // silc_free(pc->prev);
- // pc->prev = NULL;
}
if (check == FALSE)
- return FALSE;;
+ return FALSE;
/* Check that all mandatory sections really were found. If not, the server
cannot function and we return error. */
- ret = silc_config_server_check_sections(checkmask);
+ ret = silc_server_config_check_sections(checkmask);
if (ret == FALSE) {
/* XXX */
config->pkcs = config->pkcs->prev;
while (config->hash_func && config->hash_func->prev)
config->hash_func = config->hash_func->prev;
+ while (config->hmac && config->hmac->prev)
+ config->hmac = config->hmac->prev;
while (config->listen_port && config->listen_port->prev)
config->listen_port = config->listen_port->prev;
while (config->logging && config->logging->prev)
config->clients = config->clients->prev;
while (config->servers && config->servers->prev)
config->servers = config->servers->prev;
+ while (config->admins && config->admins->prev)
+ config->admins = config->admins->prev;
while (config->routers && config->routers->prev)
config->routers = config->routers->prev;
/* This function checks that the mask sent as argument includes all the
sections that are mandatory in SILC server. */
-int silc_config_server_check_sections(unsigned int checkmask)
+int silc_server_config_check_sections(uint32 checkmask)
{
if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO))) {
return FALSE;
}
- if (!(checkmask & (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
+ if (!(checkmask &
+ (1L << SILC_CONFIG_SERVER_SECTION_TYPE_CLIENT_CONNECTION))) {
return FALSE;
}
return FALSE;
}
- if (!(checkmask
+ if (!(checkmask
& (1L << SILC_CONFIG_SERVER_SECTION_TYPE_ROUTER_CONNECTION))) {
-
+
return FALSE;
}
/* Sets log files where log messages is saved by the server. */
-void silc_config_server_setlogfiles(SilcConfigServer config)
+void silc_server_config_setlogfiles(SilcServerConfig config, SilcSchedule sked)
{
- SilcConfigServerSectionLogging *log;
- char *info, *warning, *error, *fatal;
- unsigned int info_size, warning_size, error_size, fatal_size;
+ long tmp;
+ SilcServerConfigSectionLogging *log;
SILC_LOG_DEBUG(("Setting configured log file names"));
-
- /* Set default files before checking configuration */
- info = SILC_LOG_FILE_INFO;
- warning = SILC_LOG_FILE_WARNING;
- error = SILC_LOG_FILE_ERROR;
- fatal = SILC_LOG_FILE_FATAL;
- info_size = 0;
- warning_size = 0;
- error_size = 0;
- fatal_size = 0;
-
log = config->logging;
- while(log) {
- if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO)) {
- info = log->filename;
- info_size = log->maxsize;
+ while (log) {
+ /* Logging Files */
+ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_INFO))
+ silc_log_set_file(SILC_LOG_INFO, log->filename, log->maxsize, sked);
+ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING))
+ silc_log_set_file(SILC_LOG_WARNING, log->filename, log->maxsize, sked);
+ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR))
+ silc_log_set_file(SILC_LOG_ERROR, log->filename, log->maxsize, sked);
+ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL))
+ silc_log_set_file(SILC_LOG_FATAL, log->filename, log->maxsize, sked);
+ /* Logging Options */
+ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_QUICK)) {
+ if (!strcasecmp(log->filename, "yes") ||
+ !strcasecmp(log->filename, "on"))
+ silc_log_quick = TRUE;
}
- if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_WARNING)) {
- warning = log->filename;
- warning_size = log->maxsize;
- }
- if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_ERROR)) {
- error = log->filename;
- error_size = log->maxsize;
- }
- if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LF_FATAL)) {
- fatal = log->filename;
- fatal_size = log->maxsize;
+ if (!strcmp(log->logtype, SILC_CONFIG_SERVER_LO_FDELAY)) {
+ tmp = atol(log->filename);
+ if (tmp > 0)
+ silc_log_flushdelay = tmp;
+ else {
+ fprintf(stderr, "config: invalid flushdelay value, use quicklogs if "
+ "you want real-time logging.\n");
+ exit(1);
+ }
}
log = log->next;
}
-
- silc_log_set_files(info, info_size, warning, warning_size,
- error, error_size, fatal, fatal_size);
}
/* Registers configured ciphers. These can then be allocated by the
server when needed. */
-void silc_config_server_register_ciphers(SilcConfigServer config)
+bool silc_server_config_register_ciphers(SilcServerConfig config)
{
- SilcConfigServerSectionAlg *alg;
+ SilcServerConfigSectionAlg *alg;
SilcServer server = (SilcServer)config->server;
SILC_LOG_DEBUG(("Registering configured ciphers"));
+ if (!config->cipher)
+ return FALSE;
+
alg = config->cipher;
while(alg) {
if (!alg->sim_name) {
- /* Crypto module is supposed to be built in. Nothing to be done
- here except to test that the cipher really is built in. */
- SilcCipher tmp = NULL;
-
- if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
- SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
+ int i;
+
+ for (i = 0; silc_default_ciphers[i].name; i++)
+ if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
+ silc_cipher_register(&silc_default_ciphers[i]);
+ break;
+ }
+
+ if (!silc_cipher_is_supported(alg->alg_name)) {
+ SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
silc_server_stop(server);
exit(1);
}
- silc_cipher_free(tmp);
-
#ifdef SILC_SIM
} else {
/* Load (try at least) the crypto SIM module */
SilcCipherObject cipher;
SilcSimContext *sim;
+ char *alg_name;
memset(&cipher, 0, sizeof(cipher));
cipher.name = alg->alg_name;
sim->type = SILC_SIM_CIPHER;
sim->libname = alg->sim_name;
+ alg_name = strdup(alg->alg_name);
+ if (strchr(alg_name, '-'))
+ *strchr(alg_name, '-') = '\0';
+
if ((silc_sim_load(sim))) {
cipher.set_key =
- silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
+ silc_sim_getsym(sim, silc_sim_symname(alg_name,
SILC_CIPHER_SIM_SET_KEY));
SILC_LOG_DEBUG(("set_key=%p", cipher.set_key));
cipher.set_key_with_string =
- silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
+ silc_sim_getsym(sim, silc_sim_symname(alg_name,
SILC_CIPHER_SIM_SET_KEY_WITH_STRING));
SILC_LOG_DEBUG(("set_key_with_string=%p", cipher.set_key_with_string));
cipher.encrypt =
- silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
+ silc_sim_getsym(sim, silc_sim_symname(alg_name,
SILC_CIPHER_SIM_ENCRYPT_CBC));
SILC_LOG_DEBUG(("encrypt_cbc=%p", cipher.encrypt));
cipher.decrypt =
- silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
+ silc_sim_getsym(sim, silc_sim_symname(alg_name,
SILC_CIPHER_SIM_DECRYPT_CBC));
SILC_LOG_DEBUG(("decrypt_cbc=%p", cipher.decrypt));
cipher.context_len =
- silc_sim_getsym(sim, silc_sim_symname(alg->alg_name,
+ silc_sim_getsym(sim, silc_sim_symname(alg_name,
SILC_CIPHER_SIM_CONTEXT_LEN));
SILC_LOG_DEBUG(("context_len=%p", cipher.context_len));
- /* Put the SIM to the table of all SIM's in server */
- server->sim = silc_realloc(server->sim,
- sizeof(*server->sim) *
- (server->sim_count + 1));
- server->sim[server->sim_count] = sim;
- server->sim_count++;
+ /* Put the SIM to the list of all SIM's in server */
+ silc_dlist_add(server->sim, sim);
+
+ silc_free(alg_name);
} else {
SILC_LOG_ERROR(("Error configuring ciphers"));
silc_server_stop(server);
alg = alg->next;
}
+
+ return TRUE;
}
/* Registers configured PKCS's. */
-/* XXX: This really doesn't do anything now since we have statically
- registered our PKCS's. This should be implemented when PKCS works
- as SIM's. This checks now only that the PKCS user requested is
- really out there. */
-void silc_config_server_register_pkcs(SilcConfigServer config)
+bool silc_server_config_register_pkcs(SilcServerConfig config)
{
- SilcConfigServerSectionAlg *alg = config->pkcs;
+ SilcServerConfigSectionAlg *alg = config->pkcs;
SilcServer server = (SilcServer)config->server;
- SilcPKCS tmp = NULL;
SILC_LOG_DEBUG(("Registering configured PKCS"));
- while(alg) {
+ if (!config->pkcs)
+ return FALSE;
- if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
- SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
+ while(alg) {
+ int i;
+
+ for (i = 0; silc_default_pkcs[i].name; i++)
+ if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
+ silc_pkcs_register(&silc_default_pkcs[i]);
+ break;
+ }
+
+ if (!silc_pkcs_is_supported(alg->alg_name)) {
+ SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
silc_server_stop(server);
exit(1);
}
- silc_free(tmp);
alg = alg->next;
}
+
+ return TRUE;
}
/* Registers configured hash functions. These can then be allocated by the
server when needed. */
-void silc_config_server_register_hashfuncs(SilcConfigServer config)
+bool silc_server_config_register_hashfuncs(SilcServerConfig config)
{
- SilcConfigServerSectionAlg *alg;
+ SilcServerConfigSectionAlg *alg;
SilcServer server = (SilcServer)config->server;
SILC_LOG_DEBUG(("Registering configured hash functions"));
+ if (!config->hash_func)
+ return FALSE;
+
alg = config->hash_func;
while(alg) {
if (!alg->sim_name) {
- /* Hash module is supposed to be built in. Nothing to be done
- here except to test that the hash function really is built in. */
- SilcHash tmp = NULL;
-
- if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
- SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
+ int i;
+
+ for (i = 0; silc_default_hash[i].name; i++)
+ if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
+ silc_hash_register(&silc_default_hash[i]);
+ break;
+ }
+
+ if (!silc_hash_is_supported(alg->alg_name)) {
+ SILC_LOG_ERROR(("Unknown hash funtion `%s'", alg->alg_name));
silc_server_stop(server);
exit(1);
}
- silc_free(tmp);
#ifdef SILC_SIM
} else {
SILC_LOG_DEBUG(("context_len=%p", hash.context_len));
/* Put the SIM to the table of all SIM's in server */
- server->sim = silc_realloc(server->sim,
- sizeof(*server->sim) *
- (server->sim_count + 1));
- server->sim[server->sim_count] = sim;
- server->sim_count++;
+ silc_dlist_add(server->sim, sim);
} else {
SILC_LOG_ERROR(("Error configuring hash functions"));
silc_server_stop(server);
exit(1);
}
- /* Register the cipher */
+ /* Register the hash function */
silc_hash_register(&hash);
#endif
}
alg = alg->next;
}
+
+ return TRUE;
+}
+
+/* Registers configure HMACs. These can then be allocated by the server
+ when needed. */
+
+bool silc_server_config_register_hmacs(SilcServerConfig config)
+{
+ SilcServerConfigSectionAlg *alg;
+ SilcServer server = (SilcServer)config->server;
+
+ SILC_LOG_DEBUG(("Registering configured HMACs"));
+
+ if (!config->hmac)
+ return FALSE;
+
+ alg = config->hmac;
+ while(alg) {
+ SilcHmacObject hmac;
+
+ if (!silc_hash_is_supported(alg->sim_name)) {
+ SILC_LOG_ERROR(("Unknown hash function `%s'", alg->sim_name));
+ silc_server_stop(server);
+ exit(1);
+ }
+
+ /* Register the HMAC */
+ memset(&hmac, 0, sizeof(hmac));
+ hmac.name = alg->alg_name;
+ hmac.len = alg->key_len;
+ silc_hmac_register(&hmac);
+
+ alg = alg->next;
+ }
+
+ return TRUE;
}
/* Returns client authentication information from server configuration
- by host (name or ip). */
+ by host (name or ip). If `port' is non-null then both name or IP and
+ the port must match. */
-SilcConfigServerSectionClientConnection *
-silc_config_server_find_client_conn(SilcConfigServer config,
+SilcServerConfigSectionClientConnection *
+silc_server_config_find_client_conn(SilcServerConfig config,
char *host, int port)
{
int i;
- SilcConfigServerSectionClientConnection *client = NULL;
+ SilcServerConfigSectionClientConnection *client = NULL;
+ bool match = FALSE;
if (!host)
return NULL;
for (i = 0; client; i++) {
if (silc_string_compare(client->host, host))
+ match = TRUE;
+
+ if (port && client->port && client->port != port)
+ match = FALSE;
+
+ if (match)
break;
+
client = client->next;
}
}
/* Returns server connection info from server configuartion by host
- (name or ip). */
+ (name or ip). If `port' is non-null then both name or IP and the port
+ must match. */
-SilcConfigServerSectionServerConnection *
-silc_config_server_find_server_conn(SilcConfigServer config,
+SilcServerConfigSectionServerConnection *
+silc_server_config_find_server_conn(SilcServerConfig config,
char *host, int port)
{
int i;
- SilcConfigServerSectionServerConnection *serv = NULL;
+ SilcServerConfigSectionServerConnection *serv = NULL;
+ bool match = FALSE;
if (!host)
return NULL;
serv = config->servers;
for (i = 0; serv; i++) {
if (silc_string_compare(serv->host, host))
+ match = TRUE;
+
+ if (port && serv->port && serv->port != port)
+ match = FALSE;
+
+ if (match)
break;
+
serv = serv->next;
}
/* Returns router connection info from server configuartion by
host (name or ip). */
-SilcConfigServerSectionServerConnection *
-silc_config_server_find_router_conn(SilcConfigServer config,
+SilcServerConfigSectionServerConnection *
+silc_server_config_find_router_conn(SilcServerConfig config,
char *host, int port)
{
int i;
- SilcConfigServerSectionServerConnection *serv = NULL;
+ SilcServerConfigSectionServerConnection *serv = NULL;
+ bool match = FALSE;
if (!host)
return NULL;
serv = config->routers;
for (i = 0; serv; i++) {
if (silc_string_compare(serv->host, host))
+ match = TRUE;
+
+ if (port && serv->port && serv->port != port)
+ match = FALSE;
+
+ if (match)
break;
+
serv = serv->next;
}
return serv;
}
-/* Prints out example configuration file with default built in
- configuration values. */
+/* Returns TRUE if configuartion for a router connection that we are
+ initiating exists. */
+
+bool silc_server_config_is_primary_route(SilcServerConfig config)
+{
+ int i;
+ SilcServerConfigSectionServerConnection *serv = NULL;
+ bool found = FALSE;
+
+ serv = config->routers;
+ for (i = 0; serv; i++) {
+ if (serv->initiator == TRUE && serv->backup_router == FALSE) {
+ found = TRUE;
+ break;
+ }
+
+ serv = serv->next;
+ }
+
+ return found;
+}
+
+/* Returns our primary connection configuration or NULL if we do not
+ have primary router configured. */
+
+SilcServerConfigSectionServerConnection *
+silc_server_config_get_primary_router(SilcServerConfig config)
+{
+ int i;
+ SilcServerConfigSectionServerConnection *serv = NULL;
+
+ serv = config->routers;
+ for (i = 0; serv; i++) {
+ if (serv->initiator == TRUE && serv->backup_router == FALSE)
+ return serv;
+ serv = serv->next;
+ }
+
+ return NULL;
+}
+
+/* Returns Admin connection configuration by host, username and/or
+ nickname. */
-void silc_config_server_print()
+SilcServerConfigSectionAdminConnection *
+silc_server_config_find_admin(SilcServerConfig config,
+ char *host, char *username, char *nickname)
{
- char *buf;
+ SilcServerConfigSectionAdminConnection *admin = NULL;
+ int i;
+
+ if (!config->admins)
+ return NULL;
+
+ if (!host)
+ host = "*";
+ if (!username)
+ username = "*";
+ if (!nickname)
+ nickname = "*";
+
+ admin = config->admins;
+ for (i = 0; admin; i++) {
+ if (silc_string_compare(admin->host, host) &&
+ silc_string_compare(admin->username, username) &&
+ silc_string_compare(admin->nickname, nickname))
+ break;
- buf = "\
-#\n\
-# Automatically generated example SILCd configuration file with default\n\
-# built in values. Use this as a guide to configure your SILCd configuration\n\
-# file for your system. For detailed description of different configuration\n\
-# sections refer to silcd(8) manual page.\n\
-#\n";
- /*
-#<Cipher>
-#+blowfish
-#+twofish
-#+rc5
-#+rc6
-#+3des
+ admin = admin->next;
+ }
-#<HashFunction>
-#+md5
-#+sha1
+ if (!admin)
+ return NULL;
-<ServerInfo>
-+lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333
+ return admin;
+}
-<AdminInfo>
-+Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
+/* Returns the Denied connection configuration by host and port. */
-<ListenPort>
-+10.2.1.6:10.2.1.6:1333
+SilcServerConfigSectionDenyConnection *
+silc_server_config_denied_conn(SilcServerConfig config, char *host,
+ int port)
+{
+ int i;
+ SilcServerConfigSectionDenyConnection *deny = NULL;
+ bool match = FALSE;
-<Logging>
-+infologfile:silcd.log:10000
-#+warninglogfile:/var/log/silcd_warning.log:10000
-#+errorlogfile:ERROR.log:10000
-#+fatallogfile:/var/log/silcd_error.log:
+ if (!host)
+ return NULL;
-<ConnectionClass>
- +1:100:100:100
- +2:200:300:400
+ if (!config->denied)
+ return NULL;
-<ClientAuth>
-+10.2.1.199:priikone:333:1
+ deny = config->denied;
+ for (i = 0; deny; i++) {
+ if (silc_string_compare(deny->host, host))
+ match = TRUE;
-<AdminAuth>
-+10.2.1.199:priikone:priikone:1
+ if (port && deny->port && deny->port != port)
+ match = FALSE;
-<ServerConnection>
+ if (match)
+ break;
-<RouterConnection>
+ deny = deny->next;
+ }
-<DenyConnection>
-<RedirectClient>
- */
+ if (!deny)
+ return NULL;
- fprintf(stdout, "%s\n", buf);
+ return deny;
}