Fixed backup router resuming protocol bugs, especially packet
authorPekka Riikonen <priikone@silcnet.org>
Thu, 5 Dec 2002 21:37:28 +0000 (21:37 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 5 Dec 2002 21:37:28 +0000 (21:37 +0000)
decryption bugs which cause server crashes.

apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server_backup.c

index afee4c0fa79c5f977f8b554f48acf0131d36ebb6..cd1f4f13dfa2b3b3482c99462e5aafe33eaddfdb 100644 (file)
@@ -741,6 +741,9 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server,
                                            unsigned char *data,
                                            unsigned int data_len)
 {
+  SilcUInt32 mac_len, iv_len;
+  unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
+
   /* If we are router and the packet came from router and private key
      has not been set for the channel then we must encrypt the packet
      as it was decrypted with the session key shared between us and the
@@ -748,11 +751,17 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server,
      same channel key. */
   if (server->server_type == SILC_ROUTER &&
       sock->type == SILC_SOCKET_TYPE_ROUTER &&
-      !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) &&
-      channel->channel_key) {
-    SilcUInt32 mac_len = silc_hmac_len(channel->hmac);
-    SilcUInt32 iv_len = silc_cipher_get_block_len(channel->channel_key);
-    unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
+      !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) {
+
+    /* If we are backup router and remote is our primary router and
+       we are currently doing backup resuming protocol we must not
+       re-encrypt message with session key. */
+    if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
+       SILC_PRIMARY_ROUTE(server) == sock)
+      return TRUE;
+
+    mac_len = silc_hmac_len(channel->hmac);
+    iv_len = silc_cipher_get_block_len(channel->channel_key);
 
     if (data_len <= mac_len + iv_len) {
       SILC_LOG_WARNING(("Corrupted channel message, cannot relay it"));
index 7c7c5294e5ed8d773fcaa5e23fb7c8507dc32d14..1e4f94adc3139d5f207271c060f5a9b1e5113ff6 100644 (file)
@@ -2144,6 +2144,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
   SilcCipher cipher = NULL;
   SilcHmac hmac = NULL;
   SilcUInt32 sequence = 0;
+  bool local_is_router;
   int ret;
 
   if (!sock) {
@@ -2265,10 +2266,20 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
     sequence = idata->psn_receive;
   }
 
-  /* Process the packet. This will call the parser that will then
+  /* Then, process the packet. This will call the parser that will then
      decrypt and parse the packet. */
-  ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ?
-                                   TRUE : FALSE, cipher, hmac, sequence,
+
+  local_is_router = (server->server_type == SILC_ROUTER);
+
+  /* If socket connection is our primary, we are backup and we are doing
+     backup resuming, we won't process the packet as being a router 
+     (affects channel message decryption). */
+  if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) &&
+      SILC_PRIMARY_ROUTE(server) == sock)
+    local_is_router = FALSE;
+
+  ret = silc_packet_receive_process(sock, local_is_router,
+                                   cipher, hmac, sequence,
                                    silc_server_packet_parse, server);
 
   /* If processing failed the connection is closed. */
@@ -2406,14 +2417,14 @@ bool silc_server_packet_parse(SilcPacketParserContext *parser_context,
        and we want to call this processor with valid cipher. */
     if (idata)
       ret = silc_packet_receive_process(
-                                 sock, server->server_type == SILC_ROUTER ?
-                                 TRUE : FALSE, idata->receive_key,
+                                 sock, server->server_type == SILC_ROUTER,
+                                 idata->receive_key,
                                  idata->hmac_receive, idata->psn_receive,
                                  silc_server_packet_parse, server);
     else
       ret = silc_packet_receive_process(
-                                 sock, server->server_type == SILC_ROUTER ?
-                                 TRUE : FALSE, NULL, NULL, 0,
+                                 sock, server->server_type == SILC_ROUTER,
+                                 NULL, NULL, 0,
                                  silc_server_packet_parse, server);
 
     if (!ret) {
@@ -2919,7 +2930,7 @@ void silc_server_close_connection(SilcServer server,
   char tmp[128];
 
   if (!server->sockets[sock->sock] && SILC_IS_DISCONNECTED(sock)) {
-    silc_schedule_task_add(server->schedule, 0,
+    silc_schedule_task_add(server->schedule, sock->sock,
                           silc_server_close_connection_final,
                           (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
                           SILC_TASK_PRI_NORMAL);
@@ -2961,7 +2972,7 @@ void silc_server_close_connection(SilcServer server,
     }
   }
 
-  silc_schedule_task_add(server->schedule, 0,
+  silc_schedule_task_add(server->schedule, sock->sock,
                         silc_server_close_connection_final,
                         (void *)sock, 0, 1, SILC_TASK_TIMEOUT,
                         SILC_TASK_PRI_NORMAL);
index 88da61f8c36115e9b1da493e83dc27db0c3482ac..a6cfffb65d4ee3c981a64abe89b58a0f193549ef 100644 (file)
@@ -1197,6 +1197,9 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done)
     SILC_LOG_ERROR(("Error occurred during backup router resuming protcool"));
   }
 
+  if (server->server_shutdown)
+    return;
+
   /* Remove this protocol from all server entries that has it */
   if (silc_idcache_get_all(server->local_list->servers, &list)) {
     if (silc_idcache_list_first(list, &id_cache)) {