From: Pekka Riikonen Date: Fri, 31 Aug 2001 22:56:03 +0000 (+0000) Subject: updates. X-Git-Tag: silcertest~138 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=1ad1d027c752dc4193dbacb9192f92de293c9453;p=silc.git updates. --- diff --git a/CHANGES b/CHANGES index 346ca5ac..b49391b0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +Sat Sep 1 00:29:33 EEST 2001 Pekka Riikonen + + * 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 * Statement about ignoring the Mutual Authentication flag when diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 7a126f38..128f95af 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -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 diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 8aa845b9..ba3c9cd7 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -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; diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 66f5a996..b65af7d6 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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); diff --git a/apps/silcd/serverid.c b/apps/silcd/serverid.c index 12cebb6a..fb29b468 100644 --- a/apps/silcd/serverid.c +++ b/apps/silcd/serverid.c @@ -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; } diff --git a/apps/silcd/serverid.h b/apps/silcd/serverid.h index 82942771..4a81a4a4 100644 --- a/apps/silcd/serverid.h +++ b/apps/silcd/serverid.h @@ -23,10 +23,12 @@ /* 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 diff --git a/apps/silcd/serverincludes.h b/apps/silcd/serverincludes.h index aa2e8830..838f97ca 100644 --- a/apps/silcd/serverincludes.h +++ b/apps/silcd/serverincludes.h @@ -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"