From f5655eda8412bc7b03b6162cad01ad612719ad4a Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 16 Feb 2002 19:26:30 +0000 Subject: [PATCH] tupdates --- CHANGES | 17 ++ TODO | 16 +- apps/irssi/src/silc/core/client_ops.c | 2 +- apps/silcd/command.c | 4 +- apps/silcd/packet_receive.c | 9 +- apps/silcd/protocol.c | 12 +- apps/silcd/protocol.h | 1 + apps/silcd/server.c | 170 +++++++++++----- apps/silcd/server.h | 10 +- apps/silcd/server_backup.c | 2 +- apps/silcd/server_internal.h | 8 + apps/silcd/server_util.c | 15 ++ apps/silcd/server_util.h | 4 + apps/silcd/serverconfig.c | 269 ++++++++++++++++---------- apps/silcd/serverconfig.h | 133 ++++++------- doc/example_silcd.conf.in | 93 +++++++-- doc/silcalgs.conf | 4 + lib/silcske/silcske.c | 12 +- lib/silcske/silcske.h | 6 +- 19 files changed, 515 insertions(+), 272 deletions(-) diff --git a/CHANGES b/CHANGES index 4189c155..b7a03848 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,23 @@ Sat Feb 16 13:44:24 EET 2002 Johnny Mnemonic little timeout after connecting. The affected file is lib/silcclient/client.c. + * Added following new config file settings: + channel_rekey_secs, key_exchange_rekey, key_exchange_pfs, + key_exchange_timeout, conn_auth_timeout, connections_max, + links_max. + + Implemented all the new config settings handling in the server. + + Optimized the use of SKE Mutual flag usage. Use it only + if connection authentication protocol is not based in public + key authentication. + + Renamed all SilcServerConfigSection* to SilcServerConfig* + to have a bit shorter names. + + Affected files silcd/serverconfig.[ch], server.[ch], and + protocol.[ch]. + Sat Feb 16 02:46:43 CET 2002 Johnny Mnemonic * Cleaned up the listening sockets code, preparing for the rehash diff --git a/TODO b/TODO index eae63e9a..c8d44d4e 100644 --- a/TODO +++ b/TODO @@ -37,19 +37,9 @@ TODO/bugs In SILC Server o Configuration file additions: - o Allow configuration of protocol execution timeouts. This - includes SKE, CONN_AUTH and REKEY timeouts. Check all - "XXX hardcoded" from the code for these. - - o IP address fields in configuration file should accept mask - format as well, IP/MASK, and not just plain IP. This would - allow subnet filtering etc. - - o Add channel key rekey default timeout. - - o Add (advanced options in General) to set how often certain ID - caches are purged (could be used to optimize the server's - behaviour). + o Add incoming connection frequency, incoming connection frequency + for single IP address, key exchange frequency, key exchange + frequency for single IP. Add also frequency base. o Add hashed passwords to config file. diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index f86ff03d..11b33fc0 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -590,7 +590,7 @@ void silc_disconnect(SilcClient client, SilcClientConnection conn) SILC_LOG_DEBUG(("Start")); - if (server->conn) { + if (server->conn && server->conn->local_entry) { nicklist_rename_unique(SERVER(server), server->conn->local_entry, server->nick, server->conn->local_entry, diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 9d521036..5221c09e 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -4583,7 +4583,7 @@ SILC_SERVER_CMD_FUNC(oper) SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; unsigned char *username, *auth; uint32 tmp_len; - SilcServerConfigSectionAdmin *admin; + SilcServerConfigAdmin *admin; SilcIDListData idata = (SilcIDListData)client; bool result = FALSE; @@ -4670,7 +4670,7 @@ SILC_SERVER_CMD_FUNC(silcoper) SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data; unsigned char *username, *auth; uint32 tmp_len; - SilcServerConfigSectionAdmin *admin; + SilcServerConfigAdmin *admin; SilcIDListData idata = (SilcIDListData)client; bool result = FALSE; diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 0956be2d..98800ee1 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -2499,9 +2499,9 @@ void silc_server_connection_auth_request(SilcServer server, SilcSocketConnection sock, SilcPacketContext *packet) { - SilcServerConfigSectionClient *client = NULL; + SilcServerConfigClient *client = NULL; uint16 conn_type; - int ret, port; + int ret; SilcAuthMethod auth_meth = SILC_AUTH_NONE; SILC_LOG_DEBUG(("Start")); @@ -2522,10 +2522,9 @@ void silc_server_connection_auth_request(SilcServer server, /* Get the authentication method for the client */ auth_meth = SILC_AUTH_NONE; - port = server->sockets[server->sock]->port; /* Listenning port */ - client = silc_server_config_find_client(server, sock->ip, port); + client = silc_server_config_find_client(server, sock->ip); if (!client) - client = silc_server_config_find_client(server, sock->hostname, port); + client = silc_server_config_find_client(server, sock->hostname); if (client) { if (client->passphrase) { if (client->publickey && !server->config->prefer_passphrase_auth) diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index afa0ad43..7e6b1631 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -283,7 +283,7 @@ int silc_server_protocol_ke_set_keys(SilcServer server, keymat->send_enc_key, keymat->enc_key_len / 8); idata->rekey->enc_key_len = keymat->enc_key_len / 8; - if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS) + if (ske->prop->flags & SILC_SKE_SP_FLAG_PFS) idata->rekey->pfs = TRUE; idata->rekey->ske_group = silc_ske_group_get_number(group); @@ -471,12 +471,12 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange) properties packet from initiator. */ status = silc_ske_responder_start(ske, ctx->rng, ctx->sock, silc_version_string, - ctx->packet->buffer, TRUE); + ctx->packet->buffer, ctx->flags); } else { SilcSKEStartPayload *start_payload; /* Assemble security properties. */ - silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_MUTUAL, + silc_ske_assemble_security_properties(ske, ctx->flags, silc_version_string, &start_payload); @@ -953,7 +953,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) /* Remote end is client */ if (conn_type == SILC_SOCKET_TYPE_CLIENT) { - SilcServerConfigSectionClient *client = ctx->cconfig; + SilcServerConfigClient *client = ctx->cconfig; if (client) { ret = silc_server_get_authentication(ctx, client->passphrase, @@ -982,7 +982,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) /* Remote end is server */ if (conn_type == SILC_SOCKET_TYPE_SERVER) { - SilcServerConfigSectionServer *serv = ctx->sconfig; + SilcServerConfigServer *serv = ctx->sconfig; if (serv) { ret = silc_server_get_authentication(ctx, serv->passphrase, @@ -1011,7 +1011,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) /* Remote end is router */ if (conn_type == SILC_SOCKET_TYPE_ROUTER) { - SilcServerConfigSectionRouter *serv = ctx->rconfig; + SilcServerConfigRouter *serv = ctx->rconfig; if (serv) { ret = silc_server_get_authentication(ctx, serv->passphrase, diff --git a/apps/silcd/protocol.h b/apps/silcd/protocol.h index 26be5e89..c2b30e5e 100644 --- a/apps/silcd/protocol.h +++ b/apps/silcd/protocol.h @@ -51,6 +51,7 @@ typedef struct { SilcTask timeout_task; SilcPacketContext *packet; + SilcSKESecurityPropertyFlag flags; SilcSKE ske; SilcSKEKeyMaterial *keymat; } SilcServerKEInternalContext; diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 75c9cdc3..c2caa843 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -157,8 +157,7 @@ int silc_server_init(SilcServer server) /* Create a listening server */ sock = silc_net_create_server(server->config->server_info->port, - server->config->server_info->server_ip); - /* XXX What if I want my errno? Where is my errno?!? -Johnny */ + server->config->server_info->server_ip); if (sock < 0) { SILC_LOG_ERROR(("Could not create server listener: %s on %hu", server->config->server_info->server_ip, @@ -184,7 +183,7 @@ int silc_server_init(SilcServer server) all connections will have entry in this table (it is a table of pointers to the actual object that is allocated individually later). */ - server->sockets = silc_calloc(SILC_SERVER_MAX_CONNECTIONS, + server->sockets = silc_calloc(server->config->param.connections_max, sizeof(*server->sockets)); do { @@ -252,7 +251,7 @@ int silc_server_init(SilcServer server) silc_server_protocols_register(); /* Initialize the scheduler. */ - server->schedule = silc_schedule_init(SILC_SERVER_MAX_CONNECTIONS); + server->schedule = silc_schedule_init(server->config->param.connections_max); if (!server->schedule) goto err; @@ -282,7 +281,7 @@ int silc_server_init(SilcServer server) /* If server connections has been configured then we must be router as normal server cannot have server connections, only router connections. */ if (server->config->servers) { - SilcServerConfigSectionServer *ptr = server->config->servers; + SilcServerConfigServer *ptr = server->config->servers; server->server_type = SILC_ROUTER; while (ptr) { @@ -477,6 +476,7 @@ void silc_server_start_key_exchange(SilcServer server, SilcSocketConnection newsocket; SilcProtocol protocol; SilcServerKEInternalContext *proto_ctx; + SilcServerConfigRouter *conn = sconn->conn; void *context; /* Cancel any possible retry timeouts */ @@ -507,6 +507,12 @@ void silc_server_start_key_exchange(SilcServer server, proto_ctx->rng = server->rng; proto_ctx->responder = FALSE; + /* Set Key Exchange flags from configuration, but fall back to global + settings too. */ + SILC_GET_SKE_FLAGS(conn, proto_ctx); + if (server->config->param.key_exchange_pfs) + proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS; + /* Perform key exchange protocol. silc_server_connect_to_router_second will be called after the protocol is finished. */ silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE, @@ -519,7 +525,7 @@ void silc_server_start_key_exchange(SilcServer server, proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock, silc_server_timeout_remote, - server, 60, 0, /* XXX hardcoded */ + server, server->config->key_exchange_timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); @@ -545,9 +551,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_retry) { SilcServerConnection sconn = (SilcServerConnection)context; SilcServer server = sconn->server; - SilcServerConfigSectionConnectionParam *param; - - param = (sconn->param ? sconn->param : &server->config->param); + SilcServerConfigConnParams *param = + (sconn->param ? sconn->param : &server->config->param); SILC_LOG_INFO(("Retrying connecting to a router")); @@ -564,7 +569,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_retry) silc_rng_get_rn32(server->rng) % SILC_SERVER_RETRY_RANDOMIZER; /* If we've reached max retry count, give up. */ - if (sconn->retry_count > param->reconnect_count && + if (sconn->retry_count > param->reconnect_count && param->reconnect_keep_trying == FALSE) { SILC_LOG_ERROR(("Could not connect to router, giving up")); silc_free(sconn->remote_host); @@ -620,7 +625,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) { SilcServer server = (SilcServer)context; SilcServerConnection sconn; - SilcServerConfigSectionRouter *ptr; + SilcServerConfigRouter *ptr; SILC_LOG_DEBUG(("Connecting to router(s)")); @@ -690,7 +695,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) SilcServerConnection sconn = (SilcServerConnection)ctx->context; SilcSocketConnection sock = ctx->sock; SilcServerConnAuthInternalContext *proto_ctx; - SilcServerConfigSectionRouter *conn = NULL; + SilcServerConfigRouter *conn = NULL; SILC_LOG_DEBUG(("Start")); @@ -816,7 +821,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock->sock, silc_server_timeout_remote, - (void *)server, 15, 0, /* XXX hardcoded */ + (void *)server, + server->config->conn_auth_timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); @@ -841,7 +847,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) unsigned char *id_string; uint32 id_len; SilcIDListData idata; - SilcServerConfigSectionConnectionParam *param; + SilcServerConfigConnParams *param; SILC_LOG_DEBUG(("Start")); @@ -923,8 +929,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) param = (sconn->param ? sconn->param : &server->config->param); /* Perform keepalive. The `hb_context' will be freed automatically - when finally calling the silc_socket_free function. XXX hardcoded - timeout!! */ + when finally calling the silc_socket_free function. */ hb_context = silc_calloc(1, sizeof(*hb_context)); hb_context->server = server; silc_socket_set_heartbeat(sock, param->keepalive_secs, hb_context, @@ -932,7 +937,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) server->schedule); /* Register re-key timeout */ - idata->rekey->timeout = 3600; /* XXX hardcoded */ + idata->rekey->timeout = param->key_exchange_rekey; idata->rekey->context = (void *)server; silc_schedule_task_add(server->schedule, sock->sock, silc_server_rekey_callback, @@ -1002,8 +1007,10 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, { SilcServer server = (SilcServer)context; SilcServerKEInternalContext *proto_ctx; - void *cconfig, *sconfig, *rconfig; - SilcServerConfigSectionDeny *deny; + SilcServerConfigClient *cconfig = NULL; + SilcServerConfigServer *sconfig = NULL; + SilcServerConfigRouter *rconfig = NULL; + SilcServerConfigDeny *deny; int port; SILC_LOG_DEBUG(("Start")); @@ -1052,13 +1059,16 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, /* Check whether we have configred this sort of connection at all. We have to check all configurations since we don't know what type of connection this is. */ - if (!(cconfig = silc_server_config_find_client(server, sock->ip, port))) - cconfig = silc_server_config_find_client(server, sock->hostname, port); + if (!(cconfig = silc_server_config_find_client(server, sock->ip))) + cconfig = silc_server_config_find_client(server, sock->hostname); if (!(sconfig = silc_server_config_find_server_conn(server, sock->ip))) sconfig = silc_server_config_find_server_conn(server, sock->hostname); - if (!(rconfig = silc_server_config_find_router_conn(server, sock->ip, port))) - rconfig = silc_server_config_find_router_conn(server, sock->hostname, - sock->port); + if (server->server_type == SILC_ROUTER) { + if (!(rconfig = silc_server_config_find_router_conn(server, + sock->ip, port))) + rconfig = silc_server_config_find_router_conn(server, sock->hostname, + sock->port); + } if (!cconfig && !sconfig && !rconfig) { SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, sock->ip)); @@ -1082,6 +1092,15 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, proto_ctx->sconfig = sconfig; proto_ctx->rconfig = rconfig; + /* Take flags for key exchange. Since we do not know what type of connection + this is, we go through all found configuratios and use the global ones + as well. This will result always into strictest key exchange flags. */ + SILC_GET_SKE_FLAGS(cconfig, proto_ctx); + SILC_GET_SKE_FLAGS(sconfig, proto_ctx); + SILC_GET_SKE_FLAGS(rconfig, proto_ctx); + if (server->config->param.key_exchange_pfs) + proto_ctx->flags |= SILC_SKE_SP_FLAG_PFS; + /* Prepare the connection for key exchange protocol. We allocate the protocol but will not start it yet. The connector will be the initiator of the protocol thus we will wait for initiation from @@ -1092,13 +1111,12 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, silc_server_accept_new_connection_second); /* Register a timeout task that will be executed if the connector - will not start the key exchange protocol within 60 seconds. For - now, this is a hard coded limit. After the timeout the connection will - be closed if the key exchange protocol has not been started. */ + will not start the key exchange protocol within specified timeout + and the connection will be closed. */ proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock->sock, silc_server_timeout_remote, - context, 60, 0, /* XXX hardcoded */ + context, server->config->key_exchange_timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); } @@ -1123,12 +1141,12 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection) return; } - /* Check max connections */ - if (sock > SILC_SERVER_MAX_CONNECTIONS) { - SILC_LOG_ERROR(("Refusing connection, server is full")); + /* Check for maximum allowed connections */ + if (sock > server->config->param.connections_max) { + SILC_LOG_ERROR(("Refusing connection, server is full, try again later")); server->stat.conn_failures++; return; - } + } /* Set socket options */ silc_net_set_socket_nonblock(sock); @@ -1246,7 +1264,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) proto_ctx->timeout_task = silc_schedule_task_add(server->schedule, sock->sock, silc_server_timeout_remote, - (void *)server, 60, 0, /* XXX hardcoded */ + (void *)server, + server->config->conn_auth_timeout, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); } @@ -1265,7 +1284,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) SilcServerHBContext hb_context; SilcUnknownEntry entry = (SilcUnknownEntry)sock->user_data; void *id_entry; - uint32 hearbeat_timeout = SILC_SERVER_KEEPALIVE; + uint32 hearbeat_timeout = server->config->param.keepalive_secs; + uint32 num_sockets; SILC_LOG_DEBUG(("Start")); @@ -1290,11 +1310,36 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) entry->data.last_receive = time(NULL); + num_sockets = silc_server_num_sockets_by_ip(server, sock->ip); + switch (ctx->conn_type) { case SILC_SOCKET_TYPE_CLIENT: { SilcClientEntry client; - SilcServerConfigSectionClient *conn = ctx->cconfig; + SilcServerConfigClient *conn = ctx->cconfig; + uint32 max_per_host = server->config->param.connections_max_per_host; + + /* Check for maximum connections limit */ + if (conn->param) { + if (conn->param->connections_max && + server->stat.my_clients >= conn->param->connections_max) { + silc_server_disconnect_remote(server, sock, + "Server closed connection: " + "Server is full, try again later"); + server->stat.auth_failures++; + goto out; + } + + max_per_host = conn->param->connections_max_per_host; + } + + if (num_sockets > max_per_host) { + silc_server_disconnect_remote(server, sock, + "Server closed connection: " + "Too many connections from your host"); + server->stat.auth_failures++; + goto out; + } SILC_LOG_DEBUG(("Remote host is client")); SILC_LOG_INFO(("Connection from %s (%s) is client", sock->hostname, @@ -1339,29 +1384,60 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) bool backup_router = FALSE; char *backup_replace_ip = NULL; uint16 backup_replace_port = 0; - SilcServerConfigSectionServer *sconn = ctx->sconfig; - SilcServerConfigSectionRouter *rconn = ctx->rconfig; + SilcServerConfigServer *sconn = ctx->sconfig; + SilcServerConfigRouter *rconn = ctx->rconfig; + uint32 max_per_host = server->config->param.connections_max_per_host; if (ctx->conn_type == SILC_SOCKET_TYPE_ROUTER && rconn) { + if (rconn->param) { + /* Check for maximum connections limit */ + if (rconn->param->connections_max && + server->stat.my_routers >= rconn->param->connections_max) { + silc_server_disconnect_remote(server, sock, + "Server closed connection: " + "Server is full, try again later"); + server->stat.auth_failures++; + goto out; + } + max_per_host = rconn->param->connections_max_per_host; + + if (rconn->param->keepalive_secs) + hearbeat_timeout = rconn->param->keepalive_secs; + } + initiator = rconn->initiator; backup_local = rconn->backup_local; backup_router = rconn->backup_router; backup_replace_ip = rconn->backup_replace_ip; backup_replace_port = rconn->backup_replace_port; - - if (rconn->param) { - if (rconn->param->keepalive_secs) - hearbeat_timeout = rconn->param->keepalive_secs; - } } if (ctx->conn_type == SILC_SOCKET_TYPE_SERVER && sconn) { - backup_router = sconn->backup_router; - if (sconn->param) { + /* Check for maximum connections limit */ + if (sconn->param->connections_max && + server->stat.my_servers >= sconn->param->connections_max) { + silc_server_disconnect_remote(server, sock, + "Server closed connection: " + "Server is full, try again later"); + server->stat.auth_failures++; + goto out; + } + max_per_host = sconn->param->connections_max_per_host; + if (sconn->param->keepalive_secs) hearbeat_timeout = sconn->param->keepalive_secs; } + + backup_router = sconn->backup_router; + } + + if (num_sockets > max_per_host) { + silc_server_disconnect_remote(server, sock, + "Server closed connection: " + "Too many connections from your host"); + server->stat.auth_failures++; + goto out; } SILC_LOG_DEBUG(("Remote host is %s", @@ -3010,7 +3086,8 @@ bool silc_server_create_channel_key(SilcServer server, channel->rekey->task = silc_schedule_task_add(server->schedule, 0, silc_server_channel_key_rekey, - (void *)channel->rekey, 3600, 0, + (void *)channel->rekey, + server->config->channel_rekey_secs, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } @@ -3122,7 +3199,8 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, channel->rekey->task = silc_schedule_task_add(server->schedule, 0, silc_server_channel_key_rekey, - (void *)channel->rekey, 3600, 0, + (void *)channel->rekey, + server->config->channel_rekey_secs, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } diff --git a/apps/silcd/server.h b/apps/silcd/server.h index afff2b97..9e626f5e 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -63,8 +63,6 @@ typedef struct { void *callback_context; } *SilcServerConnection; -#define SILC_SERVER_MAX_CONNECTIONS 1000 - /* General definitions */ /* SILC port */ @@ -86,7 +84,13 @@ typedef struct { #define SILC_SERVER_RETRY_INTERVAL_MIN 10 /* Min retry timeout */ #define SILC_SERVER_RETRY_INTERVAL_MAX 600 /* Max generated timeout */ -#define SILC_SERVER_KEEPALIVE 300 /* Heartbeat interval */ +#define SILC_SERVER_KEEPALIVE 300 /* Heartbeat interval */ +#define SILC_SERVER_CHANNEL_REKEY 3600 /* Channel rekey interval */ +#define SILC_SERVER_REKEY 3600 /* Session rekey interval */ +#define SILC_SERVER_SKE_TIMEOUT 60 /* SKE timeout */ +#define SILC_SERVER_CONNAUTH_TIMEOUT 60 /* CONN_AUTH timeout */ +#define SILC_SERVER_MAX_CONNECTIONS 1000 /* Max connections */ +#define SILC_SERVER_MAX_CONNECTIONS_SINGLE 1000 /* Max connections per host */ /* Macros */ diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index 1c553e96..9591cade 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -867,7 +867,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) protocol->state++; } else { /* Responder of the protocol. */ - SilcServerConfigSectionRouter *primary; + SilcServerConfigRouter *primary; /* We should have received START or START_GLOBAL packet */ if (ctx->type != SILC_SERVER_BACKUP_START && diff --git a/apps/silcd/server_internal.h b/apps/silcd/server_internal.h index 423e37e6..f4f1d10c 100644 --- a/apps/silcd/server_internal.h +++ b/apps/silcd/server_internal.h @@ -175,6 +175,14 @@ do { \ } \ } while(0) +#define SILC_GET_SKE_FLAGS(x, p) \ + if ((x)) { \ + if ((x)->param && (x)->param->key_exchange_pfs) \ + (p)->flags |= SILC_SKE_SP_FLAG_PFS; \ + if (!(x)->publickey) \ + (p)->flags |= SILC_SKE_SP_FLAG_MUTUAL; \ + } + /* Prototypes */ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final); diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 5c06bcd1..3592df58 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -787,3 +787,18 @@ char *silc_server_name_modify_bad(const char *name, uint32 name_len) return newname; } + +/* Find number of sockets by IP address indicated by `ip'. Returns 0 if + socket connections with the IP address does not exist. */ + +uint32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip) +{ + int i, count; + + for (i = 0, count = 0; i < server->config->param.connections_max; i++) { + if (server->sockets[i] && !strcmp(server->sockets[i]->ip, ip)) + count++; + } + + return count; +} diff --git a/apps/silcd/server_util.h b/apps/silcd/server_util.h index 9cfe1607..665647f0 100644 --- a/apps/silcd/server_util.h +++ b/apps/silcd/server_util.h @@ -81,4 +81,8 @@ bool silc_server_name_bad_chars(const char *name, uint32 name_len); allocated nickname that does not include bad characters. */ char *silc_server_name_modify_bad(const char *name, uint32 name_len); +/* Find number of sockets by IP address indicated by `ip'. Returns 0 if + socket connections with the IP address does not exist. */ +uint32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip); + #endif /* SERVER_UTIL_H */ diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 6ee3ebc6..d6754da5 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -63,11 +63,36 @@ silc_free(__section__->passphrase); \ silc_pkcs_public_key_free(__section__->publickey) +/* Set default values to those parameters that have not been defined */ +static void +my_set_param_defaults(SilcServerConfigConnParams *params, + SilcServerConfigConnParams *defaults) +{ +#define SET_PARAM_DEFAULT(p, d) \ + (params->p ? params->p : (defaults && defaults->p ? defaults->p : d)) + + params->connections_max = + SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS); + params->connections_max_per_host = + SET_PARAM_DEFAULT(connections_max_per_host, + SILC_SERVER_MAX_CONNECTIONS_SINGLE); + params->keepalive_secs = + SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE); + params->reconnect_count = + SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT); + params->reconnect_interval = + SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN); + params->reconnect_interval_max = + SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX); + params->key_exchange_rekey = + SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY); +} + /* Find connection parameters by the parameter block name. */ -static SilcServerConfigSectionConnectionParam * +static SilcServerConfigConnParams * my_find_param(SilcServerConfig config, const char *name, uint32 line) { - SilcServerConfigSectionConnectionParam *param; + SilcServerConfigConnParams *param; for (param = config->conn_params; param; param = param->next) { if (!strcasecmp(param->name, name)) @@ -129,6 +154,12 @@ SILC_CONFIG_CALLBACK(fetch_generic) else if (!strcmp(name, "require_reverse_lookup")) { config->require_reverse_lookup = *(bool *)val; } + else if (!strcmp(name, "connections_max")) { + config->param.connections_max = (uint32) *(int *)val; + } + else if (!strcmp(name, "connections_max_per_host")) { + config->param.connections_max_per_host = (uint32) *(int *)val; + } else if (!strcmp(name, "keepalive_secs")) { config->param.keepalive_secs = (uint32) *(int *)val; } @@ -144,6 +175,21 @@ SILC_CONFIG_CALLBACK(fetch_generic) else if (!strcmp(name, "reconnect_keep_trying")) { config->param.reconnect_keep_trying = *(bool *)val; } + else if (!strcmp(name, "key_exchange_rekey")) { + config->param.key_exchange_rekey = (uint32) *(int *)val; + } + else if (!strcmp(name, "key_exchange_pfs")) { + config->param.key_exchange_pfs = *(bool *)val; + } + else if (!strcmp(name, "channel_rekey_secs")) { + config->channel_rekey_secs = (uint32) *(int *)val; + } + else if (!strcmp(name, "key_exchange_timeout")) { + config->key_exchange_timeout = (uint32) *(int *)val; + } + else if (!strcmp(name, "conn_auth_timeout")) { + config->conn_auth_timeout = (uint32) *(int *)val; + } else return SILC_CONFIG_EINTERNAL; @@ -155,7 +201,7 @@ SILC_CONFIG_CALLBACK(fetch_generic) SILC_CONFIG_CALLBACK(fetch_cipher) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionCipher); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigCipher); SERVER_CONFIG_DEBUG(("Received CIPHER type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -175,7 +221,7 @@ SILC_CONFIG_CALLBACK(fetch_cipher) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionCipher *) config->tmp; + tmp = (SilcServerConfigCipher *) config->tmp; } /* Identify and save this value */ @@ -207,7 +253,7 @@ SILC_CONFIG_CALLBACK(fetch_cipher) SILC_CONFIG_CALLBACK(fetch_hash) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHash); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHash); SERVER_CONFIG_DEBUG(("Received HASH type=%d name=%s (val=%x)", type, name, context)); @@ -228,7 +274,7 @@ SILC_CONFIG_CALLBACK(fetch_hash) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionHash *) config->tmp; + tmp = (SilcServerConfigHash *) config->tmp; } /* Identify and save this value */ @@ -260,7 +306,7 @@ SILC_CONFIG_CALLBACK(fetch_hash) SILC_CONFIG_CALLBACK(fetch_hmac) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionHmac); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigHmac); SERVER_CONFIG_DEBUG(("Received HMAC type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -280,7 +326,7 @@ SILC_CONFIG_CALLBACK(fetch_hmac) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionHmac *) config->tmp; + tmp = (SilcServerConfigHmac *) config->tmp; } /* Identify and save this value */ @@ -309,7 +355,7 @@ SILC_CONFIG_CALLBACK(fetch_hmac) SILC_CONFIG_CALLBACK(fetch_pkcs) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionPkcs); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigPkcs); SERVER_CONFIG_DEBUG(("Received PKCS type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -329,7 +375,7 @@ SILC_CONFIG_CALLBACK(fetch_pkcs) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionPkcs *) config->tmp; + tmp = (SilcServerConfigPkcs *) config->tmp; } /* Identify and save this value */ @@ -351,12 +397,12 @@ SILC_CONFIG_CALLBACK(fetch_pkcs) SILC_CONFIG_CALLBACK(fetch_serverinfo) { SilcServerConfig config = (SilcServerConfig) context; - SilcServerConfigSectionServerInfo *server_info = config->server_info; + SilcServerConfigServerInfo *server_info = config->server_info; int got_errno = 0; /* if there isn't the struct alloc it */ if (!server_info) - config->server_info = server_info = (SilcServerConfigSectionServerInfo *) + config->server_info = server_info = (SilcServerConfigServerInfo *) silc_calloc(1, sizeof(*server_info)); if (type == SILC_CONFIG_ARG_BLOCK) { @@ -448,8 +494,8 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) SILC_CONFIG_CALLBACK(fetch_logging) { SilcServerConfig config = (SilcServerConfig) context; - SilcServerConfigSectionLogging *tmp = - (SilcServerConfigSectionLogging *) config->tmp; + SilcServerConfigLogging *tmp = + (SilcServerConfigLogging *) config->tmp; int got_errno; if (!strcmp(name, "quicklogs")) { @@ -481,7 +527,7 @@ SILC_CONFIG_CALLBACK(fetch_logging) else if (!strcmp(name, "file")) { if (!tmp) { /* FIXME: what the fuck is this? */ config->tmp = silc_calloc(1, sizeof(*tmp)); - tmp = (SilcServerConfigSectionLogging *) config->tmp; + tmp = (SilcServerConfigLogging *) config->tmp; } if (tmp->file) { got_errno = SILC_CONFIG_EMISSFIELDS; goto got_err; @@ -491,7 +537,7 @@ SILC_CONFIG_CALLBACK(fetch_logging) else if (!strcmp(name, "size")) { if (!tmp) { config->tmp = silc_calloc(1, sizeof(*tmp)); - tmp = (SilcServerConfigSectionLogging *) config->tmp; + tmp = (SilcServerConfigLogging *) config->tmp; } tmp->maxsize = *(uint32 *) val; } @@ -508,7 +554,7 @@ SILC_CONFIG_CALLBACK(fetch_logging) SILC_CONFIG_CALLBACK(fetch_connparam) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionConnectionParam); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigConnParams); SERVER_CONFIG_DEBUG(("Received CONNPARAM type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -517,6 +563,14 @@ SILC_CONFIG_CALLBACK(fetch_connparam) if (!tmp) return SILC_CONFIG_OK; + if (!tmp->name) { + got_errno = SILC_CONFIG_EMISSFIELDS; + goto got_err; + } + + /* Set defaults */ + my_set_param_defaults(tmp, &config->param); + SILC_SERVER_CONFIG_LIST_APPENDTMP(config->conn_params); config->tmp = NULL; return SILC_CONFIG_OK; @@ -525,13 +579,19 @@ SILC_CONFIG_CALLBACK(fetch_connparam) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionConnectionParam *) config->tmp; + tmp = (SilcServerConfigConnParams *) config->tmp; } if (!strcmp(name, "name")) { CONFIG_IS_DOUBLE(tmp->name); tmp->name = (*(char *)val ? strdup((char *) val) : NULL); } + else if (!strcmp(name, "connections_max")) { + tmp->connections_max = *(uint32 *)val; + } + else if (!strcmp(name, "connections_max_per_host")) { + tmp->connections_max_per_host = *(uint32 *)val; + } else if (!strcmp(name, "keepalive_secs")) { tmp->keepalive_secs = *(uint32 *)val; } @@ -547,6 +607,12 @@ SILC_CONFIG_CALLBACK(fetch_connparam) else if (!strcmp(name, "reconnect_keep_trying")) { tmp->reconnect_keep_trying = *(bool *)val; } + else if (!strcmp(name, "key_exchange_rekey")) { + tmp->key_exchange_rekey = *(uint32 *)val; + } + else if (!strcmp(name, "key_exchange_pfs")) { + tmp->key_exchange_pfs = *(bool *)val; + } else return SILC_CONFIG_EINTERNAL; @@ -561,7 +627,7 @@ SILC_CONFIG_CALLBACK(fetch_connparam) SILC_CONFIG_CALLBACK(fetch_client) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionClient); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigClient); SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -569,7 +635,7 @@ SILC_CONFIG_CALLBACK(fetch_client) /* alloc tmp before block checking (empty sub-blocks are welcome here) */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionClient *) config->tmp; + tmp = (SilcServerConfigClient *) config->tmp; } if (type == SILC_CONFIG_ARG_BLOCK) { @@ -599,16 +665,7 @@ SILC_CONFIG_CALLBACK(fetch_client) goto got_err; } } - else if (!strcmp(name, "port")) { - int port = *(int *)val; - if ((port <= 0) || (port > 65535)) { - fprintf(stderr, "Invalid port number!\n"); - got_errno = SILC_CONFIG_ESILENT; - goto got_err; - } - tmp->port = (uint16) port; - } - else if (!strcmp(name, "param")) { + else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); tmp->param = my_find_param(config, (char *) val, line); if (!tmp->param) { /* error already output */ @@ -630,7 +687,7 @@ SILC_CONFIG_CALLBACK(fetch_client) SILC_CONFIG_CALLBACK(fetch_admin) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionAdmin); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigAdmin); SERVER_CONFIG_DEBUG(("Received CLIENT type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -648,7 +705,7 @@ SILC_CONFIG_CALLBACK(fetch_admin) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionAdmin *) config->tmp; + tmp = (SilcServerConfigAdmin *) config->tmp; } /* Identify and save this value */ @@ -695,7 +752,7 @@ SILC_CONFIG_CALLBACK(fetch_admin) SILC_CONFIG_CALLBACK(fetch_deny) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionDeny); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigDeny); SERVER_CONFIG_DEBUG(("Received DENY type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -714,7 +771,7 @@ SILC_CONFIG_CALLBACK(fetch_deny) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionDeny *) config->tmp; + tmp = (SilcServerConfigDeny *) config->tmp; } /* Identify and save this value */ @@ -726,7 +783,8 @@ SILC_CONFIG_CALLBACK(fetch_deny) int port = *(int *)val; if ((port <= 0) || (port > 65535)) { fprintf(stderr, "Invalid port number!\n"); - got_errno = SILC_CONFIG_ESILENT; goto got_err; + got_errno = SILC_CONFIG_ESILENT; + goto got_err; } tmp->port = (uint16) port; } @@ -748,7 +806,7 @@ SILC_CONFIG_CALLBACK(fetch_deny) SILC_CONFIG_CALLBACK(fetch_server) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionServer); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServer); SERVER_CONFIG_DEBUG(("Received SERVER type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -758,8 +816,6 @@ SILC_CONFIG_CALLBACK(fetch_server) if (!tmp) /* empty sub-block? */ return SILC_CONFIG_OK; - /* XXX mandatory fields for server? */ - /* the temporary struct is ok, append it to the list */ SILC_SERVER_CONFIG_LIST_APPENDTMP(config->servers); config->tmp = NULL; @@ -769,7 +825,7 @@ SILC_CONFIG_CALLBACK(fetch_server) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionServer *) config->tmp; + tmp = (SilcServerConfigServer *) config->tmp; } /* Identify and save this value */ @@ -796,7 +852,7 @@ SILC_CONFIG_CALLBACK(fetch_server) CONFIG_IS_DOUBLE(tmp->version); tmp->version = strdup((char *) val); } - else if (!strcmp(name, "param")) { + else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); tmp->param = my_find_param(config, (char *) val, line); if (!tmp->param) { /* error already output */ @@ -823,7 +879,7 @@ SILC_CONFIG_CALLBACK(fetch_server) SILC_CONFIG_CALLBACK(fetch_router) { - SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigSectionRouter); + SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigRouter); SERVER_CONFIG_DEBUG(("Received ROUTER type=%d name=\"%s\" (val=%x)", type, name, context)); @@ -832,8 +888,6 @@ SILC_CONFIG_CALLBACK(fetch_router) if (!tmp) /* empty sub-block? */ return SILC_CONFIG_OK; - /* XXX mandatory fields for router? */ - /* the temporary struct is ok, append it to the list */ SILC_SERVER_CONFIG_LIST_APPENDTMP(config->routers); config->tmp = NULL; @@ -843,7 +897,7 @@ SILC_CONFIG_CALLBACK(fetch_router) /* if there isn't a temporary struct alloc one */ if (!tmp) { config->tmp = silc_calloc(1, sizeof(*findtmp)); - tmp = (SilcServerConfigSectionRouter *) config->tmp; + tmp = (SilcServerConfigRouter *) config->tmp; } /* Identify and save this value */ @@ -878,7 +932,7 @@ SILC_CONFIG_CALLBACK(fetch_router) CONFIG_IS_DOUBLE(tmp->version); tmp->version = strdup((char *) val); } - else if (!strcmp(name, "param")) { + else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); tmp->param = my_find_param(config, (char *) val, line); if (!tmp->param) { /* error already output */ @@ -914,11 +968,18 @@ static const SilcConfigTable table_general[] = { { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "connections_max_per_host", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, + { "channel_rekey_secs", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "key_exchange_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, + { "conn_auth_timeout", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, { 0, 0, 0, 0 } }; @@ -987,11 +1048,15 @@ static const SilcConfigTable table_logging[] = { static const SilcConfigTable table_connparam[] = { { "name", SILC_CONFIG_ARG_STR, fetch_connparam, NULL }, { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL }, + { "connections_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, + { "connections_max_per_host",SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, { "keepalive_secs", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, { "reconnect_count", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, { "reconnect_interval", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, { "reconnect_interval_max", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, { "reconnect_keep_trying", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL }, + { "key_exchange_rekey", SILC_CONFIG_ARG_INT, fetch_connparam, NULL }, + { "key_exchange_pfs", SILC_CONFIG_ARG_TOGGLE, fetch_connparam, NULL }, { 0, 0, 0, 0 } }; @@ -999,8 +1064,7 @@ static const SilcConfigTable table_client[] = { { "host", SILC_CONFIG_ARG_STRE, fetch_client, NULL }, { "passphrase", SILC_CONFIG_ARG_STR, fetch_client, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_client, NULL }, - { "port", SILC_CONFIG_ARG_INT, fetch_client, NULL }, - { "param", SILC_CONFIG_ARG_STR, fetch_client, NULL }, + { "params", SILC_CONFIG_ARG_STR, fetch_client, NULL }, { 0, 0, 0, 0 } }; @@ -1011,7 +1075,7 @@ static const SilcConfigTable table_admin[] = { { "passphrase", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { "port", SILC_CONFIG_ARG_INT, fetch_admin, NULL }, - { "param", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, + { "params", SILC_CONFIG_ARG_STR, fetch_admin, NULL }, { 0, 0, 0, 0 } }; @@ -1027,7 +1091,7 @@ static const SilcConfigTable table_serverconn[] = { { "passphrase", SILC_CONFIG_ARG_STR, fetch_server, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_server, NULL }, { "versionid", SILC_CONFIG_ARG_STR, fetch_server, NULL }, - { "param", SILC_CONFIG_ARG_STR, fetch_server, NULL }, + { "params", SILC_CONFIG_ARG_STR, fetch_server, NULL }, { "backup", SILC_CONFIG_ARG_TOGGLE, fetch_server, NULL }, { 0, 0, 0, 0 } }; @@ -1038,7 +1102,7 @@ static const SilcConfigTable table_routerconn[] = { { "passphrase", SILC_CONFIG_ARG_STR, fetch_router, NULL }, { "publickey", SILC_CONFIG_ARG_STR, fetch_router, NULL }, { "versionid", SILC_CONFIG_ARG_STR, fetch_router, NULL }, - { "param", SILC_CONFIG_ARG_STR, fetch_router, NULL }, + { "params", SILC_CONFIG_ARG_STR, fetch_router, NULL }, { "initiator", SILC_CONFIG_ARG_TOGGLE, fetch_router, NULL }, { "backuphost", SILC_CONFIG_ARG_STRE, fetch_router, NULL }, { "backupport", SILC_CONFIG_ARG_INT, fetch_router, NULL }, @@ -1054,7 +1118,7 @@ static const SilcConfigTable table_main[] = { { "pkcs", SILC_CONFIG_ARG_BLOCK, fetch_pkcs, table_pkcs }, { "serverinfo", SILC_CONFIG_ARG_BLOCK, fetch_serverinfo, table_serverinfo }, { "logging", SILC_CONFIG_ARG_BLOCK, NULL, table_logging }, - { "connectionparam", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam }, + { "connectionparams", SILC_CONFIG_ARG_BLOCK, fetch_connparam, table_connparam }, { "client", SILC_CONFIG_ARG_BLOCK, fetch_client, table_client }, { "admin", SILC_CONFIG_ARG_BLOCK, fetch_admin, table_admin }, { "deny", SILC_CONFIG_ARG_BLOCK, fetch_deny, table_deny }, @@ -1090,7 +1154,8 @@ SilcServerConfig silc_server_config_alloc(char *filename) /* enter the main parsing loop. When this returns, we have the parsing * result and the object filled (or partially, in case of errors). */ ret = silc_config_main(ent); - SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret, silc_config_strerror(ret))); + SILC_LOG_DEBUG(("Parser returned [ret=%d]: %s", ret, + silc_config_strerror(ret))); /* Check if the parser returned errors */ if (ret) { @@ -1136,7 +1201,7 @@ void silc_server_config_destroy(SilcServerConfig config) /* Destroy the ServerInfo struct */ if (config->server_info) { - register SilcServerConfigSectionServerInfo *si = config->server_info; + register SilcServerConfigServerInfo *si = config->server_info; silc_free(si->server_name); silc_free(si->server_ip); silc_free(si->server_type); @@ -1151,52 +1216,52 @@ void silc_server_config_destroy(SilcServerConfig config) /* Now let's destroy the lists */ - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionCipher, + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher, config->cipher) silc_free(di->name); silc_free(di->module); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHash, config->hash) + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash) silc_free(di->name); silc_free(di->module); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionHmac, config->hmac) + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac) silc_free(di->name); silc_free(di->hash); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionPkcs, config->pkcs) + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigPkcs, config->pkcs) silc_free(di->name); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionClient, + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigClient, config->clients) silc_free(di->host); CONFIG_FREE_AUTH(di); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionAdmin, config->admins) + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigAdmin, config->admins) silc_free(di->host); silc_free(di->user); silc_free(di->nick); CONFIG_FREE_AUTH(di); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionDeny, config->denied) + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigDeny, config->denied) silc_free(di->host); silc_free(di->reason); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionServer, + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigServer, config->servers) silc_free(di->host); silc_free(di->version); CONFIG_FREE_AUTH(di); silc_free(di); } - SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigSectionRouter, + SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigRouter, config->routers) silc_free(di->host); silc_free(di->version); @@ -1212,7 +1277,7 @@ void silc_server_config_destroy(SilcServerConfig config) bool silc_server_config_register_ciphers(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionCipher *cipher = config->cipher; + SilcServerConfigCipher *cipher = config->cipher; char *module_path = config->module_path; SILC_LOG_DEBUG(("Registering configured ciphers")); @@ -1264,9 +1329,11 @@ bool silc_server_config_register_ciphers(SilcServer server) SILC_CIPHER_SIM_SET_KEY)); SILC_LOG_DEBUG(("set_key=%p", cipher_obj.set_key)); cipher_obj.set_key_with_string = - 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_obj.set_key_with_string)); + 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_obj.set_key_with_string)); cipher_obj.encrypt = silc_sim_getsym(sim, silc_sim_symname(alg_name, SILC_CIPHER_SIM_ENCRYPT_CBC)); @@ -1311,7 +1378,7 @@ bool silc_server_config_register_ciphers(SilcServer server) bool silc_server_config_register_hashfuncs(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionHash *hash = config->hash; + SilcServerConfigHash *hash = config->hash; char *module_path = config->module_path; SILC_LOG_DEBUG(("Registering configured hash functions")); @@ -1396,7 +1463,7 @@ bool silc_server_config_register_hashfuncs(SilcServer server) bool silc_server_config_register_hmacs(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionHmac *hmac = config->hmac; + SilcServerConfigHmac *hmac = config->hmac; SILC_LOG_DEBUG(("Registering configured HMACs")); @@ -1427,7 +1494,7 @@ bool silc_server_config_register_hmacs(SilcServer server) bool silc_server_config_register_pkcs(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionPkcs *pkcs = config->pkcs; + SilcServerConfigPkcs *pkcs = config->pkcs; SILC_LOG_DEBUG(("Registering configured PKCS")); @@ -1457,7 +1524,7 @@ bool silc_server_config_register_pkcs(SilcServer server) void silc_server_config_setlogfiles(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionLogging *this; + SilcServerConfigLogging *this; SILC_LOG_DEBUG(("Setting configured log file names")); @@ -1478,26 +1545,18 @@ void silc_server_config_setlogfiles(SilcServer server) /* Returns client authentication information from configuration file by host (name or ip) */ -SilcServerConfigSectionClient * -silc_server_config_find_client(SilcServer server, char *host, int port) +SilcServerConfigClient * +silc_server_config_find_client(SilcServer server, char *host) { SilcServerConfig config = server->config; - SilcServerConfigSectionClient *client; + SilcServerConfigClient *client; - if (!config || !port) { - SILC_LOG_WARNING(("Bogus: config_find_client(config=0x%08x, " - "host=0x%08x \"%s\", port=%hu)", - (uint32) config, (uint32) host, host, port)); - return NULL; - } - if (!host) + if (!config || !host) return NULL; for (client = config->clients; client; client = client->next) { if (client->host && !silc_string_compare(client->host, host)) continue; - if (client->port && (client->port != port)) - continue; break; } @@ -1508,12 +1567,12 @@ silc_server_config_find_client(SilcServer server, char *host, int port) /* Returns admin connection configuration by host, username and/or nickname. */ -SilcServerConfigSectionAdmin * +SilcServerConfigAdmin * silc_server_config_find_admin(SilcServer server, char *host, char *user, char *nick) { SilcServerConfig config = server->config; - SilcServerConfigSectionAdmin *admin; + SilcServerConfigAdmin *admin; /* make sure we have a value for the matching parameters */ if (!host) @@ -1540,11 +1599,11 @@ silc_server_config_find_admin(SilcServer server, char *host, char *user, /* Returns the denied connection configuration entry by host and port. */ -SilcServerConfigSectionDeny * +SilcServerConfigDeny * silc_server_config_find_denied(SilcServer server, char *host, uint16 port) { SilcServerConfig config = server->config; - SilcServerConfigSectionDeny *deny; + SilcServerConfigDeny *deny; /* make sure we have a value for the matching parameters */ if (!config || !port) { @@ -1569,11 +1628,11 @@ silc_server_config_find_denied(SilcServer server, char *host, uint16 port) /* Returns server connection info from server configuartion by host (name or ip). */ -SilcServerConfigSectionServer * +SilcServerConfigServer * silc_server_config_find_server_conn(SilcServer server, char *host) { SilcServerConfig config = server->config; - SilcServerConfigSectionServer *serv = NULL; + SilcServerConfigServer *serv = NULL; if (!host) return NULL; @@ -1593,11 +1652,11 @@ silc_server_config_find_server_conn(SilcServer server, char *host) /* Returns router connection info from server configuration by host (name or ip). */ -SilcServerConfigSectionRouter * +SilcServerConfigRouter * silc_server_config_find_router_conn(SilcServer server, char *host, int port) { SilcServerConfig config = server->config; - SilcServerConfigSectionRouter *serv = NULL; + SilcServerConfigRouter *serv = NULL; if (!host) return NULL; @@ -1622,7 +1681,7 @@ silc_server_config_find_router_conn(SilcServer server, char *host, int port) bool silc_server_config_is_primary_route(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionRouter *serv = NULL; + SilcServerConfigRouter *serv = NULL; int i; bool found = FALSE; @@ -1642,11 +1701,11 @@ bool silc_server_config_is_primary_route(SilcServer server) /* Returns our primary connection configuration or NULL if we do not have primary router configured. */ -SilcServerConfigSectionRouter * +SilcServerConfigRouter * silc_server_config_get_primary_router(SilcServer server) { SilcServerConfig config = server->config; - SilcServerConfigSectionRouter *serv = NULL; + SilcServerConfigRouter *serv = NULL; int i; serv = config->routers; @@ -1665,19 +1724,17 @@ bool silc_server_config_set_defaults(SilcServer server) { SilcServerConfig config = server->config; - config->param.keepalive_secs = (config->param.keepalive_secs ? - config->param.keepalive_secs : - SILC_SERVER_KEEPALIVE); - config->param.reconnect_count = (config->param.reconnect_count ? - config->param.reconnect_count : - SILC_SERVER_RETRY_COUNT); - config->param.reconnect_interval = (config->param.reconnect_interval ? - config->param.reconnect_interval : - SILC_SERVER_RETRY_INTERVAL_MIN); - config->param.reconnect_interval_max = - (config->param.reconnect_interval_max ? - config->param.reconnect_interval_max : - SILC_SERVER_RETRY_INTERVAL_MAX); + my_set_param_defaults(&config->param, NULL); + + config->channel_rekey_secs = (config->channel_rekey_secs ? + config->channel_rekey_secs : + SILC_SERVER_CHANNEL_REKEY); + config->key_exchange_timeout = (config->key_exchange_timeout ? + config->key_exchange_timeout : + SILC_SERVER_SKE_TIMEOUT); + config->conn_auth_timeout = (config->conn_auth_timeout ? + config->conn_auth_timeout : + SILC_SERVER_CONNAUTH_TIMEOUT); return TRUE; } diff --git a/apps/silcd/serverconfig.h b/apps/silcd/serverconfig.h index 2ec5f8a3..4508c717 100644 --- a/apps/silcd/serverconfig.h +++ b/apps/silcd/serverconfig.h @@ -21,35 +21,35 @@ #ifndef SERVERCONFIG_H #define SERVERCONFIG_H -typedef struct SilcServerConfigSectionCipherStruct { +typedef struct SilcServerConfigCipherStruct { char *name; char *module; uint32 key_length; uint32 block_length; - struct SilcServerConfigSectionCipherStruct *next; -} SilcServerConfigSectionCipher; + struct SilcServerConfigCipherStruct *next; +} SilcServerConfigCipher; -typedef struct SilcServerConfigSectionHashStruct { +typedef struct SilcServerConfigHashStruct { char *name; char *module; uint32 block_length; uint32 digest_length; - struct SilcServerConfigSectionHashStruct *next; -} SilcServerConfigSectionHash; + struct SilcServerConfigHashStruct *next; +} SilcServerConfigHash; -typedef struct SilcServerConfigSectionHmacStruct { +typedef struct SilcServerConfigHmacStruct { char *name; char *hash; uint32 mac_length; - struct SilcServerConfigSectionHmacStruct *next; -} SilcServerConfigSectionHmac; + struct SilcServerConfigHmacStruct *next; +} SilcServerConfigHmac; -typedef struct SilcServerConfigSectionPkcsStruct { +typedef struct SilcServerConfigPkcsStruct { char *name; - struct SilcServerConfigSectionPkcsStruct *next; -} SilcServerConfigSectionPkcs; + struct SilcServerConfigPkcsStruct *next; +} SilcServerConfigPkcs; -typedef struct SilcServerConfigSectionServerInfoStruct { +typedef struct SilcServerConfigServerInfoStruct { char *server_name; char *server_ip; uint16 port; @@ -63,86 +63,85 @@ typedef struct SilcServerConfigSectionServerInfoStruct { SilcPrivateKey private_key; char *motd_file; /* path to text motd file (reading only) */ char *pid_file; /* path to the pid file (for reading and writing) */ -} SilcServerConfigSectionServerInfo; +} SilcServerConfigServerInfo; -typedef struct SilcServerConfigSectionLoggingStruct { +typedef struct SilcServerConfigLoggingStruct { char *file; uint32 maxsize; -} SilcServerConfigSectionLogging; +} SilcServerConfigLogging; /* Connection parameters */ -typedef struct SilcServerConfigSectionConnectionParam { +typedef struct SilcServerConfigConnParams { char *name; + uint32 connections_max; + uint32 connections_max_per_host; uint32 keepalive_secs; uint32 reconnect_count; uint32 reconnect_interval; uint32 reconnect_interval_max; bool reconnect_keep_trying; - /* - uint32 connect_freq; - uint32 max_links; - */ - struct SilcServerConfigSectionConnectionParam *next; -} SilcServerConfigSectionConnectionParam; + uint32 key_exchange_rekey; + bool key_exchange_pfs; + struct SilcServerConfigConnParams *next; +} SilcServerConfigConnParams; /* Holds all client authentication data from config file */ -typedef struct SilcServerConfigSectionClientStruct { +typedef struct SilcServerConfigClientStruct { char *host; unsigned char *passphrase; uint32 passphrase_len; void *publickey; - uint16 port; - SilcServerConfigSectionConnectionParam *param; - struct SilcServerConfigSectionClientStruct *next; -} SilcServerConfigSectionClient; + SilcServerConfigConnParams *param; + struct SilcServerConfigClientStruct *next; +} SilcServerConfigClient; /* Holds all server's administrators authentication data from config file */ -typedef struct SilcServerConfigSectionAdminStruct { +typedef struct SilcServerConfigAdminStruct { char *host; char *user; char *nick; unsigned char *passphrase; uint32 passphrase_len; void *publickey; - struct SilcServerConfigSectionAdminStruct *next; -} SilcServerConfigSectionAdmin; + struct SilcServerConfigAdminStruct *next; +} SilcServerConfigAdmin; /* Holds all configured denied connections from config file */ -typedef struct SilcServerConfigSectionDenyStruct { +typedef struct SilcServerConfigDenyStruct { char *host; uint16 port; char *reason; - struct SilcServerConfigSectionDenyStruct *next; -} SilcServerConfigSectionDeny; + struct SilcServerConfigDenyStruct *next; +} SilcServerConfigDeny; /* Holds all configured server connections from config file */ -typedef struct SilcServerConfigSectionServerStruct { +typedef struct SilcServerConfigServerStruct { char *host; unsigned char *passphrase; uint32 passphrase_len; void *publickey; char *version; - SilcServerConfigSectionConnectionParam *param; + SilcServerConfigConnParams *param; bool backup_router; - struct SilcServerConfigSectionServerStruct *next; -} SilcServerConfigSectionServer; + struct SilcServerConfigServerStruct *next; +} SilcServerConfigServer; /* Holds all configured router connections from config file */ -typedef struct SilcServerConfigSectionRouterStruct { +typedef struct SilcServerConfigRouterStruct { char *host; unsigned char *passphrase; uint32 passphrase_len; void *publickey; uint16 port; char *version; - SilcServerConfigSectionConnectionParam *param; + SilcServerConfigConnParams *param; bool initiator; bool backup_router; char *backup_replace_ip; uint16 backup_replace_port; bool backup_local; - struct SilcServerConfigSectionRouterStruct *next; -} SilcServerConfigSectionRouter; + struct SilcServerConfigRouterStruct *next; +} SilcServerConfigRouter; /* define the SilcServerConfig object */ typedef struct { @@ -152,25 +151,27 @@ typedef struct { char *module_path; bool prefer_passphrase_auth; bool require_reverse_lookup; - /* XXX Still think whether to actually have params in general... -Pekka */ - SilcServerConfigSectionConnectionParam param; + uint32 channel_rekey_secs; + uint32 key_exchange_timeout; + uint32 conn_auth_timeout; + SilcServerConfigConnParams param; /* Other configuration sections */ - SilcServerConfigSectionCipher *cipher; - SilcServerConfigSectionHash *hash; - SilcServerConfigSectionHmac *hmac; - SilcServerConfigSectionPkcs *pkcs; - SilcServerConfigSectionLogging *logging_info; - SilcServerConfigSectionLogging *logging_warnings; - SilcServerConfigSectionLogging *logging_errors; - SilcServerConfigSectionLogging *logging_fatals; - SilcServerConfigSectionServerInfo *server_info; - SilcServerConfigSectionConnectionParam *conn_params; - SilcServerConfigSectionClient *clients; - SilcServerConfigSectionAdmin *admins; - SilcServerConfigSectionDeny *denied; - SilcServerConfigSectionServer *servers; - SilcServerConfigSectionRouter *routers; + SilcServerConfigCipher *cipher; + SilcServerConfigHash *hash; + SilcServerConfigHmac *hmac; + SilcServerConfigPkcs *pkcs; + SilcServerConfigLogging *logging_info; + SilcServerConfigLogging *logging_warnings; + SilcServerConfigLogging *logging_errors; + SilcServerConfigLogging *logging_fatals; + SilcServerConfigServerInfo *server_info; + SilcServerConfigConnParams *conn_params; + SilcServerConfigClient *clients; + SilcServerConfigAdmin *admins; + SilcServerConfigDeny *denied; + SilcServerConfigServer *servers; + SilcServerConfigRouter *routers; } *SilcServerConfig; /* Prototypes */ @@ -187,19 +188,19 @@ bool silc_server_config_register_pkcs(SilcServer server); void silc_server_config_setlogfiles(SilcServer server); /* Run-time config access functions */ -SilcServerConfigSectionClient * -silc_server_config_find_client(SilcServer server, char *host, int port); -SilcServerConfigSectionAdmin * +SilcServerConfigClient * +silc_server_config_find_client(SilcServer server, char *host); +SilcServerConfigAdmin * silc_server_config_find_admin(SilcServer server, char *host, char *user, char *nick); -SilcServerConfigSectionDeny * +SilcServerConfigDeny * silc_server_config_find_denied(SilcServer server, char *host, uint16 port); -SilcServerConfigSectionServer * +SilcServerConfigServer * silc_server_config_find_server_conn(SilcServer server, char *host); -SilcServerConfigSectionRouter * +SilcServerConfigRouter * silc_server_config_find_router_conn(SilcServer server, char *host, int port); bool silc_server_config_is_primary_route(SilcServer server); -SilcServerConfigSectionRouter * +SilcServerConfigRouter * silc_server_config_get_primary_router(SilcServer server); bool silc_server_config_set_defaults(SilcServer server); diff --git a/doc/example_silcd.conf.in b/doc/example_silcd.conf.in index 2f68295b..29dd23a7 100644 --- a/doc/example_silcd.conf.in +++ b/doc/example_silcd.conf.in @@ -17,7 +17,7 @@ Include "@ETCDIR@/silcalgs.conf"; # General configuration options # # These defines the default behaviour of the server. Most of these values -# can be overridden with ConnectionParam, which can be defined independently +# can be overridden with ConnectionParams, which can be defined independently # for different connections. # General { @@ -33,11 +33,22 @@ General { #prefer_passphrase_auth = true; # Set this to true if the server should require fully qualified - # domain names (FQDN) for incoming connections. - #require_reverse_lookup = false; + # domain names (FQDN) for incoming connections. If true, a host + # without FQDN cannot connect to the server. + #require_reverse_lookup = true; + + # Maximum number of incoming connections allowed to this server. + # If more attempt to connet they will be refused. + connections_max = 1000; + + # Maximum number of incoming connections allowed per single host. + # For example, if this is one (1) it means a host can link only + # once to the server. Attempting to connect more than once would be + # refused. This can be overridden with ConnectionParams. + #connections_max_per_host = 10; # Default keepalive frequency (seconds). This can be overridden - # with ConnectionParam. + # with ConnectionParams. keepalive_secs = 300; # Default reconnection parameters defines how the server reconnect @@ -58,11 +69,39 @@ General { # reconnect_count is reached (the interval # will be reconnect_interval_max). # - # These can be overridden with ConnectionParam. + # These can be overridden with ConnectionParams. reconnect_count = 7; reconnect_interval = 10; reconnect_interval_max = 600; reconnect_keep_trying = true; + + # Key exchange protocol rekey interval (seconds). How often to + # regenerate the session key with the remote. Initiator will perform + # the rekey and this setting affects only when connecting as intiator. + # This can be overridden with ConnectionParams. + #key_exchange_rekey = 3600; + + # Key exchange with Perfect Forward Secrecy (PFS). This will perform + # the rekey process with PFS, making the new key more secure since it + # is not dependent in any way of the old key. This will make the rekey + # process somewhat slower, than without PFS. This can be overridden + # with ConnectionParams. + #key_exchange_pfs = true; + + # Key exchange timeout (seconds). If the key exchange protocol is not + # finished in this time period the remote connection will be closed. + #key_exchange_timeout = 60; + + # Connection authentication timeout (seconds). If the connection + # authentication protocol is not finished in this time period the + # remote connection will be closed. + #conn_auth_timeout = 60; + + # Channel key rekey interval (seconds). How often channel key is + # regenerated. Note that channel key regenerated also always when + # someone joins or leaves the channel. + #channel_rekey_secs = 3600; + }; # @@ -90,12 +129,12 @@ ServerInfo { # # Full admin name # - Admin = "Pekka Riikonen"; + Admin = "Foo T. Bar"; # # Admin's email address # - AdminEmail = "priikone@poseidon.pspt.fi"; + AdminEmail = "foo-admin@bar.com"; # # Run SILC server as specific user and group. The server must be @@ -180,11 +219,25 @@ Logging { # (or values defined in General section). You can have multiple # ConnectionParams blocks defined. # -ConnectionParam { +ConnectionParams { # unique name. The name is used to reference to this parameter - # block from the connections. + # block from the connections. This field is mandatory. name = "normal"; + # Maximum number of connections allowed. More connections will be + # refused. This can be used for example to limit number of clients. + # Note that this never can be larger than the connections_max + # specified in General section. + connections_max = 200; + + # Maximum number of connections allowed per host. For example, if + # this is one (1) it means a host can link only once to the server. + # Attempting to link more than once would be refused. + # + # If this connection parameters block is used with incoming server + # connections it is recommended that this value is set to one (1). + connections_max_per_host = 10; + # Keepalive frequency (seconds). keepalive_secs = 300; @@ -210,12 +263,18 @@ ConnectionParam { reconnect_interval_max = 600; reconnect_keep_trying = true; - #TODO: - #key_exchange_rekey - rekey timeout - #key_exchange_pfs - rekey PFS - #key_exchange_mutual_auth - SKE mutual auth + # Key exchange protocol rekey interval (seconds). How often to + # regenerate the session key with the remote. Initiator will perform + # the rekey and this setting affects only when connecting as initiator. + #key_exchange_rekey = 3600; + + # Key exchange with Perfect Forward Secrecy (PFS). This will perform + # the rekey process with PFS, making the new key more secure since it + # is not dependent in any way of the old key. This will make the rekey + # process somewhat slower, than without PFS. + #key_exchange_pfs = true; - #connections_max - max incoming connection + #TODO: #connections_interval - incoming connection interval limit ? }; @@ -240,7 +299,7 @@ Client { #Host = "10.1.*"; #Passphrase = "secret"; #PublicKey = "/path/to/the/public.key"; - Param = "normal"; + Params = "normal"; }; # @@ -286,7 +345,7 @@ ServerConnection { Passphrase = "verysecret"; #Publickey = "/path/to/the/public.key"; VersionID = 1; - Param = "normal"; + Params = "normal"; Backup = false; }; @@ -321,7 +380,7 @@ RouterConnection { Passphrase = "verysecret"; #Publickey = "/path/to/the/public.key"; VersionID = 1; - Param = "normal"; + Params = "normal"; Initiator = true; #BackupHost = "10.2.1.6"; #BackupPort = 706; diff --git a/doc/silcalgs.conf b/doc/silcalgs.conf index a0fb89bb..0d84b6b4 100644 --- a/doc/silcalgs.conf +++ b/doc/silcalgs.conf @@ -7,6 +7,8 @@ # You should not change the contents of this file unless you know what you # are doing. # +# The first algorithm defined is always the default one to use. +# # # Configured ciphers @@ -74,6 +76,8 @@ cipher { cipher { name = "none"; module = "none.sim.so"; + keylength = 0; + blocklength = 0; }; # diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index a6b23c85..a5f7a645 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -624,7 +624,7 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng, SilcSocketConnection sock, char *version, SilcBuffer start_payload, - bool mutual_auth) + SilcSKESecurityPropertyFlag flags) { SilcSKEStatus status = SILC_SKE_STATUS_OK; SilcSKEStartPayload *remote_payload = NULL, *payload = NULL; @@ -646,11 +646,17 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng, ske->start_payload_copy = silc_buffer_copy(start_payload); /* Force the mutual authentication flag if we want to do it. */ - if (mutual_auth) { + if (flags & SILC_SKE_SP_FLAG_MUTUAL) { SILC_LOG_DEBUG(("Force mutual authentication")); remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL; } + /* Force PFS flag if we require it */ + if (flags & SILC_SKE_SP_FLAG_PFS) { + SILC_LOG_DEBUG(("Force PFS")); + remote_payload->flags |= SILC_SKE_SP_FLAG_PFS; + } + /* Parse and select the security properties from the payload */ payload = silc_calloc(1, sizeof(*payload)); status = silc_ske_select_security_properties(ske, version, @@ -1107,7 +1113,7 @@ SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status) SilcSKEStatus silc_ske_assemble_security_properties(SilcSKE ske, - unsigned char flags, + SilcSKESecurityPropertyFlag flags, char *version, SilcSKEStartPayload **return_payload) { diff --git a/lib/silcske/silcske.h b/lib/silcske/silcske.h index 85c78657..60de4114 100644 --- a/lib/silcske/silcske.h +++ b/lib/silcske/silcske.h @@ -125,7 +125,7 @@ typedef enum { to negotiate what security properties should be used in the communication. */ struct SilcSKESecurityPropertiesStruct { - unsigned char flags; + SilcSKESecurityPropertyFlag flags; SilcSKEDiffieHellmanGroup group; SilcPKCS pkcs; SilcCipher cipher; @@ -208,7 +208,7 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng, SilcSocketConnection sock, char *version, SilcBuffer start_payload, - bool mutual_auth); + SilcSKESecurityPropertyFlag flags); SilcSKEStatus silc_ske_responder_phase_1(SilcSKE ske, SilcSKEStartPayload *start_payload); SilcSKEStatus silc_ske_responder_phase_2(SilcSKE ske, @@ -221,7 +221,7 @@ SilcSKEStatus silc_ske_end(SilcSKE ske); SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status); SilcSKEStatus silc_ske_assemble_security_properties(SilcSKE ske, - unsigned char flags, + SilcSKESecurityPropertyFlag flags, char *version, SilcSKEStartPayload **return_payload); SilcSKEStatus -- 2.24.0