Added support for multiple PublicKey instances in the config
[silc.git] / apps / silcd / serverconfig.c
index 7177c103d8fd65cd230ac53fd730dc00f35c6eb3..0a0bfe55ee4762a35aefc556d1f6a281d52f0706 100644 (file)
 
 /* Free the authentication fields in the specified struct
  * Expands to two instructions */
-#define CONFIG_FREE_AUTH(__section__)                                  \
-  silc_free(__section__->passphrase);                                  \
-  silc_pkcs_public_key_free(__section__->publickey)
+#define CONFIG_FREE_AUTH(__section__)                  \
+  silc_free(__section__->passphrase);                  \
+  if (__section__->publickeys)                         \
+    silc_hash_table_free(__section__->publickeys);
+
+static void my_free_public_key(void *key, void *context, void *user_data)
+{
+  silc_pkcs_public_key_free(context);
+}
 
 /* Set default values to those parameters that have not been defined */
 static void 
@@ -90,7 +96,7 @@ my_set_param_defaults(SilcServerConfigConnParams *params,
 
 /* Find connection parameters by the parameter block name. */
 static SilcServerConfigConnParams *
-my_find_param(SilcServerConfig config, const char *name, uint32 line)
+my_find_param(SilcServerConfig config, const char *name, SilcUInt32 line)
 {
   SilcServerConfigConnParams *param;
 
@@ -106,17 +112,18 @@ my_find_param(SilcServerConfig config, const char *name, uint32 line)
 }
 
 /* parse an authdata according to its auth method */
-static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line,
-                             void **auth_data, uint32 *auth_data_len)
+static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, 
+                             SilcUInt32 line, void **auth_data, 
+                             SilcUInt32 *auth_data_len)
 {
   if (auth_meth == SILC_AUTH_PASSWORD) {
     /* p is a plain text password */
     if (auth_data)
       *auth_data = (void *) strdup(p);
     if (auth_data_len)
-      *auth_data_len = (uint32) strlen(p);
+      *auth_data_len = (SilcUInt32) strlen(p);
   } else if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
-    /* p is a public key */
+    /* p is a public key file name */
     SilcPublicKey public_key;
 
     if (!silc_pkcs_load_public_key(p, &public_key, SILC_PKCS_FILE_PEM))
@@ -125,10 +132,16 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, uint32 line,
                "Could not load public key file!\n", line);
        return FALSE;
       }
-    if (auth_data)
-      *auth_data = (void *) public_key;
-    if (auth_data_len)
-      *auth_data_len = 0;
+
+    /* The auth_data is a pointer to the hash table of public keys. */
+    if (auth_data) {
+      if (*auth_data == NULL)
+       *auth_data = silc_hash_table_alloc(1, silc_hash_public_key, NULL, 
+                                          NULL, NULL, 
+                                          my_free_public_key, NULL, 
+                                          TRUE);
+      silc_hash_table_add(*auth_data, public_key, public_key);
+    }
   } else {
     fprintf(stderr, "\nError while parsing config file at line %lu: "
            "Unknown authentication method.\n", line);
@@ -155,40 +168,40 @@ SILC_CONFIG_CALLBACK(fetch_generic)
     config->require_reverse_lookup = *(bool *)val;
   }
   else if (!strcmp(name, "connections_max")) {
-    config->param.connections_max = (uint32) *(int *)val;
+    config->param.connections_max = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "connections_max_per_host")) {
-    config->param.connections_max_per_host = (uint32) *(int *)val;
+    config->param.connections_max_per_host = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "keepalive_secs")) {
-    config->param.keepalive_secs = (uint32) *(int *)val;
+    config->param.keepalive_secs = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "reconnect_count")) {
-    config->param.reconnect_count = (uint32) *(int *)val;
+    config->param.reconnect_count = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "reconnect_interval")) {
-    config->param.reconnect_interval = (uint32) *(int *)val;
+    config->param.reconnect_interval = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "reconnect_interval_max")) {
-    config->param.reconnect_interval_max = (uint32) *(int *)val;
+    config->param.reconnect_interval_max = (SilcUInt32) *(int *)val;
   }
   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;
+    config->param.key_exchange_rekey = (SilcUInt32) *(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;
+    config->channel_rekey_secs = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "key_exchange_timeout")) {
-    config->key_exchange_timeout = (uint32) *(int *)val;
+    config->key_exchange_timeout = (SilcUInt32) *(int *)val;
   }
   else if (!strcmp(name, "conn_auth_timeout")) {
-    config->conn_auth_timeout = (uint32) *(int *)val;
+    config->conn_auth_timeout = (SilcUInt32) *(int *)val;
   }
   else
     return SILC_CONFIG_EINTERNAL;
@@ -234,10 +247,10 @@ SILC_CONFIG_CALLBACK(fetch_cipher)
     tmp->module = (*(char *)val ? strdup((char *) val) : NULL);
   }
   else if (!strcmp(name, "keylength")) {
-    tmp->key_length = *(uint32 *)val;
+    tmp->key_length = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "blocklength")) {
-    tmp->block_length = *(uint32 *)val;
+    tmp->block_length = *(SilcUInt32 *)val;
   }
   else
     return SILC_CONFIG_EINTERNAL;
@@ -423,7 +436,7 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo)
       fprintf(stderr, "Invalid port number!\n");
       return SILC_CONFIG_ESILENT;
     }
-    server_info->port = (uint16) port;
+    server_info->port = (SilcUInt16) port;
   }
   else if (!strcmp(name, "servertype")) {
     CONFIG_IS_DOUBLE(server_info->server_type);
@@ -539,7 +552,7 @@ SILC_CONFIG_CALLBACK(fetch_logging)
       config->tmp = silc_calloc(1, sizeof(*tmp));
       tmp = (SilcServerConfigLogging *) config->tmp;
     }
-    tmp->maxsize = *(uint32 *) val;
+    tmp->maxsize = *(SilcUInt32 *) val;
   }
   else
     return SILC_CONFIG_EINTERNAL;
@@ -587,28 +600,28 @@ SILC_CONFIG_CALLBACK(fetch_connparam)
     tmp->name = (*(char *)val ? strdup((char *) val) : NULL);
   }
   else if (!strcmp(name, "connections_max")) {
-    tmp->connections_max = *(uint32 *)val;
+    tmp->connections_max = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "connections_max_per_host")) {
-    tmp->connections_max_per_host = *(uint32 *)val;
+    tmp->connections_max_per_host = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "keepalive_secs")) {
-    tmp->keepalive_secs = *(uint32 *)val;
+    tmp->keepalive_secs = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "reconnect_count")) {
-    tmp->reconnect_count = *(uint32 *)val;
+    tmp->reconnect_count = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "reconnect_interval")) {
-    tmp->reconnect_interval = *(uint32 *)val;
+    tmp->reconnect_interval = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "reconnect_interval_max")) {
-    tmp->reconnect_interval_max = *(uint32 *)val;
+    tmp->reconnect_interval_max = *(SilcUInt32 *)val;
   }
   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;
+    tmp->key_exchange_rekey = *(SilcUInt32 *)val;
   }
   else if (!strcmp(name, "key_exchange_pfs")) {
     tmp->key_exchange_pfs = *(bool *)val;
@@ -651,6 +664,7 @@ SILC_CONFIG_CALLBACK(fetch_client)
     tmp->host = (*(char *)val ? strdup((char *) val) : NULL);
   }
   else if (!strcmp(name, "passphrase")) {
+    CONFIG_IS_DOUBLE(tmp->passphrase);
     if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
                           (void **)&tmp->passphrase,
                           &tmp->passphrase_len)) {
@@ -660,7 +674,7 @@ SILC_CONFIG_CALLBACK(fetch_client)
   }
   else if (!strcmp(name, "publickey")) {
     if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
-                          &tmp->publickey, NULL)) {
+                          (void **)&tmp->publickeys, NULL)) {
       got_errno = SILC_CONFIG_ESILENT;
       goto got_err;
     }
@@ -722,6 +736,7 @@ SILC_CONFIG_CALLBACK(fetch_admin)
     tmp->nick = (*(char *)val ? strdup((char *) val) : NULL);
   }
   else if (!strcmp(name, "passphrase")) {
+    CONFIG_IS_DOUBLE(tmp->passphrase);
     if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
                           (void **)&tmp->passphrase,
                           &tmp->passphrase_len)) {
@@ -730,8 +745,9 @@ SILC_CONFIG_CALLBACK(fetch_admin)
     }
   }
   else if (!strcmp(name, "publickey")) {
+    CONFIG_IS_DOUBLE(tmp->publickeys);
     if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
-                          &tmp->publickey, NULL)) {
+                          (void **)&tmp->publickeys, NULL)) {
       got_errno = SILC_CONFIG_ESILENT;
       goto got_err;
     }
@@ -825,6 +841,7 @@ SILC_CONFIG_CALLBACK(fetch_server)
     tmp->host = (*(char *)val ? strdup((char *) val) : strdup("*"));
   }
   else if (!strcmp(name, "passphrase")) {
+    CONFIG_IS_DOUBLE(tmp->passphrase);
     if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
                           (void **)&tmp->passphrase,
                           &tmp->passphrase_len)) {
@@ -833,8 +850,9 @@ SILC_CONFIG_CALLBACK(fetch_server)
     }
   }
   else if (!strcmp(name, "publickey")) {
+    CONFIG_IS_DOUBLE(tmp->publickeys);
     if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
-                          &tmp->publickey, NULL)) {
+                          (void **)&tmp->publickeys, NULL)) {
       got_errno = SILC_CONFIG_ESILENT;
       goto got_err;
     }
@@ -902,9 +920,10 @@ SILC_CONFIG_CALLBACK(fetch_router)
       fprintf(stderr, "Invalid port number!\n");
       return SILC_CONFIG_ESILENT;
     }
-    tmp->port = (uint16) port;
+    tmp->port = (SilcUInt16) port;
   }
   else if (!strcmp(name, "passphrase")) {
+    CONFIG_IS_DOUBLE(tmp->passphrase);
     if (!my_parse_authdata(SILC_AUTH_PASSWORD, (char *) val, line,
                           (void **)&tmp->passphrase,
                           &tmp->passphrase_len)) {
@@ -913,8 +932,9 @@ SILC_CONFIG_CALLBACK(fetch_router)
     }
   }
   else if (!strcmp(name, "publickey")) {
+    CONFIG_IS_DOUBLE(tmp->publickeys);
     if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, line,
-                          &tmp->publickey, NULL)) {
+                          (void **)&tmp->publickeys, NULL)) {
       got_errno = SILC_CONFIG_ESILENT;
       goto got_err;
     }
@@ -945,7 +965,7 @@ SILC_CONFIG_CALLBACK(fetch_router)
       fprintf(stderr, "Invalid port number!\n");
       return SILC_CONFIG_ESILENT;
     }
-    tmp->backup_replace_port = (uint16) port;
+    tmp->backup_replace_port = (SilcUInt16) port;
   }
   else if (!strcmp(name, "backuplocal")) {
     tmp->backup_local = *(bool *)val;
@@ -1163,7 +1183,7 @@ SilcServerConfig silc_server_config_alloc(char *filename)
     /* handle this special error return which asks to quietly return */
     if (ret != SILC_CONFIG_ESILENT) {
       char *linebuf, *filename = silc_config_get_filename(file);
-      uint32 line = silc_config_get_line(file);
+      SilcUInt32 line = silc_config_get_line(file);
       fprintf(stderr, "\nError while parsing config file: %s.\n",
                silc_config_strerror(ret));
       linebuf = silc_config_read_line(file, line);
@@ -1293,7 +1313,7 @@ bool silc_server_config_register_ciphers(SilcServer server)
       int i;
       for (i = 0; silc_default_ciphers[i].name; i++)
        if (!strcmp(silc_default_ciphers[i].name, cipher->name)) {
-         silc_cipher_register(&silc_default_ciphers[i]);
+         silc_cipher_register((SilcCipherObject *)&silc_default_ciphers[i]);
          break;
        }
       if (!silc_cipher_is_supported(cipher->name)) {
@@ -1394,7 +1414,7 @@ bool silc_server_config_register_hashfuncs(SilcServer server)
       int i;
       for (i = 0; silc_default_hash[i].name; i++)
        if (!strcmp(silc_default_hash[i].name, hash->name)) {
-         silc_hash_register(&silc_default_hash[i]);
+         silc_hash_register((SilcHashObject *)&silc_default_hash[i]);
          break;
        }
       if (!silc_hash_is_supported(hash->name)) {
@@ -1478,6 +1498,7 @@ bool silc_server_config_register_hmacs(SilcServer server)
       silc_server_stop(server);
       exit(1);
     }
+
     /* Register the HMAC */
     memset(&hmac_obj, 0, sizeof(hmac_obj));
     hmac_obj.name = hmac->name;
@@ -1506,7 +1527,7 @@ bool silc_server_config_register_pkcs(SilcServer server)
     int i;
     for (i = 0; silc_default_pkcs[i].name; i++)
       if (!strcmp(silc_default_pkcs[i].name, pkcs->name)) {
-       silc_pkcs_register(&silc_default_pkcs[i]);
+       silc_pkcs_register((SilcPKCSObject *)&silc_default_pkcs[i]);
        break;
       }
     if (!silc_pkcs_is_supported(pkcs->name)) {