Added remote version control support to server.
[silc.git] / apps / silcd / serverconfig.c
index 09fde6070f8fdab3de3aa6accfd0e64efb627e97..2153870e0dc904ef599b9a510e7a78de12b49440 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 
 my_set_param_defaults(SilcServerConfigConnParams *params,
                      SilcServerConfigConnParams *defaults)
 {
-#define SET_PARAM_DEFAULT(p, d)                                                \
+#define SET_PARAM_DEFAULT(p, d)        params->p =                             \
   (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);
+  SET_PARAM_DEFAULT(connections_max, SILC_SERVER_MAX_CONNECTIONS);
+  SET_PARAM_DEFAULT(connections_max_per_host, 
+                   SILC_SERVER_MAX_CONNECTIONS_SINGLE);
+  SET_PARAM_DEFAULT(keepalive_secs, SILC_SERVER_KEEPALIVE);
+  SET_PARAM_DEFAULT(reconnect_count, SILC_SERVER_RETRY_COUNT);
+  SET_PARAM_DEFAULT(reconnect_interval, SILC_SERVER_RETRY_INTERVAL_MIN);
+  SET_PARAM_DEFAULT(reconnect_interval_max, SILC_SERVER_RETRY_INTERVAL_MAX);
+  SET_PARAM_DEFAULT(key_exchange_rekey, SILC_SERVER_REKEY);
 }
 
 /* Find connection parameters by the parameter block name. */
@@ -106,8 +105,9 @@ my_find_param(SilcServerConfig config, const char *name, SilcUInt32 line)
 }
 
 /* parse an authdata according to its auth method */
-static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, SilcUInt32 line,
-                             void **auth_data, SilcUInt32 *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 */
@@ -116,7 +116,7 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, SilcUInt32 line
     if (auth_data_len)
       *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 +125,16 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, SilcUInt32 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);
@@ -190,6 +196,21 @@ SILC_CONFIG_CALLBACK(fetch_generic)
   else if (!strcmp(name, "conn_auth_timeout")) {
     config->conn_auth_timeout = (SilcUInt32) *(int *)val;
   }
+  else if (!strcmp(name, "version_protocol")) {
+    CONFIG_IS_DOUBLE(config->param.version_protocol);
+    config->param.version_protocol = 
+      (*(char *)val ? strdup((char *) val) : NULL);
+  }
+  else if (!strcmp(name, "version_software")) {
+    CONFIG_IS_DOUBLE(config->param.version_software);
+    config->param.version_software = 
+      (*(char *)val ? strdup((char *) val) : NULL);
+  }
+  else if (!strcmp(name, "version_software_vendor")) {
+    CONFIG_IS_DOUBLE(config->param.version_software_vendor);;
+    config->param.version_software_vendor = 
+      (*(char *)val ? strdup((char *) val) : NULL);
+  }
   else
     return SILC_CONFIG_EINTERNAL;
 
@@ -613,6 +634,19 @@ SILC_CONFIG_CALLBACK(fetch_connparam)
   else if (!strcmp(name, "key_exchange_pfs")) {
     tmp->key_exchange_pfs = *(bool *)val;
   }
+  else if (!strcmp(name, "version_protocol")) {
+    CONFIG_IS_DOUBLE(tmp->version_protocol);
+    tmp->version_protocol = (*(char *)val ? strdup((char *) val) : NULL);
+  }
+  else if (!strcmp(name, "version_software")) {
+    CONFIG_IS_DOUBLE(tmp->version_software);
+    tmp->version_software = (*(char *)val ? strdup((char *) val) : NULL);
+  }
+  else if (!strcmp(name, "version_software_vendor")) {
+    CONFIG_IS_DOUBLE(tmp->version_software_vendor);;
+    tmp->version_software_vendor = 
+      (*(char *)val ? strdup((char *) val) : NULL);
+  }
   else
     return SILC_CONFIG_EINTERNAL;
 
@@ -651,6 +685,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 +695,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 +757,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 +766,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 +862,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 +871,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;
     }
@@ -905,6 +944,7 @@ SILC_CONFIG_CALLBACK(fetch_router)
     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 +953,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;
     }
@@ -982,6 +1023,9 @@ static const SilcConfigTable table_general[] = {
   { "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 },
+  { "version_protocol",                SILC_CONFIG_ARG_STR,    fetch_generic,  NULL },
+  { "version_software",                SILC_CONFIG_ARG_STR,    fetch_generic,  NULL },
+  { "version_software_vendor",  SILC_CONFIG_ARG_STR,    fetch_generic, NULL },
   { 0, 0, 0, 0 }
 };
 
@@ -1059,6 +1103,9 @@ static const SilcConfigTable table_connparam[] = {
   { "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 },
+  { "version_protocol",               SILC_CONFIG_ARG_STR,    fetch_connparam, NULL },
+  { "version_software",               SILC_CONFIG_ARG_STR,    fetch_connparam, NULL },
+  { "version_software_vendor", SILC_CONFIG_ARG_STR,    fetch_connparam,        NULL },
   { 0, 0, 0, 0 }
 };
 
@@ -1293,7 +1340,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)) {
@@ -1306,7 +1353,7 @@ bool silc_server_config_register_ciphers(SilcServer server)
       /* Load (try at least) the crypto SIM module */
       char buf[1023], *alg_name;
       SilcCipherObject cipher_obj;
-      SilcSimContext *sim;
+      SilcSim sim;
 
       memset(&cipher_obj, 0, sizeof(cipher_obj));
       cipher_obj.name = cipher->name;
@@ -1316,9 +1363,7 @@ bool silc_server_config_register_ciphers(SilcServer server)
       /* build the libname */
       snprintf(buf, sizeof(buf), "%s/%s", config->module_path,
                cipher->module);
-      sim = silc_sim_alloc();
-      sim->type = SILC_SIM_CIPHER;
-      sim->libname = buf;
+      sim = silc_sim_alloc(SILC_SIM_CIPHER, buf, 0);
 
       alg_name = strdup(cipher->name);
       if (strchr(alg_name, '-'))
@@ -1394,7 +1439,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)) {
@@ -1406,16 +1451,14 @@ bool silc_server_config_register_hashfuncs(SilcServer server)
 #ifdef SILC_SIM
       /* Load (try at least) the hash SIM module */
       SilcHashObject hash_obj;
-      SilcSimContext *sim;
+      SilcSim sim;
 
       memset(&hash_obj, 0, sizeof(hash_obj));
       hash_obj.name = hash->name;
       hash_obj.block_len = hash->block_length;
       hash_obj.hash_len = hash->digest_length;
 
-      sim = silc_sim_alloc();
-      sim->type = SILC_SIM_HASH;
-      sim->libname = hash->module;
+      sim = silc_sim_alloc(SILC_SIM_HASH, hash->module, 0);
 
       if ((silc_sim_load(sim))) {
        hash_obj.init =
@@ -1478,6 +1521,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 +1550,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)) {