New silcconfig library and server parser. Merged silc-newconfig-final.patch.
[silc.git] / apps / silcd / protocol.c
index 061894bec98e8e521b451557971db92be8ab61ff..a7a1b707d7d1a39000626dbf555ac8f20a52cd2d 100644 (file)
@@ -131,12 +131,11 @@ silc_verify_public_key_internal(SilcServer server, SilcSocketConnection sock,
 
       /* Save the key for future checking */
       unlink(filename);
-      silc_pkcs_save_public_key_data(filename, pk, pk_len,
-                                    SILC_PKCS_FILE_PEM);
+      silc_pkcs_save_public_key_data(filename, pk, pk_len, SILC_PKCS_FILE_PEM);
       return TRUE;
     }
 
-    if (memcmp(encpk, pk, encpk_len)) {
+    if (memcmp(pk, encpk, encpk_len)) {
       SILC_LOG_WARNING(("%s (%s) port %d server public key does not match "
                        "with local copy", sock->hostname, sock->ip, 
                        sock->port));
@@ -206,7 +205,8 @@ static void silc_server_protocol_ke_send_packet(SilcSKE ske,
 
 /* Sets the negotiated key material into use for particular connection. */
 
-int silc_server_protocol_ke_set_keys(SilcSKE ske,
+int silc_server_protocol_ke_set_keys(SilcServer server,
+                                    SilcSKE ske,
                                     SilcSocketConnection sock,
                                     SilcSKEKeyMaterial *keymat,
                                     SilcCipher cipher,
@@ -300,6 +300,9 @@ int silc_server_protocol_ke_set_keys(SilcSKE ske,
   /* Save the remote host's public key */
   silc_pkcs_public_key_decode(ske->ke1_payload->pk_data, 
                              ske->ke1_payload->pk_len, &idata->public_key);
+  if (ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL)
+    silc_hash_make(server->sha1hash, ske->ke1_payload->pk_data,
+                  ske->ke1_payload->pk_len, idata->fingerprint);
 
   sock->user_data = (void *)conn_data;
 
@@ -364,8 +367,10 @@ SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
 
   if (maj != maj2)
     status = SILC_SKE_STATUS_BAD_VERSION;
+#if 0
   if (min > min2)
     status = SILC_SKE_STATUS_BAD_VERSION;
+#endif
 
   /* XXX < 0.6 is not allowed */
   if (maj == 0 && min < 5)
@@ -648,6 +653,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
       if (ctx->timeout_task)
        silc_schedule_task_del(server->schedule, ctx->timeout_task);
 
+      /* Assure that after calling final callback there cannot be pending
+        executions for this protocol anymore. This just unregisters any 
+        timeout callbacks for this protocol. */
+      silc_protocol_cancel(protocol, server->schedule);
+
       /* Call the final callback */
       if (protocol->final_callback)
        silc_protocol_execute_final(protocol, server->schedule);
@@ -670,6 +680,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
     if (ctx->timeout_task)
       silc_schedule_task_del(server->schedule, ctx->timeout_task);
 
+    /* Assure that after calling final callback there cannot be pending
+       executions for this protocol anymore. This just unregisters any 
+       timeout callbacks for this protocol. */
+    silc_protocol_cancel(protocol, server->schedule);
+
     /* On error the final callback is always called. */
     if (protocol->final_callback)
       silc_protocol_execute_final(protocol, server->schedule);
@@ -688,6 +703,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
     if (ctx->timeout_task)
       silc_schedule_task_del(server->schedule, ctx->timeout_task);
 
+    /* Assure that after calling final callback there cannot be pending
+       executions for this protocol anymore. This just unregisters any 
+       timeout callbacks for this protocol. */
+    silc_protocol_cancel(protocol, server->schedule);
+    
     /* On error the final callback is always called. */
     if (protocol->final_callback)
       silc_protocol_execute_final(protocol, server->schedule);
@@ -705,13 +725,13 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
  */
 
 static int 
-silc_server_password_authentication(SilcServer server, char *auth1
-                                   char *auth2)
+silc_server_password_authentication(SilcServer server, char *remote_auth
+                                   char *local_auth)
 {
-  if (!auth1 || !auth2)
+  if (!remote_auth || !local_auth)
     return FALSE;
 
-  if (!memcmp(auth1, auth2, strlen(auth1)))
+  if (!memcmp(remote_auth, local_auth, strlen(local_auth)))
     return TRUE;
 
   return FALSE;
@@ -886,7 +906,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
 
        /* Remote end is client */
        if (conn_type == SILC_SOCKET_TYPE_CLIENT) {
-         SilcServerConfigSectionClientConnection *client = ctx->cconfig;
+         SilcServerConfigSectionClient *client = ctx->cconfig;
          
          if (client) {
            switch(client->auth_meth) {
@@ -935,8 +955,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
              return;
            }
          } else {
-           SILC_LOG_DEBUG(("No configuration for remote connection"));
-           SILC_LOG_ERROR(("Remote connection not configured"));
+           SILC_LOG_DEBUG(("No configuration for remote client connection"));
+           SILC_LOG_ERROR(("Remote client connection not configured"));
            SILC_LOG_ERROR(("Authentication failed"));
            silc_free(auth_data);
            protocol->state = SILC_PROTOCOL_STATE_ERROR;
@@ -948,7 +968,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        
        /* Remote end is server */
        if (conn_type == SILC_SOCKET_TYPE_SERVER) {
-         SilcServerConfigSectionServerConnection *serv = ctx->sconfig;
+         SilcServerConfigSectionServer *serv = ctx->sconfig;
          
          if (serv) {
            switch(serv->auth_meth) {
@@ -997,8 +1017,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
              return;
            }
          } else {
-           SILC_LOG_DEBUG(("No configuration for remote connection"));
-           SILC_LOG_ERROR(("Remote connection not configured"));
+           SILC_LOG_DEBUG(("No configuration for remote server connection"));
+           SILC_LOG_ERROR(("Remote server connection not configured"));
            SILC_LOG_ERROR(("Authentication failed"));
            protocol->state = SILC_PROTOCOL_STATE_ERROR;
            silc_protocol_execute(protocol, server->schedule, 
@@ -1010,7 +1030,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
        
        /* Remote end is router */
        if (conn_type == SILC_SOCKET_TYPE_ROUTER) {
-         SilcServerConfigSectionServerConnection *serv = ctx->rconfig;
+         SilcServerConfigSectionRouter *serv = ctx->rconfig;
 
          if (serv) {
            switch(serv->auth_meth) {
@@ -1059,8 +1079,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
              return;
            }
          } else {
-           SILC_LOG_DEBUG(("No configuration for remote connection"));
-           SILC_LOG_ERROR(("Remote connection not configured"));
+           SILC_LOG_DEBUG(("No configuration for remote router connection"));
+           SILC_LOG_ERROR(("Remote router connection not configured"));
            SILC_LOG_ERROR(("Authentication failed"));
            silc_free(auth_data);
            protocol->state = SILC_PROTOCOL_STATE_ERROR;
@@ -1166,6 +1186,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
       if (ctx->timeout_task)
        silc_schedule_task_del(server->schedule, ctx->timeout_task);
 
+      /* Assure that after calling final callback there cannot be pending
+        executions for this protocol anymore. This just unregisters any 
+        timeout callbacks for this protocol. */
+      silc_protocol_cancel(protocol, server->schedule);
+    
       /* Protocol has ended, call the final callback */
       if (protocol->final_callback)
        silc_protocol_execute_final(protocol, server->schedule);
@@ -1192,6 +1217,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
       if (ctx->timeout_task)
        silc_schedule_task_del(server->schedule, ctx->timeout_task);
 
+      /* Assure that after calling final callback there cannot be pending
+        executions for this protocol anymore. This just unregisters any 
+        timeout callbacks for this protocol. */
+      silc_protocol_cancel(protocol, server->schedule);
+    
       /* On error the final callback is always called. */
       if (protocol->final_callback)
        silc_protocol_execute_final(protocol, server->schedule);
@@ -1211,6 +1241,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
     if (ctx->timeout_task)
       silc_schedule_task_del(server->schedule, ctx->timeout_task);
 
+    /* Assure that after calling final callback there cannot be pending
+       executions for this protocol anymore. This just unregisters any 
+       timeout callbacks for this protocol. */
+    silc_protocol_cancel(protocol, server->schedule);
+    
     /* On error the final callback is always called. */
     if (protocol->final_callback)
       silc_protocol_execute_final(protocol, server->schedule);
@@ -1406,7 +1441,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey)
          ctx->ske = silc_ske_alloc();
          ctx->ske->rng = server->rng;
          ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
-         silc_ske_get_group_by_number(idata->rekey->ske_group,
+         silc_ske_group_get_by_number(idata->rekey->ske_group,
                                       &ctx->ske->prop->group);
 
          silc_ske_set_callbacks(ctx->ske, 
@@ -1462,7 +1497,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey)
          ctx->ske = silc_ske_alloc();
          ctx->ske->rng = server->rng;
          ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
-         silc_ske_get_group_by_number(idata->rekey->ske_group,
+         silc_ske_group_get_by_number(idata->rekey->ske_group,
                                       &ctx->ske->prop->group);
 
          silc_ske_set_callbacks(ctx->ske, 
@@ -1580,6 +1615,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey)
        encrypted with the new key so set the decryption key to the new key */
     silc_server_protocol_rekey_generate(server, ctx, FALSE);
 
+    /* Assure that after calling final callback there cannot be pending
+       executions for this protocol anymore. This just unregisters any 
+       timeout callbacks for this protocol. */
+    silc_protocol_cancel(protocol, server->schedule);
+    
     /* Protocol has ended, call the final callback */
     if (protocol->final_callback)
       silc_protocol_execute_final(protocol, server->schedule);
@@ -1597,6 +1637,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey)
       silc_ske_abort(ctx->ske, ctx->ske->status);
     }
 
+    /* Assure that after calling final callback there cannot be pending
+       executions for this protocol anymore. This just unregisters any 
+       timeout callbacks for this protocol. */
+    silc_protocol_cancel(protocol, server->schedule);
+    
     /* On error the final callback is always called. */
     if (protocol->final_callback)
       silc_protocol_execute_final(protocol, server->schedule);
@@ -1609,6 +1654,11 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey)
      * We have received failure from remote
      */
 
+    /* Assure that after calling final callback there cannot be pending
+       executions for this protocol anymore. This just unregisters any 
+       timeout callbacks for this protocol. */
+    silc_protocol_cancel(protocol, server->schedule);
+    
     /* On error the final callback is always called. */
     if (protocol->final_callback)
       silc_protocol_execute_final(protocol, server->schedule);