updates.
[silc.git] / apps / silcd / serverconfig.c
index 1a9abdf33eeb53b57eea533afc0b3ab0cb358149..ecc35e2fa799ca880a0c7ef696b60362246d1933 100644 (file)
@@ -26,7 +26,7 @@ SilcServerConfigSection silc_server_config_sections[] = {
   { "[Cipher]", 
     SILC_CONFIG_SERVER_SECTION_TYPE_CIPHER, 4 },
   { "[PKCS]", 
-    SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 2 },
+    SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, 1 },
   { "[Hash]", 
     SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 },
   { "[hmac]", 
@@ -54,7 +54,7 @@ SilcServerConfigSection silc_server_config_sections[] = {
   { "[AdminConnection]", 
     SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_CONNECTION, 5 },
   { "[DenyConnection]", 
-    SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 4 },
+    SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION, 3 },
   { "[motd]", 
     SILC_CONFIG_SERVER_SECTION_TYPE_MOTD, 1 },
   
@@ -268,7 +268,7 @@ int silc_server_config_parse_lines(SilcServerConfig config,
 
     /* Get number of tokens in line */
     ret = silc_config_check_num_token(line);
-    if (ret != pc->section->maxfields) {
+    if (ret < pc->section->maxfields) {
       /* Bad line */
       fprintf(stderr, "%s:%d: Missing tokens, %d tokens (should be %d)\n",
              config->filename, pc->linenum, ret, 
@@ -340,18 +340,6 @@ int silc_server_config_parse_lines(SilcServerConfig config,
        break;
       }
 
-      /* Get key length */
-      ret = silc_config_get_token(line, &tmp);
-      if (ret < 0)
-       break;
-      if (ret == 0) {
-       fprintf(stderr, "%s:%d: PKCS key length not defined\n",
-               config->filename, pc->linenum);
-       break;
-      }
-      config->pkcs->key_len = atoi(tmp);
-      silc_free(tmp);
-
       check = TRUE;
       checkmask |= (1L << pc->section->type);
       break;
@@ -569,13 +557,13 @@ int silc_server_config_parse_lines(SilcServerConfig config,
 
       SILC_SERVER_CONFIG_LIST_ALLOC(config->listen_port);
 
-      /* Get host */
-      ret = silc_config_get_token(line, &config->listen_port->host);
+      /* Get local IP */
+      ret = silc_config_get_token(line, &config->listen_port->local_ip);
       if (ret < 0)
        break;
 
-      /* Get remote IP */
-      ret = silc_config_get_token(line, &config->listen_port->remote_ip);
+      /* Get listener IP */
+      ret = silc_config_get_token(line, &config->listen_port->listener_ip);
       if (ret < 0)
        break;
 
@@ -760,7 +748,7 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       ret = silc_config_get_token(line, &tmp);
       if (ret < 0)
        break;
-      if (ret == 0) {
+      if (ret) {
        config->clients->port = atoi(tmp);
        silc_free(tmp);
       }
@@ -860,6 +848,15 @@ int silc_server_config_parse_lines(SilcServerConfig config,
        silc_free(tmp);
       }
 
+      /* Check whether this connection is backup router connection */
+      ret = silc_config_get_token(line, &tmp);
+      if (ret != -1) {
+       config->servers->backup_router = atoi(tmp);
+       if (config->servers->backup_router != 0)
+         config->servers->backup_router = TRUE;
+       silc_free(tmp);
+      }
+
       check = TRUE;
       checkmask |= (1L << pc->section->type);
       break;
@@ -872,9 +869,6 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       ret = silc_config_get_token(line, &config->routers->host);
       if (ret < 0)
        break;
-      //      if (ret == 0)
-      ///* Any host */
-      //       config->routers->host = strdup("*");
 
       /* Get authentication method */
       ret = silc_config_get_token(line, &tmp);
@@ -957,6 +951,24 @@ int silc_server_config_parse_lines(SilcServerConfig config,
        silc_free(tmp);
       }
 
+      /* Check whether this connection is backup router connection */
+      ret = silc_config_get_token(line, &tmp);
+      if (ret != -1) {
+       config->routers->backup_router = atoi(tmp);
+       if (config->routers->backup_router != 0)
+         config->routers->backup_router = TRUE;
+       silc_free(tmp);
+      }
+
+      /* Check whether this backup is local (in cell) or remote (other cell) */
+      ret = silc_config_get_token(line, &tmp);
+      if (ret != -1) {
+       config->routers->backup_local = atoi(tmp);
+       if (config->routers->backup_local != 0)
+         config->routers->backup_local = TRUE;
+       silc_free(tmp);
+      }
+
       check = TRUE;
       checkmask |= (1L << pc->section->type);
       break;
@@ -1041,8 +1053,39 @@ int silc_server_config_parse_lines(SilcServerConfig config,
       break;
 
     case SILC_CONFIG_SERVER_SECTION_TYPE_DENY_CONNECTION:
-      /* Not implemented yet */
+
+      SILC_SERVER_CONFIG_LIST_ALLOC(config->denied);
+
+      /* Get host */
+      ret = silc_config_get_token(line, &config->denied->host);
+      if (ret < 0)
+       break;
+      if (ret == 0) {
+       /* Any host */
+       config->denied->host = strdup("*");
+       fprintf(stderr, "warning: %s:%d: Denying all connections",
+               config->filename, pc->linenum);
+      }
+
+      /* Get port */
+      ret = silc_config_get_token(line, &tmp);
+      if (ret < 0)
+       break;
+      if (ret == 0) {
+       /* Any port */
+       config->denied->port = 0;
+      } else {
+       config->denied->port = atoi(tmp);
+       silc_free(tmp);
+      }
+
+      /* Get comment */
+      ret = silc_config_get_token(line, &config->denied->comment);
+      if (ret < 0)
+       break;
+
       check = TRUE;
+      checkmask |= (1L << pc->section->type);
       break;
 
     case SILC_CONFIG_SERVER_SECTION_TYPE_MOTD:
@@ -1106,6 +1149,8 @@ int silc_server_config_parse_lines(SilcServerConfig config,
     config->clients = config->clients->prev;
   while (config->servers && config->servers->prev)
     config->servers = config->servers->prev;
+  while (config->admins && config->admins->prev)
+    config->admins = config->admins->prev;
   while (config->routers && config->routers->prev)
     config->routers = config->routers->prev;
   
@@ -1199,28 +1244,33 @@ void silc_server_config_setlogfiles(SilcServerConfig config)
 /* Registers configured ciphers. These can then be allocated by the
    server when needed. */
 
-void silc_server_config_register_ciphers(SilcServerConfig config)
+bool silc_server_config_register_ciphers(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured ciphers"));
 
+  if (!config->cipher)
+    return FALSE;
+
   alg = config->cipher;
   while(alg) {
 
     if (!alg->sim_name) {
-      /* Crypto module is supposed to be built in. Nothing to be done
-        here except to test that the cipher really is built in. */
-      SilcCipher tmp = NULL;
-
-      if (silc_cipher_alloc(alg->alg_name, &tmp) == FALSE) {
-       SILC_LOG_ERROR(("Unsupported cipher `%s'", alg->alg_name));
+      int i;
+      
+      for (i = 0; silc_default_ciphers[i].name; i++)
+       if (!strcmp(silc_default_ciphers[i].name, alg->alg_name)) {
+         silc_cipher_register(&silc_default_ciphers[i]);
+         break;
+       }
+      
+      if (!silc_cipher_is_supported(alg->alg_name)) {
+       SILC_LOG_ERROR(("Unknown cipher `%s'", alg->alg_name));
        silc_server_stop(server);
        exit(1);
       }
-      silc_cipher_free(tmp);
-
 #ifdef SILC_SIM
     } else {
       /* Load (try at least) the crypto SIM module */
@@ -1280,59 +1330,73 @@ void silc_server_config_register_ciphers(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configured PKCS's. */
-/* XXX: This really doesn't do anything now since we have statically
-   registered our PKCS's. This should be implemented when PKCS works
-   as SIM's. This checks now only that the PKCS user requested is 
-   really out there. */
 
-void silc_server_config_register_pkcs(SilcServerConfig config)
+bool silc_server_config_register_pkcs(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg = config->pkcs;
   SilcServer server = (SilcServer)config->server;
-  SilcPKCS tmp = NULL;
 
   SILC_LOG_DEBUG(("Registering configured PKCS"));
 
-  while(alg) {
+  if (!config->pkcs)
+    return FALSE;
 
-    if (silc_pkcs_alloc(alg->alg_name, &tmp) == FALSE) {
-      SILC_LOG_ERROR(("Unsupported PKCS `%s'", alg->alg_name));
+  while(alg) {
+    int i;
+    
+    for (i = 0; silc_default_pkcs[i].name; i++)
+      if (!strcmp(silc_default_pkcs[i].name, alg->alg_name)) {
+       silc_pkcs_register(&silc_default_pkcs[i]);
+       break;
+      }
+      
+    if (!silc_pkcs_is_supported(alg->alg_name)) {
+      SILC_LOG_ERROR(("Unknown PKCS `%s'", alg->alg_name));
       silc_server_stop(server);
       exit(1);
     }
-    silc_free(tmp);
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configured hash functions. These can then be allocated by the
    server when needed. */
 
-void silc_server_config_register_hashfuncs(SilcServerConfig config)
+bool silc_server_config_register_hashfuncs(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured hash functions"));
 
+  if (!config->hash_func)
+    return FALSE;
+
   alg = config->hash_func;
   while(alg) {
 
     if (!alg->sim_name) {
-      /* Hash module is supposed to be built in. Nothing to be done
-        here except to test that the hash function really is built in. */
-      SilcHash tmp = NULL;
-
-      if (silc_hash_alloc(alg->alg_name, &tmp) == FALSE) {
-       SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->alg_name));
+      int i;
+      
+      for (i = 0; silc_default_hash[i].name; i++)
+       if (!strcmp(silc_default_hash[i].name, alg->alg_name)) {
+         silc_hash_register(&silc_default_hash[i]);
+         break;
+       }
+      
+      if (!silc_hash_is_supported(alg->alg_name)) {
+       SILC_LOG_ERROR(("Unknown hash funtion `%s'", alg->alg_name));
        silc_server_stop(server);
        exit(1);
       }
-      silc_hash_free(tmp);
 
 #ifdef SILC_SIM
     } else {
@@ -1382,31 +1446,29 @@ void silc_server_config_register_hashfuncs(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Registers configure HMACs. These can then be allocated by the server
    when needed. */
 
-void silc_server_config_register_hmacs(SilcServerConfig config)
+bool silc_server_config_register_hmacs(SilcServerConfig config)
 {
   SilcServerConfigSectionAlg *alg;
   SilcServer server = (SilcServer)config->server;
 
   SILC_LOG_DEBUG(("Registering configured HMACs"));
 
-  if (!config->hmac) {
-    SILC_LOG_ERROR(("HMACs are not configured. SILC cannot work without "
-                   "HMACs"));
-    silc_server_stop(server);
-    exit(1);
-  }
+  if (!config->hmac)
+    return FALSE;
 
   alg = config->hmac;
   while(alg) {
     SilcHmacObject hmac;
     
     if (!silc_hash_is_supported(alg->sim_name)) {
-      SILC_LOG_ERROR(("Unsupported hash function `%s'", alg->sim_name));
+      SILC_LOG_ERROR(("Unknown hash function `%s'", alg->sim_name));
       silc_server_stop(server);
       exit(1);
     }
@@ -1419,10 +1481,13 @@ void silc_server_config_register_hmacs(SilcServerConfig config)
 
     alg = alg->next;
   }
+
+  return TRUE;
 }
 
 /* Returns client authentication information from server configuration
-   by host (name or ip). */
+   by host (name or ip). If `port' is non-null then both name or IP and 
+   the port must match. */
 
 SilcServerConfigSectionClientConnection *
 silc_server_config_find_client_conn(SilcServerConfig config, 
@@ -1430,6 +1495,7 @@ silc_server_config_find_client_conn(SilcServerConfig config,
 {
   int i;
   SilcServerConfigSectionClientConnection *client = NULL;
+  bool match = FALSE;
 
   if (!host)
     return NULL;
@@ -1441,7 +1507,14 @@ silc_server_config_find_client_conn(SilcServerConfig config,
 
   for (i = 0; client; i++) {
     if (silc_string_compare(client->host, host))
+      match = TRUE;
+
+    if (port && client->port && client->port != port)
+      match = FALSE;
+
+    if (match)
       break;
+
     client = client->next;
   }
 
@@ -1452,7 +1525,8 @@ silc_server_config_find_client_conn(SilcServerConfig config,
 }
 
 /* Returns server connection info from server configuartion by host 
-   (name or ip). */
+   (name or ip). If `port' is non-null then both name or IP and the port
+   must match. */
 
 SilcServerConfigSectionServerConnection *
 silc_server_config_find_server_conn(SilcServerConfig config, 
@@ -1460,6 +1534,7 @@ silc_server_config_find_server_conn(SilcServerConfig config,
 {
   int i;
   SilcServerConfigSectionServerConnection *serv = NULL;
+  bool match = FALSE;
 
   if (!host)
     return NULL;
@@ -1470,7 +1545,14 @@ silc_server_config_find_server_conn(SilcServerConfig config,
   serv = config->servers;
   for (i = 0; serv; i++) {
     if (silc_string_compare(serv->host, host))
+      match = TRUE;
+
+    if (port && serv->port && serv->port != port)
+      match = FALSE;
+
+    if (match)
       break;
+
     serv = serv->next;
   }
 
@@ -1489,6 +1571,7 @@ silc_server_config_find_router_conn(SilcServerConfig config,
 {
   int i;
   SilcServerConfigSectionServerConnection *serv = NULL;
+  bool match = FALSE;
 
   if (!host)
     return NULL;
@@ -1499,7 +1582,14 @@ silc_server_config_find_router_conn(SilcServerConfig config,
   serv = config->routers;
   for (i = 0; serv; i++) {
     if (silc_string_compare(serv->host, host))
+      match = TRUE;
+
+    if (port && serv->port && serv->port != port)
+      match = FALSE;
+
+    if (match)
       break;
+
     serv = serv->next;
   }
 
@@ -1509,6 +1599,47 @@ silc_server_config_find_router_conn(SilcServerConfig config,
   return serv;
 }
 
+/* Returns TRUE if configuartion for a router connection that we are 
+   initiating exists. */
+
+bool silc_server_config_is_primary_route(SilcServerConfig config)
+{
+  int i;
+  SilcServerConfigSectionServerConnection *serv = NULL;
+  bool found = FALSE;
+
+  serv = config->routers;
+  for (i = 0; serv; i++) {
+    if (serv->initiator == TRUE && serv->backup_router == FALSE) {
+      found = TRUE;
+      break;
+    }
+
+    serv = serv->next;
+  }
+
+  return found;
+}
+
+/* Returns our primary connection configuration or NULL if we do not
+   have primary router configured. */
+
+SilcServerConfigSectionServerConnection *
+silc_server_config_get_primary_router(SilcServerConfig config)
+{
+  int i;
+  SilcServerConfigSectionServerConnection *serv = NULL;
+
+  serv = config->routers;
+  for (i = 0; serv; i++) {
+    if (serv->initiator == TRUE && serv->backup_router == FALSE)
+      return serv;
+    serv = serv->next;
+  }
+
+  return NULL;
+}
+
 /* Returns Admin connection configuration by host, username and/or 
    nickname. */
 
@@ -1544,3 +1675,39 @@ silc_server_config_find_admin(SilcServerConfig config,
 
   return admin;
 }
+
+/* Returns the Denied connection configuration by host and port. */
+
+SilcServerConfigSectionDenyConnection *
+silc_server_config_denied_conn(SilcServerConfig config, char *host,
+                              int port)
+{
+  int i;
+  SilcServerConfigSectionDenyConnection *deny = NULL;
+  bool match = FALSE;
+
+  if (!host)
+    return NULL;
+
+  if (!config->denied)
+    return NULL;
+
+  deny = config->denied;
+  for (i = 0; deny; i++) {
+    if (silc_string_compare(deny->host, host))
+      match = TRUE;
+
+    if (port && deny->port && deny->port != port)
+      match = FALSE;
+
+    if (match)
+      break;
+
+    deny = deny->next;
+  }
+
+  if (!deny)
+    return NULL;
+
+  return deny;
+}