updates.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 31 Aug 2001 22:56:03 +0000 (22:56 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 31 Aug 2001 22:56:03 +0000 (22:56 +0000)
CHANGES
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/serverid.c
apps/silcd/serverid.h
apps/silcd/serverincludes.h

diff --git a/CHANGES b/CHANGES
index 346ca5ac8684f98ec954b19bbc1d497d21c7fc13..b49391b07c27ff67decb6b3c3e5bb6de3ac60729 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,16 @@
+Sat Sep  1 00:29:33 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
+
+       * Changed the silc_id_create_client_id to be collision
+         resistant.  It is now assured that there cannot be created
+         two same client ID's.  I suspect that some weird bugs in 
+         the server were actually caused by duplicate Client IDs.
+         Affected file silcd/serverid.[ch].  A router receiving
+         new ID now also assures and informs the sending server
+         if the ID caused collision.
+
+       * Changed the silc_id_create_channel_id to also assure that
+         there are no collisions.
+
 Wed Aug 29 17:55:01 EEST 2001  Pekka Riikonen <priikone@silcnet.org>
 
        * Statement about ignoring the Mutual Authentication flag when
index 7a126f387f75aef44909a0b15d63d914fa5ebbfe..128f95af9c212b7363ad9467889367d6b21e0914 100644 (file)
@@ -1776,6 +1776,7 @@ SILC_SERVER_CMD_FUNC(nick)
   SilcClientID *new_id;
   char *nick;
   uint16 ident = silc_command_get_ident(cmd->payload);
+  int nickfail = 0;
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
     goto out;
@@ -1791,12 +1792,16 @@ SILC_SERVER_CMD_FUNC(nick)
   }
 
   if (strlen(nick) > 128)
-    nick[127] = '\0';
+    nick[128] = '\0';
 
   /* Create new Client ID */
-  silc_id_create_client_id(cmd->server->id, cmd->server->rng, 
-                          cmd->server->md5hash, nick,
-                          &new_id);
+  while (!silc_id_create_client_id(cmd->server, cmd->server->id, 
+                                  cmd->server->rng, 
+                                  cmd->server->md5hash, nick,
+                                  &new_id)) {
+    nickfail++;
+    snprintf(&nick[strlen(nick) - 1], 1, "%d", nickfail);
+  }
 
   /* Send notify about nickname change to our router. We send the new
      ID and ask to replace it with the old one. If we are router the
index 8aa845b91d62dfe3cb605ec1f6c4526f6d8945e4..ba3c9cd7d42da6e582cc8f0720fe36407dc8782b 100644 (file)
@@ -1309,6 +1309,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   uint32 id_len;
   int ret;
   char *hostname, *nickname;
+  int nickfail = 0;
 
   SILC_LOG_DEBUG(("Creating new client"));
 
@@ -1441,8 +1442,11 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   }
 
   /* Create Client ID */
-  silc_id_create_client_id(server->id, server->rng, server->md5hash,
-                          nickname, &client_id);
+  while (!silc_id_create_client_id(server, server->id, server->rng, 
+                                  server->md5hash, nickname, &client_id)) {
+    nickfail++;
+    snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
+  }
 
   /* Update client entry */
   idata->registered = TRUE;
@@ -1710,6 +1714,9 @@ static void silc_server_new_id_real(SilcServer server,
                                     id, router, NULL);
       if (!entry) {
        SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
+
+       /* Inform the sender that the ID is not usable */
+       silc_server_send_notify_signoff(server, sock, FALSE, id, NULL);
        goto out;
       }
       entry->nickname = NULL;
index 66f5a996936b0c0c878e1c8f80089bdb6c826730..b65af7d6514377b9f7d0123326faabf28eb05fca 100644 (file)
@@ -2942,7 +2942,13 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server,
   channel_name = strdup(channel_name);
 
   /* Create the channel */
-  silc_id_create_channel_id(router_id, server->rng, &channel_id);
+  if (!silc_id_create_channel_id(server, router_id, server->rng, 
+                                &channel_id)) {
+    silc_free(channel_name);
+    silc_cipher_free(key);
+    silc_hmac_free(newhmac);
+    return NULL;
+  }
   entry = silc_idlist_add_channel(server->local_list, channel_name, 
                                  SILC_CHANNEL_MODE_NONE, channel_id, 
                                  NULL, key, newhmac);
index 12cebb6a57ec3d0ebe26ea4dbd73f36c28b651ec..fb29b468412e6f2b828f4949aacd2b222385094e 100644 (file)
@@ -20,6 +20,7 @@
 /* $Id$ */
 
 #include "serverincludes.h"
+#include "server_internal.h"
 
 /* Creates a Server ID. Newly created Server ID is returned to the
    new_id argument. */
@@ -53,13 +54,19 @@ void silc_id_create_server_id(int sock, SilcRng rng, SilcServerID **new_id)
   SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_SERVER)));
 }
 
-/* Creates Client ID */
+/* Creates Client ID. This assures that there are no collisions in the
+   created Client IDs.  If the collision would occur (meaning that there
+   are 2^8 occurences of the `nickname' this will return FALSE, and the
+   caller must recall the function with different nickname. If this returns
+   TRUE the new ID was created successfully. */
 
-void silc_id_create_client_id(SilcServerID *server_id, SilcRng rng,
+bool silc_id_create_client_id(SilcServer server,
+                             SilcServerID *server_id, SilcRng rng,
                              SilcHash md5hash, char *nickname, 
                              SilcClientID **new_id)
 {
   unsigned char hash[16];
+  bool finding = FALSE;
 
   SILC_LOG_DEBUG(("Creating new Client ID"));
 
@@ -74,14 +81,42 @@ void silc_id_create_client_id(SilcServerID *server_id, SilcRng rng,
   (*new_id)->rnd = silc_rng_get_byte(rng);
   memcpy((*new_id)->hash, hash, CLIENTID_HASH_LEN);
 
+  /* Assure that the ID does not exist already */
+  while (1) {
+    if (!silc_idlist_find_client_by_id(server->local_list, 
+                                      *new_id, FALSE, NULL))
+      if (!silc_idlist_find_client_by_id(server->global_list, 
+                                        *new_id, FALSE, NULL))
+       break;
+
+    /* The ID exists, start increasing the rnd from 0 until we find a
+       ID that does not exist. If we wrap and it still exists then we
+       will return FALSE and the caller must send some other nickname
+       since this cannot be used anymore. */
+    (*new_id)->rnd++;
+
+    if (finding && (*new_id)->rnd == 0)
+      return FALSE;
+
+    if (!finding) {
+      (*new_id)->rnd = 0;
+      finding = TRUE;
+    }
+  }
+
   SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_CLIENT)));
+
+  return TRUE;
 }
 
 /* Creates Channel ID */
 
-void silc_id_create_channel_id(SilcServerID *router_id, SilcRng rng,
+bool silc_id_create_channel_id(SilcServer server,
+                              SilcServerID *router_id, SilcRng rng,
                               SilcChannelID **new_id)
 {
+  bool finding = TRUE;
+
   SILC_LOG_DEBUG(("Creating new Channel ID"));
 
   *new_id = silc_calloc(1, sizeof(**new_id));
@@ -92,5 +127,26 @@ void silc_id_create_channel_id(SilcServerID *router_id, SilcRng rng,
   (*new_id)->port = router_id->port;
   (*new_id)->rnd = silc_rng_get_rn16(rng);
 
+  /* Assure that the ID does not exist already */
+  while (1) {
+    if (!silc_idlist_find_channel_by_id(server->local_list, 
+                                       *new_id, NULL))
+      if (!silc_idlist_find_channel_by_id(server->global_list, 
+                                         *new_id, NULL))
+       break;
+    
+    (*new_id)->rnd++;
+    
+    if (finding && (*new_id)->rnd == 0)
+      return FALSE;
+    
+    if (!finding) {
+      (*new_id)->rnd = 0;
+      finding = TRUE;
+    }
+  }
+
   SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_CHANNEL)));
+
+  return TRUE;
 }
index 829427711578f9742937d599dc237cd09cd1cfe8..4a81a4a44e83273c0f39cc91a3e8f78b42edf45e 100644 (file)
 
 /* Prototypes */
 void silc_id_create_server_id(int sock, SilcRng rng, SilcServerID **new_id);
-void silc_id_create_client_id(SilcServerID *server_id, SilcRng rng,
+bool silc_id_create_client_id(SilcServer server,
+                             SilcServerID *server_id, SilcRng rng,
                              SilcHash md5hash, char *nickname, 
                              SilcClientID **new_id);
-void silc_id_create_channel_id(SilcServerID *router_id, SilcRng rng,
+bool silc_id_create_channel_id(SilcServer server,
+                              SilcServerID *router_id, SilcRng rng,
                               SilcChannelID **new_id);
 
 #endif
index aa2e8830bb8849274e629dfc1b71f962cbd4327b..838f97ca12b9b717bf51305bc0b0cd0970d396e3 100644 (file)
@@ -26,9 +26,9 @@
 
 /* SILC Server includes */
 #include "idlist.h"
-#include "serverid.h"
 #include "serverconfig.h"
 #include "server.h"
+#include "serverid.h"
 #include "packet_send.h"
 #include "packet_receive.h"
 #include "route.h"