tupdates
authorPekka Riikonen <priikone@silcnet.org>
Sat, 16 Feb 2002 19:26:30 +0000 (19:26 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 16 Feb 2002 19:26:30 +0000 (19:26 +0000)
19 files changed:
CHANGES
TODO
apps/irssi/src/silc/core/client_ops.c
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/protocol.c
apps/silcd/protocol.h
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/server_backup.c
apps/silcd/server_internal.h
apps/silcd/server_util.c
apps/silcd/server_util.h
apps/silcd/serverconfig.c
apps/silcd/serverconfig.h
doc/example_silcd.conf.in
doc/silcalgs.conf
lib/silcske/silcske.c
lib/silcske/silcske.h

diff --git a/CHANGES b/CHANGES
index 4189c1557d4621a2c2de4efa0edd72656106db6d..b7a03848bfb924bea17ae787dae6131a461a5414 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -8,6 +8,23 @@ Sat Feb 16 13:44:24 EET 2002  Johnny Mnemonic <johnny@themnemonic.org>
          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 <johnny@themnemonic.org>
 
        * Cleaned up the listening sockets code, preparing for the rehash
diff --git a/TODO b/TODO
index eae63e9a808e6f2ee084364b59f21e9211ff382a..c8d44d4e1b356ebcff699e6aab9ea153d77b210a 100644 (file)
--- 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.
 
index f86ff03d500364e74781f14a11b749f5ea7122cc..11b33fc0c1422641e98e6b129a50d7b622ae7b87 100644 (file)
@@ -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, 
index 9d5210369a154270878ad8c5a74445e6101fe363..5221c09efd9079f105257f52ae8408e272366703 100644 (file)
@@ -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;
 
index 0956be2dad1444fa88339f903582ffdc6e3bf2ee..98800ee11f801a6dd84b06f57c64f297e1bac3a9 100644 (file)
@@ -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)
index afa0ad43ff69b43465a569a1f5070c9fe16aac87..7e6b1631e3f96593e726a8b9e33c6bdb216013e7 100644 (file)
@@ -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,
index 26be5e891b4e30f1b8f161895c8f35e595d508ef..c2b30e5ef0e82dab610a53f273137047a6896325 100644 (file)
@@ -51,6 +51,7 @@ typedef struct {
 
   SilcTask timeout_task;
   SilcPacketContext *packet;
+  SilcSKESecurityPropertyFlag flags;
   SilcSKE ske;
   SilcSKEKeyMaterial *keymat;
 } SilcServerKEInternalContext;
index 75c9cdc37a6d0859b1b2c43263c838449eb65192..c2caa843ab5c8fe977e536bf8e2d3c3d0b264540 100644 (file)
@@ -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);
   }
index afff2b97a9e51399ac794001ba68637ec4c0d0fb..9e626f5e3949bcdd4bf046bd8455a300e750b53b 100644 (file)
@@ -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 */
 
index 1c553e963ef8ea160dc5a0c8deb61e2a5adb937d..9591cade0aa9892a272b6cef4afd7a1e8674b2d8 100644 (file)
@@ -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 &&
index 423e37e6d9f34b499fb177ca9017326ebec0e0e8..f4f1d10ce21c0698b7fb1d9500d4fd7964c5238c 100644 (file)
@@ -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);
 
index 5c06bcd17f11abd582c0b083772f33e68f751a17..3592df581202c158e9c4b1dce0f4388ef048f929 100644 (file)
@@ -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;
+}
index 9cfe16070e7e753f96cb0779cb5151ae4dfb41ac..665647f062967b17093f119555fc77e1d461c624 100644 (file)
@@ -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 */
index 6ee3ebc6f9f32c94f4ebd49ab7eb4736f1e5cc2d..d6754da5b95177a85a1d1c339bee0928f7388063 100644 (file)
   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;
 }
index 2ec5f8a33837f06b6bb1b22045e8b5bc038d4f20..4508c71783d748007a9821c034fec8556a3f041f 100644 (file)
 #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);
 
index 2f68295b54a21f2fe2092d2184f8bc683f665d1c..29dd23a7d42e8ecf838f82ccbce39d42a242084f 100644 (file)
@@ -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;
index a0fb89bb1def2d98eafc1ef0046fece64ef0e4b5..0d84b6b49dc94eb9cb785c284fd36b8adf6b9d3c 100644 (file)
@@ -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;
 };
 
 #
index a6b23c857918cbf090182b3cfc8f86644c266f7d..a5f7a6452043962de5d0861050a7e6e55223214f 100644 (file)
@@ -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)
 {
index 85c78657e9c02362284c621baf1858aabf0b291c..60de4114bab73684df6a3db17d98d8130650753b 100644 (file)
@@ -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