Changed identifier string handling to save the original version
authorPekka Riikonen <priikone@silcnet.org>
Wed, 30 Mar 2005 12:24:53 +0000 (12:24 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 30 Mar 2005 12:24:53 +0000 (12:24 +0000)
to context's and normalized version to cache.

apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/idlist.c
apps/silcd/idlist.h
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/server_query.c
apps/silcd/server_util.c
apps/silcd/serverid.c

index 340100406efb871bd8af3591064f1a7e461ba2f7..d0cf76a3830531402db7d9eeee89ec69bbf14c72 100644 (file)
@@ -626,9 +626,8 @@ SILC_SERVER_CMD_FUNC(nick)
   SilcBuffer packet, nidp, oidp = NULL;
   SilcClientID *new_id;
   SilcUInt32 nick_len;
   SilcBuffer packet, nidp, oidp = NULL;
   SilcClientID *new_id;
   SilcUInt32 nick_len;
-  unsigned char *nick = NULL;
+  unsigned char *nick, *nickc = NULL;
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
-  int nickfail = 0;
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
     goto out;
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
     goto out;
@@ -649,46 +648,31 @@ SILC_SERVER_CMD_FUNC(nick)
     nick_len = 128;
   }
 
     nick_len = 128;
   }
 
-  /* Check for valid nickname string */
-  nick = silc_identifier_check(nick, nick_len, SILC_STRING_UTF8, 128,
-                              &nick_len);
-  if (!nick) {
+  /* Check for valid nickname string.  This is cached, original is saved
+     in the client context. */
+  nickc = silc_identifier_check(nick, nick_len, SILC_STRING_UTF8, 128, NULL);
+  if (!nickc) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
                                          SILC_STATUS_ERR_BAD_NICKNAME, 0);
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
                                          SILC_STATUS_ERR_BAD_NICKNAME, 0);
-    silc_free(nick);
     goto out;
   }
 
   /* Check for same nickname */
   if (!memcmp(client->nickname, nick, nick_len)) {
     nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
     goto out;
   }
 
   /* Check for same nickname */
   if (!memcmp(client->nickname, nick, nick_len)) {
     nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
-    silc_free(nick);
-    nick = client->nickname;
+    silc_free(nickc);
     goto send_reply;
   }
 
   /* Create new Client ID */
     goto send_reply;
   }
 
   /* Create new Client ID */
-  while (!silc_id_create_client_id(cmd->server, cmd->server->id,
-                                  cmd->server->rng,
-                                  cmd->server->md5hash, nick, nick_len,
-                                  &new_id)) {
-    nickfail++;
-    if (nickfail > 9) {
-      silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
-                                           SILC_STATUS_ERR_BAD_NICKNAME, 0);
-      goto out;
-    }
-    if (nickfail < 2) {
-      nick = silc_realloc(nick, sizeof(*nick) * (nick_len + 2));
-      if (!nick) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
-                                             SILC_STATUS_ERR_BAD_NICKNAME, 0);
-       goto out;
-      }
-      nick_len += 2;
-      nick[nick_len - 1] = '\0';
-    }
-    snprintf(&nick[nick_len - 2], 1, "%d", nickfail);
+  if (!silc_id_create_client_id(cmd->server, cmd->server->id,
+                               cmd->server->rng,
+                               cmd->server->md5hash,
+                               nickc, strlen(nickc), &new_id)) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_NICK,
+                                         SILC_STATUS_ERR_BAD_NICKNAME, 0);
+    silc_free(nickc);
+    goto out;
   }
 
   /* Send notify about nickname change to our router. We send the new
   }
 
   /* Send notify about nickname change to our router. We send the new
@@ -715,7 +699,7 @@ SILC_SERVER_CMD_FUNC(nick)
   client->nickname = nick;
 
   /* Update client cache */
   client->nickname = nick;
 
   /* Update client cache */
-  silc_idcache_add(server->local_list->clients, client->nickname,
+  silc_idcache_add(server->local_list->clients, nickc,
                   client->id, (void *)client, 0, NULL);
 
   nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
                   client->id, (void *)client, 0, NULL);
 
   nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
@@ -1571,7 +1555,7 @@ SILC_SERVER_CMD_FUNC(info)
   /* Get server name */
   dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
   if (dest_server) {
   /* Get server name */
   dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
   if (dest_server) {
-    /* Check server name */
+    /* Check server name. */
     dest_server = silc_identifier_check(dest_server, strlen(dest_server),
                                        SILC_STRING_UTF8, 256, &tmp_len);
     if (!dest_server) {
     dest_server = silc_identifier_check(dest_server, strlen(dest_server),
                                        SILC_STRING_UTF8, 256, &tmp_len);
     if (!dest_server) {
@@ -1615,7 +1599,7 @@ SILC_SERVER_CMD_FUNC(info)
   if ((!dest_server && !server_id && !entry) || (entry &&
                                                 entry == server->id_entry) ||
       (dest_server && !cmd->pending &&
   if ((!dest_server && !server_id && !entry) || (entry &&
                                                 entry == server->id_entry) ||
       (dest_server && !cmd->pending &&
-       !strncasecmp(dest_server, server->server_name, strlen(dest_server)))) {
+       !memcmp(dest_server, server->server_name, strlen(dest_server)))) {
     /* Send our reply */
     char info_string[256];
 
     /* Send our reply */
     char info_string[256];
 
@@ -1693,11 +1677,15 @@ SILC_SERVER_CMD_FUNC(info)
   silc_free(server_id);
 
   if (!entry) {
   silc_free(server_id);
 
   if (!entry) {
-    if (dest_server)
+    if (dest_server) {
+      silc_free(dest_server);
+      dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
       silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
                                           SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
                                           2, dest_server,
                                           strlen(dest_server));
       silc_server_command_send_status_data(cmd, SILC_COMMAND_INFO,
                                           SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
                                           2, dest_server,
                                           strlen(dest_server));
+      dest_server = NULL;
+    }
     goto out;
   }
 
     goto out;
   }
 
@@ -2342,7 +2330,7 @@ SILC_SERVER_CMD_FUNC(join)
   SilcServer server = cmd->server;
   unsigned char *auth, *cauth;
   SilcUInt32 tmp_len, auth_len, cauth_len;
   SilcServer server = cmd->server;
   unsigned char *auth, *cauth;
   SilcUInt32 tmp_len, auth_len, cauth_len;
-  char *tmp, *channel_name = NULL, *cipher, *hmac;
+  char *tmp, *channel_name, *channel_namec = NULL, *cipher, *hmac;
   SilcChannelEntry channel;
   SilcUInt32 umode = 0;
   bool created = FALSE, create_key = TRUE;
   SilcChannelEntry channel;
   SilcUInt32 umode = 0;
   bool created = FALSE, create_key = TRUE;
@@ -2364,11 +2352,13 @@ SILC_SERVER_CMD_FUNC(join)
     tmp[256] = '\0';
     tmp_len = 256;
   }
     tmp[256] = '\0';
     tmp_len = 256;
   }
+  channel_name = tmp;
 
 
-  /* Check for valid channel name */
-  channel_name = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8, 256,
-                                      &tmp_len);
-  if (!channel_name) {
+  /* Check for valid channel name.  This is cached, the original is saved
+     in the channel context. */
+  channel_namec = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8, 256,
+                                       NULL);
+  if (!channel_namec) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                          SILC_STATUS_ERR_BAD_CHANNEL, 0);
     goto out;
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                          SILC_STATUS_ERR_BAD_CHANNEL, 0);
     goto out;
@@ -2398,7 +2388,7 @@ SILC_SERVER_CMD_FUNC(join)
 
   /* See if the channel exists */
   channel = silc_idlist_find_channel_by_name(server->local_list,
 
   /* See if the channel exists */
   channel = silc_idlist_find_channel_by_name(server->local_list,
-                                            channel_name, NULL);
+                                            channel_namec, NULL);
 
   if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
     SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
 
   if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
     SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
@@ -2478,7 +2468,7 @@ SILC_SERVER_CMD_FUNC(join)
        /* We are router and the channel does not seem exist so we will check
           our global list as well for the channel. */
        channel = silc_idlist_find_channel_by_name(server->global_list,
        /* We are router and the channel does not seem exist so we will check
           our global list as well for the channel. */
        channel = silc_idlist_find_channel_by_name(server->global_list,
-                                                  channel_name, NULL);
+                                                  channel_namec, NULL);
        if (!channel) {
          /* Channel really does not exist, create it */
          channel = silc_server_create_new_channel(server, server->id, cipher,
        if (!channel) {
          /* Channel really does not exist, create it */
          channel = silc_server_create_new_channel(server, server->id, cipher,
@@ -2514,7 +2504,7 @@ SILC_SERVER_CMD_FUNC(join)
       /* We are router and the channel does not seem exist so we will check
         our global list as well for the channel. */
       channel = silc_idlist_find_channel_by_name(server->global_list,
       /* We are router and the channel does not seem exist so we will check
         our global list as well for the channel. */
       channel = silc_idlist_find_channel_by_name(server->global_list,
-                                                channel_name, NULL);
+                                                channel_namec, NULL);
       if (!channel) {
        /* Channel really does not exist, create it */
        channel = silc_server_create_new_channel(server, server->id, cipher,
       if (!channel) {
        /* Channel really does not exist, create it */
        channel = silc_server_create_new_channel(server, server->id, cipher,
@@ -2708,10 +2698,13 @@ SILC_SERVER_CMD_FUNC(motd)
     }
 
     if (!entry) {
     }
 
     if (!entry) {
+      silc_free(dest_server);
+      dest_server = silc_argument_get_arg_type(cmd->args, 1, NULL);
       silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
                                           SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
                                           2, dest_server,
                                           strlen(dest_server));
       silc_server_command_send_status_data(cmd, SILC_COMMAND_MOTD,
                                           SILC_STATUS_ERR_NO_SUCH_SERVER, 0,
                                           2, dest_server,
                                           strlen(dest_server));
+      dest_server = NULL;
       goto out;
     }
 
       goto out;
     }
 
@@ -4748,7 +4741,7 @@ SILC_SERVER_CMD_FUNC(users)
   unsigned char lc[4];
   SilcUInt32 list_count = 0;
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
   unsigned char lc[4];
   SilcUInt32 list_count = 0;
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
-  char *channel_name = NULL;
+  char *channel_name, *channel_namec = NULL;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
 
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_USERS, cmd, 1, 2);
 
@@ -4766,9 +4759,9 @@ SILC_SERVER_CMD_FUNC(users)
 
   /* Check channel name */
   if (channel_name) {
 
   /* Check channel name */
   if (channel_name) {
-    channel_name = silc_identifier_check(channel_name, strlen(channel_name),
-                                        SILC_STRING_UTF8, 256, NULL);
-    if (!channel_name) {
+    channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
+                                         SILC_STRING_UTF8, 256, NULL);
+    if (!channel_namec) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
                                            SILC_STATUS_ERR_BAD_CHANNEL, 0);
       goto out;
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
                                            SILC_STATUS_ERR_BAD_CHANNEL, 0);
       goto out;
@@ -4793,7 +4786,7 @@ SILC_SERVER_CMD_FUNC(users)
     channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
   else
     channel = silc_idlist_find_channel_by_name(server->local_list,
     channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
   else
     channel = silc_idlist_find_channel_by_name(server->local_list,
-                                              channel_name, NULL);
+                                              channel_namec, NULL);
 
   if (!channel || (!server->standalone && (channel->disabled ||
                    !channel->users_resolved))) {
 
   if (!channel || (!server->standalone && (channel->disabled ||
                    !channel->users_resolved))) {
@@ -4826,7 +4819,7 @@ SILC_SERVER_CMD_FUNC(users)
       channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
     else
       channel = silc_idlist_find_channel_by_name(server->global_list,
       channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
     else
       channel = silc_idlist_find_channel_by_name(server->global_list,
-                                                channel_name, NULL);
+                                                channel_namec, NULL);
     if (!channel) {
       /* Channel really does not exist */
       if (id)
     if (!channel) {
       /* Channel really does not exist */
       if (id)
@@ -4894,7 +4887,7 @@ SILC_SERVER_CMD_FUNC(users)
   silc_free(id);
 
  out:
   silc_free(id);
 
  out:
-  silc_free(channel_name);
+  silc_free(channel_namec);
   silc_server_command_free(cmd);
 }
 
   silc_server_command_free(cmd);
 }
 
index 99f459550d32c41ee06f82d21c47b96b09f24bf7..1250eaa5c9be5bf1a300a39f84c7a58e37744931 100644 (file)
@@ -197,14 +197,6 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
 
   fingerprint = silc_argument_get_arg_type(cmd->args, 9, &flen);
 
 
   fingerprint = silc_argument_get_arg_type(cmd->args, 9, &flen);
 
-  /* Check for valid username */
-  username = silc_identifier_check(username, strlen(username),
-                                  SILC_STRING_UTF8, 128, NULL);
-  if (!username) {
-    SILC_LOG_ERROR(("Malformed username received in WHOIS reply"));
-    return FALSE;
-  }
-
   /* Check if we have this client cached already. */
 
   client = silc_idlist_find_client_by_id(server->local_list, client_id,
   /* Check if we have this client cached already. */
 
   client = silc_idlist_find_client_by_id(server->local_list, client_id,
@@ -218,35 +210,21 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
   if (!client) {
     /* If router did not find such Client ID in its lists then this must
        be bogus client or some router in the net is buggy. */
   if (!client) {
     /* If router did not find such Client ID in its lists then this must
        be bogus client or some router in the net is buggy. */
-    if (server->server_type != SILC_SERVER) {
-      silc_free(username);
+    if (server->server_type != SILC_SERVER)
       return FALSE;
       return FALSE;
-    }
 
     /* Take hostname out of nick string if it includes it. */
     silc_parse_userfqdn(nickname, &nick, &servername);
 
 
     /* Take hostname out of nick string if it includes it. */
     silc_parse_userfqdn(nickname, &nick, &servername);
 
-    /* Check nickname */
-    nickname = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8,
-                                    128, NULL);
-    if (!nickname) {
-      SILC_LOG_ERROR(("Malformed nickname received in WHOIS reply"));
-      silc_free(username);
-      return FALSE;
-    }
-    silc_free(nick);
-    nick = nickname;
-
     /* We don't have that client anywhere, add it. The client is added
        to global list since server didn't have it in the lists so it must be
     /* We don't have that client anywhere, add it. The client is added
        to global list since server didn't have it in the lists so it must be
-       global. */
+       global. This will check for valid nickname and username strings. */
     client = silc_idlist_add_client(server->global_list, nick, username,
                                    strdup(realname), client_id,
                                    cmd->sock->user_data, NULL, 0);
     if (!client) {
       SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
       silc_free(nick);
     client = silc_idlist_add_client(server->global_list, nick, username,
                                    strdup(realname), client_id,
                                    cmd->sock->user_data, NULL, 0);
     if (!client) {
       SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
       silc_free(nick);
-      silc_free(username);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -268,11 +246,16 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
                                     128, NULL);
     if (!nickname) {
       SILC_LOG_ERROR(("Malformed nickname received in WHOIS reply"));
                                     128, NULL);
     if (!nickname) {
       SILC_LOG_ERROR(("Malformed nickname received in WHOIS reply"));
-      silc_free(username);
       return FALSE;
     }
       return FALSE;
     }
-    silc_free(nick);
-    nick = nickname;
+
+    /* Check username */
+    username = silc_identifier_check(username, strlen(username),
+                                    SILC_STRING_UTF8, 128, NULL);
+    if (!username) {
+      SILC_LOG_ERROR(("Malformed username received in WHOIS reply"));
+      return FALSE;
+    }
 
     /* Remove the old cache entry  */
     silc_idcache_del_by_context(global ? server->global_list->clients :
 
     /* Remove the old cache entry  */
     silc_idcache_del_by_context(global ? server->global_list->clients :
@@ -293,7 +276,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
 
     /* Create new cache entry */
     silc_idcache_add(global ? server->global_list->clients :
 
     /* Create new cache entry */
     silc_idcache_add(global ? server->global_list->clients :
-                    server->local_list->clients, nick, client->id,
+                    server->local_list->clients, nickname, client->id,
                     client, 0, NULL);
     silc_free(client_id);
   }
                     client, 0, NULL);
     silc_free(client_id);
   }
@@ -397,7 +380,6 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     }
   }
 
     }
   }
 
-  silc_free(username);
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -489,14 +471,6 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
   if (!client_id)
     return FALSE;
 
   if (!client_id)
     return FALSE;
 
-  /* Check for valid username */
-  username = silc_identifier_check(username, strlen(username),
-                                  SILC_STRING_UTF8, 128, NULL);
-  if (!username) {
-    SILC_LOG_ERROR(("Malformed username received in WHOWAS reply"));
-    return FALSE;
-  }
-
   /* Check if we have this client cached already. */
 
   client = silc_idlist_find_client_by_id(server->local_list, client_id,
   /* Check if we have this client cached already. */
 
   client = silc_idlist_find_client_by_id(server->local_list, client_id,
@@ -510,25 +484,12 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
   if (!client) {
     /* If router did not find such Client ID in its lists then this must
        be bogus client or some router in the net is buggy. */
   if (!client) {
     /* If router did not find such Client ID in its lists then this must
        be bogus client or some router in the net is buggy. */
-    if (server->server_type != SILC_SERVER) {
-      silc_free(username);
+    if (server->server_type != SILC_SERVER)
       return FALSE;
       return FALSE;
-    }
 
     /* Take hostname out of nick string if it includes it. */
     silc_parse_userfqdn(nickname, &nick, &servername);
 
 
     /* Take hostname out of nick string if it includes it. */
     silc_parse_userfqdn(nickname, &nick, &servername);
 
-    /* Check nickname */
-    nickname = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8,
-                                    128, NULL);
-    if (!nickname) {
-      SILC_LOG_ERROR(("Malformed nickname received in WHOWAS reply"));
-      silc_free(username);
-      return FALSE;
-    }
-    silc_free(nick);
-    nick = nickname;
-
     /* We don't have that client anywhere, add it. The client is added
        to global list since server didn't have it in the lists so it must be
        global. */
     /* We don't have that client anywhere, add it. The client is added
        to global list since server didn't have it in the lists so it must be
        global. */
@@ -540,7 +501,6 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     if (!client) {
       SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
       silc_free(nick);
     if (!client) {
       SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
       silc_free(nick);
-      silc_free(username);
       return FALSE;
     }
 
       return FALSE;
     }
 
@@ -559,11 +519,16 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
                                     128, NULL);
     if (!nickname) {
       SILC_LOG_ERROR(("Malformed nickname received in WHOWAS reply"));
                                     128, NULL);
     if (!nickname) {
       SILC_LOG_ERROR(("Malformed nickname received in WHOWAS reply"));
-      silc_free(username);
       return FALSE;
     }
       return FALSE;
     }
-    silc_free(nick);
-    nick = nickname;
+
+    /* Check username */
+    username = silc_identifier_check(username, strlen(username),
+                                    SILC_STRING_UTF8, 128, NULL);
+    if (!username) {
+      SILC_LOG_ERROR(("Malformed username received in WHOWAS reply"));
+      return FALSE;
+    }
 
     silc_free(client->nickname);
     silc_free(client->username);
 
     silc_free(client->nickname);
     silc_free(client->username);
@@ -579,7 +544,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     silc_idcache_del_by_context(global ? server->global_list->clients :
                                server->local_list->clients, client);
     silc_idcache_add(global ? server->global_list->clients :
     silc_idcache_del_by_context(global ? server->global_list->clients :
                                server->local_list->clients, client);
     silc_idcache_add(global ? server->global_list->clients :
-                    server->local_list->clients, nick, client->id,
+                    server->local_list->clients, nickname, client->id,
                     client, 0, NULL);
   }
 
                     client, 0, NULL);
   }
 
@@ -595,7 +560,6 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
   }
 
   silc_free(client_id);
   }
 
   silc_free(client_id);
-  silc_free(username);
 
   return TRUE;
 }
 
   return TRUE;
 }
@@ -686,25 +650,13 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
        goto error;
 
       /* Take nickname */
        goto error;
 
       /* Take nickname */
-      if (name) {
+      if (name)
        silc_parse_userfqdn(name, &nick, NULL);
 
        silc_parse_userfqdn(name, &nick, NULL);
 
-       /* Check nickname */
-       name = silc_identifier_check(nick, strlen(nick), SILC_STRING_UTF8,
-                                  128, NULL);
-       if (!name) {
-         SILC_LOG_ERROR(("Malformed nickname received in IDENTIFY reply"));
-         return FALSE;
-       }
-       silc_free(nick);
-       nick = name;
-      }
-
       /* We don't have that client anywhere, add it. The client is added
         to global list since server didn't have it in the lists so it must be
         global. */
       /* We don't have that client anywhere, add it. The client is added
         to global list since server didn't have it in the lists so it must be
         global. */
-      client = silc_idlist_add_client(server->global_list, nick,
-                                     info ? strdup(info) : NULL, NULL,
+      client = silc_idlist_add_client(server->global_list, nick, info, NULL,
                                      client_id, cmd->sock->user_data,
                                      NULL, time(NULL) + 300);
       if (!client) {
                                      client_id, cmd->sock->user_data,
                                      NULL, time(NULL) + 300);
       if (!client) {
@@ -712,6 +664,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
        silc_free(nick);
        goto error;
       }
        silc_free(nick);
        goto error;
       }
+
       client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
       client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
       client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
       client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
       client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
       client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
@@ -731,8 +684,6 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
          SILC_LOG_ERROR(("Malformed nickname received in IDENTIFY reply"));
          return FALSE;
        }
          SILC_LOG_ERROR(("Malformed nickname received in IDENTIFY reply"));
          return FALSE;
        }
-       silc_free(nick);
-       nick = name;
 
        /* Remove the old cache entry */
        silc_idcache_del_by_context(global ? server->global_list->clients :
 
        /* Remove the old cache entry */
        silc_idcache_del_by_context(global ? server->global_list->clients :
@@ -740,6 +691,11 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
 
        silc_free(client->nickname);
        client->nickname = nick;
 
        silc_free(client->nickname);
        client->nickname = nick;
+
+       /* Add new cache entry */
+       silc_idcache_add(global ? server->global_list->clients :
+                        server->local_list->clients, name, client->id,
+                        client, expire, NULL);
       }
 
       if (info) {
       }
 
       if (info) {
@@ -750,13 +706,6 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
       client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
       client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
 
       client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
       client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
 
-      if (name) {
-       /* Add new cache entry */
-       silc_idcache_add(global ? server->global_list->clients :
-                        server->local_list->clients, nick, client->id,
-                        client, expire, NULL);
-      }
-
       /* If client is global and is not on any channel then add that we'll
          expire the entry after a while. */
       if (global && server->server_type == SILC_SERVER) {
       /* If client is global and is not on any channel then add that we'll
          expire the entry after a while. */
       if (global && server->server_type == SILC_SERVER) {
@@ -823,16 +772,24 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
 
     SILC_LOG_DEBUG(("Received channel information"));
 
 
     SILC_LOG_DEBUG(("Received channel information"));
 
+    /* Check channel name */
+    info = silc_identifier_check(name, strlen(name), SILC_STRING_UTF8,
+                                256, NULL);
+    if (!info)
+      goto error;
+
     channel = silc_idlist_find_channel_by_name(server->local_list,
     channel = silc_idlist_find_channel_by_name(server->local_list,
-                                              name, NULL);
+                                              info, NULL);
     if (!channel)
       channel = silc_idlist_find_channel_by_name(server->global_list,
     if (!channel)
       channel = silc_idlist_find_channel_by_name(server->global_list,
-                                                name, NULL);
+                                                info, NULL);
     if (!channel) {
       /* If router did not find such Channel ID in its lists then this must
         be bogus channel or some router in the net is buggy. */
     if (!channel) {
       /* If router did not find such Channel ID in its lists then this must
         be bogus channel or some router in the net is buggy. */
-      if (server->server_type != SILC_SERVER)
+      if (server->server_type != SILC_SERVER) {
+       silc_free(info);
        goto error;
        goto error;
+      }
 
       /* We don't have that channel anywhere, add it. */
       channel = silc_idlist_add_channel(server->global_list, strdup(name),
 
       /* We don't have that channel anywhere, add it. */
       channel = silc_idlist_add_channel(server->global_list, strdup(name),
@@ -840,8 +797,10 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
                                        server->router, NULL, NULL, 0);
       if (!channel) {
        silc_free(channel_id);
                                        server->router, NULL, NULL, 0);
       if (!channel) {
        silc_free(channel_id);
+       silc_free(info);
        goto error;
       }
        goto error;
       }
+      silc_free(info);
       channel_id = NULL;
     }
 
       channel_id = NULL;
     }
 
@@ -900,7 +859,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
   SilcServerEntry entry;
   SilcServerID *server_id;
   SilcUInt32 tmp_len;
   SilcServerEntry entry;
   SilcServerID *server_id;
   SilcUInt32 tmp_len;
-  unsigned char *tmp, *name = NULL;
+  unsigned char *tmp, *name;
 
   COMMAND_CHECK_STATUS;
 
 
   COMMAND_CHECK_STATUS;
 
@@ -917,12 +876,6 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
   if (!name)
     goto out;
 
   if (!name)
     goto out;
 
-  /* Check server name */
-  name = silc_identifier_check(name, tmp_len, SILC_STRING_UTF8,
-                              256, NULL);
-  if (!name)
-    goto out;
-
   entry = silc_idlist_find_server_by_id(server->local_list, server_id,
                                        FALSE, NULL);
   if (!entry) {
   entry = silc_idlist_find_server_by_id(server->local_list, server_id,
                                        FALSE, NULL);
   if (!entry) {
@@ -931,12 +884,11 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
     if (!entry) {
       /* Add the server to global list */
       server_id = silc_id_dup(server_id, SILC_ID_SERVER);
     if (!entry) {
       /* Add the server to global list */
       server_id = silc_id_dup(server_id, SILC_ID_SERVER);
-      entry = silc_idlist_add_server(server->global_list, name, 0,
+      entry = silc_idlist_add_server(server->global_list, strdup(name), 0,
                                     server_id, cmd->sock->user_data,
                                     cmd->sock);
       if (!entry) {
        silc_free(server_id);
                                     server_id, cmd->sock->user_data,
                                     cmd->sock);
       if (!entry) {
        silc_free(server_id);
-       silc_free(name);
        goto out;
       }
       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
        goto out;
       }
       entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
@@ -950,8 +902,6 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
 
   entry->server_info = tmp ? strdup(tmp) : NULL;
 
 
   entry->server_info = tmp ? strdup(tmp) : NULL;
 
-  silc_free(name);
-
  out:
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_INFO);
  err:
  out:
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_INFO);
  err:
@@ -1045,7 +995,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
   SilcHmac hmac = NULL;
   SilcUInt32 id_len, len, list_count;
   unsigned char *id_string;
   SilcHmac hmac = NULL;
   SilcUInt32 id_len, len, list_count;
   unsigned char *id_string;
-  char *channel_name, *tmp;
+  char *channel_name, *channel_namec = NULL, *tmp;
   SilcUInt32 mode, created;
   SilcBuffer keyp = NULL, client_id_list = NULL, client_mode_list = NULL;
   SilcPublicKey founder_key = NULL;
   SilcUInt32 mode, created;
   SilcBuffer keyp = NULL, client_id_list = NULL, client_mode_list = NULL;
   SilcPublicKey founder_key = NULL;
@@ -1134,8 +1084,12 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
     silc_pkcs_public_key_payload_decode(tmp, len, &founder_key);
 
   /* See whether we already have the channel. */
     silc_pkcs_public_key_payload_decode(tmp, len, &founder_key);
 
   /* See whether we already have the channel. */
+  channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
+                                       SILC_STRING_UTF8, 256, NULL);
+  if (!channel_namec)
+    goto out;
   entry = silc_idlist_find_channel_by_name(server->local_list,
   entry = silc_idlist_find_channel_by_name(server->local_list,
-                                          channel_name, &cache);
+                                          channel_namec, &cache);
   if (!entry) {
     /* Add new channel */
 
   if (!entry) {
     /* Add new channel */
 
@@ -1146,7 +1100,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
     /* If the channel is found from global list we must move it to the
        local list. */
     entry = silc_idlist_find_channel_by_name(server->global_list,
     /* If the channel is found from global list we must move it to the
        local list. */
     entry = silc_idlist_find_channel_by_name(server->global_list,
-                                            channel_name, &cache);
+                                            channel_namec, &cache);
     if (entry)
       silc_idlist_del_channel(server->global_list, entry);
 
     if (entry)
       silc_idlist_del_channel(server->global_list, entry);
 
@@ -1281,6 +1235,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
  out:
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_JOIN);
  err:
  out:
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_JOIN);
  err:
+  silc_free(channel_namec);
   if (hmac)
     silc_hmac_free(hmac);
   silc_free(client_id);
   if (hmac)
     silc_hmac_free(hmac);
   silc_free(client_id);
@@ -1521,7 +1476,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   SilcChannelEntry channel;
   SilcIDCacheEntry cache;
   SilcUInt32 len;
   SilcChannelEntry channel;
   SilcIDCacheEntry cache;
   SilcUInt32 len;
-  unsigned char *tmp, *name, *topic;
+  unsigned char *tmp, *name, *namec = NULL, *topic;
   SilcUInt32 usercount = 0;
   bool global_list = FALSE;
 
   SilcUInt32 usercount = 0;
   bool global_list = FALSE;
 
@@ -1538,12 +1493,17 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   if (tmp)
     SILC_GET32_MSB(usercount, tmp);
 
   if (tmp)
     SILC_GET32_MSB(usercount, tmp);
 
+  namec = silc_identifier_check(name, strlen(name), SILC_STRING_UTF8,
+                               256, NULL);
+  if (!namec)
+    goto out;
+
   /* Add the channel entry if we do not have it already */
   channel = silc_idlist_find_channel_by_name(server->local_list,
   /* Add the channel entry if we do not have it already */
   channel = silc_idlist_find_channel_by_name(server->local_list,
-                                            name, &cache);
+                                            namec, &cache);
   if (!channel) {
     channel = silc_idlist_find_channel_by_name(server->global_list,
   if (!channel) {
     channel = silc_idlist_find_channel_by_name(server->global_list,
-                                              name, &cache);
+                                              namec, &cache);
     global_list = TRUE;
   }
   if (!channel) {
     global_list = TRUE;
   }
   if (!channel) {
@@ -1587,6 +1547,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_LIST);
   silc_free(channel_id);
  err:
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_LIST);
   silc_free(channel_id);
  err:
+  silc_free(namec);
   silc_server_command_reply_free(cmd);
 }
 
   silc_server_command_reply_free(cmd);
 }
 
index 91ac9cf2d8b093a9b449096267ebc630bdf671f9..e3f3df8ab6cc7ee4dff05c9bec49a75cbadc2680 100644 (file)
@@ -119,9 +119,18 @@ silc_idlist_add_server(SilcIDList id_list,
                       void *connection)
 {
   SilcServerEntry server;
                       void *connection)
 {
   SilcServerEntry server;
+  char *server_namec = NULL;
 
   SILC_LOG_DEBUG(("Adding new server entry"));
 
 
   SILC_LOG_DEBUG(("Adding new server entry"));
 
+  /* Normalize name.  This is cached, original is in server context.  */
+  if (server_name) {
+    server_namec = silc_identifier_check(server_name, strlen(server_name),
+                                        SILC_STRING_UTF8, 256, NULL);
+    if (!server_namec)
+      return NULL;
+  }
+
   server = silc_calloc(1, sizeof(*server));
   server->server_name = server_name;
   server->server_type = server_type;
   server = silc_calloc(1, sizeof(*server));
   server->server_name = server_name;
   server->server_type = server_type;
@@ -129,9 +138,10 @@ silc_idlist_add_server(SilcIDList id_list,
   server->router = router;
   server->connection = connection;
 
   server->router = router;
   server->connection = connection;
 
-  if (!silc_idcache_add(id_list->servers, server->server_name,
+  if (!silc_idcache_add(id_list->servers, server_namec,
                        (void *)server->id, (void *)server, 0, NULL)) {
     silc_free(server);
                        (void *)server->id, (void *)server, 0, NULL)) {
     silc_free(server);
+    silc_free(server_namec);
     return NULL;
   }
 
     return NULL;
   }
 
@@ -171,7 +181,7 @@ silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id,
   return server;
 }
 
   return server;
 }
 
-/* Find server by name */
+/* Find server by name.  The 'name' must be normalized already. */
 
 SilcServerEntry
 silc_idlist_find_server_by_name(SilcIDList id_list, char *name,
 
 SilcServerEntry
 silc_idlist_find_server_by_name(SilcIDList id_list, char *name,
@@ -259,6 +269,7 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcServerEntry server;
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcServerEntry server;
+  char *name;
 
   if (!old_id || !new_id)
     return NULL;
 
   if (!old_id || !new_id)
     return NULL;
@@ -270,6 +281,7 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
     return NULL;
 
   server = (SilcServerEntry)id_cache->context;
     return NULL;
 
   server = (SilcServerEntry)id_cache->context;
+  name = strdup(id_cache->name);
 
   /* Remove the old entry and add a new one */
 
 
   /* Remove the old entry and add a new one */
 
@@ -278,8 +290,7 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
   silc_free(server->id);
   server->id = new_id;
 
   silc_free(server->id);
   server->id = new_id;
 
-  silc_idcache_add(id_list->servers, server->server_name, server->id,
-                  server, 0, NULL);
+  silc_idcache_add(id_list->servers, name, server->id, server, 0, NULL);
 
   SILC_LOG_DEBUG(("Found"));
 
 
   SILC_LOG_DEBUG(("Found"));
 
@@ -337,12 +348,29 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
                       int expire)
 {
   SilcClientEntry client;
                       int expire)
 {
   SilcClientEntry client;
+  char *nicknamec = NULL, *usernamec = NULL;
 
   SILC_LOG_DEBUG(("Adding new client entry"));
 
 
   SILC_LOG_DEBUG(("Adding new client entry"));
 
+  /* Normalize name.  This is cached, original is in client context.  */
+  if (nickname) {
+    nicknamec = silc_identifier_check(nickname, strlen(nickname),
+                                     SILC_STRING_UTF8, 128, NULL);
+    if (!nicknamec)
+      return NULL;
+  }
+
+  /* Normalize username. */
+  if (username) {
+    usernamec = silc_identifier_check(username, strlen(username),
+                                     SILC_STRING_UTF8, 128, NULL);
+    if (!usernamec)
+      return NULL;
+  }
+
   client = silc_calloc(1, sizeof(*client));
   client->nickname = nickname;
   client = silc_calloc(1, sizeof(*client));
   client->nickname = nickname;
-  client->username = username;
+  client->username = usernamec;
   client->userinfo = userinfo;
   client->id = id;
   client->router = router;
   client->userinfo = userinfo;
   client->id = id;
   client->router = router;
@@ -350,10 +378,12 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
   client->channels = silc_hash_table_alloc(3, silc_hash_ptr, NULL,
                                           NULL, NULL, NULL, NULL, TRUE);
 
   client->channels = silc_hash_table_alloc(3, silc_hash_ptr, NULL,
                                           NULL, NULL, NULL, NULL, TRUE);
 
-  if (!silc_idcache_add(id_list->clients, nickname, (void *)client->id,
+  if (!silc_idcache_add(id_list->clients, nicknamec, (void *)client->id,
                        (void *)client, expire, NULL)) {
     silc_hash_table_free(client->channels);
     silc_free(client);
                        (void *)client, expire, NULL)) {
     silc_hash_table_free(client->channels);
     silc_free(client);
+    silc_free(nicknamec);
+    silc_free(usernamec);
     return NULL;
   }
 
     return NULL;
   }
 
@@ -368,7 +398,7 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
   SILC_LOG_DEBUG(("Start"));
 
   if (entry) {
   SILC_LOG_DEBUG(("Start"));
 
   if (entry) {
-    /* Remove from cache */
+    /* Remove from cache. Destructor callback deletes stuff. */
     if (!silc_idcache_del_by_context(id_list->clients, entry)) {
       SILC_LOG_DEBUG(("Unknown client, did not delete"));
       return FALSE;
     if (!silc_idcache_del_by_context(id_list->clients, entry)) {
       SILC_LOG_DEBUG(("Unknown client, did not delete"));
       return FALSE;
@@ -376,7 +406,6 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 
     assert(!silc_hash_table_count(entry->channels));
 
 
     assert(!silc_hash_table_count(entry->channels));
 
-    /* Free data */
     silc_free(entry->nickname);
     silc_free(entry->servername);
     silc_free(entry->username);
     silc_free(entry->nickname);
     silc_free(entry->servername);
     silc_free(entry->username);
@@ -394,8 +423,32 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
   return FALSE;
 }
 
   return FALSE;
 }
 
+/* ID Cache destructor */
+
+void silc_idlist_client_destructor(SilcIDCache cache,
+                                  SilcIDCacheEntry entry)
+{
+  SilcClientEntry client;
+
+  client = (SilcClientEntry)entry->context;
+  if (client) {
+    assert(!silc_hash_table_count(client->channels));
+    silc_free(client->nickname);
+    silc_free(client->servername);
+    silc_free(client->username);
+    silc_free(client->userinfo);
+    silc_free(client->id);
+    silc_free(client->attrs);
+    silc_hash_table_free(client->channels);
+
+    memset(client, 'A', sizeof(*client));
+    silc_free(client);
+  }
+}
+
 /* Returns all clients matching requested nickname. Number of clients is
 /* Returns all clients matching requested nickname. Number of clients is
-   returned to `clients_count'. Caller must free the returned table. */
+   returned to `clients_count'. Caller must free the returned table.
+   The 'nickname' must be normalized already. */
 
 int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
                                        char *server,
 
 int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
                                        char *server,
@@ -427,7 +480,8 @@ int silc_idlist_get_clients_by_nickname(SilcIDList id_list, char *nickname,
 }
 
 /* Returns all clients matching requested nickname hash. Number of clients
 }
 
 /* Returns all clients matching requested nickname hash. Number of clients
-   is returned to `clients_count'. Caller must free the returned table. */
+   is returned to `clients_count'. Caller must free the returned table.
+   The 'nickname' must be normalized already. */
 
 int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname,
                                    SilcHash md5hash,
 
 int silc_idlist_get_clients_by_hash(SilcIDList id_list, char *nickname,
                                    SilcHash md5hash,
@@ -517,12 +571,21 @@ silc_idlist_replace_client_id(SilcServer server,
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client;
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client;
+  char *nicknamec = NULL;
 
   if (!old_id || !new_id)
     return NULL;
 
   SILC_LOG_DEBUG(("Replacing Client ID"));
 
 
   if (!old_id || !new_id)
     return NULL;
 
   SILC_LOG_DEBUG(("Replacing Client ID"));
 
+  /* Normalize name. This is cached, original is in client context.  */
+  if (nickname) {
+    nicknamec = silc_identifier_check(nickname, strlen(nickname),
+                                     SILC_STRING_UTF8, 128, NULL);
+    if (!nicknamec)
+      return NULL;
+  }
+
   /* Do extended search since the normal ID comparison function for
      Client ID's compares only the hash from the Client ID and not the
      entire ID. The silc_hash_client_id_compare compares the entire
   /* Do extended search since the normal ID comparison function for
      Client ID's compares only the hash from the Client ID and not the
      entire ID. The silc_hash_client_id_compare compares the entire
@@ -548,14 +611,14 @@ silc_idlist_replace_client_id(SilcServer server,
   silc_free(client->id);
   silc_free(client->nickname);
   client->id = new_id;
   silc_free(client->id);
   silc_free(client->nickname);
   client->id = new_id;
-  client->nickname = nickname ? silc_memdup(nickname, strlen(nickname)) : NULL;
+  client->nickname = nickname ? strdup(nickname) : NULL;
 
   /* Check if anyone is watching new nickname */
   if (server->server_type == SILC_ROUTER)
     silc_server_check_watcher_list(server, client, nickname,
                                   SILC_NOTIFY_TYPE_NICK_CHANGE);
 
 
   /* Check if anyone is watching new nickname */
   if (server->server_type == SILC_ROUTER)
     silc_server_check_watcher_list(server, client, nickname,
                                   SILC_NOTIFY_TYPE_NICK_CHANGE);
 
-  if (!silc_idcache_add(id_list->clients, client->nickname, client->id,
+  if (!silc_idcache_add(id_list->clients, nicknamec, client->id,
                        client, 0, NULL))
     return NULL;
 
                        client, 0, NULL))
     return NULL;
 
@@ -564,27 +627,6 @@ silc_idlist_replace_client_id(SilcServer server,
   return client;
 }
 
   return client;
 }
 
-/* Client cache entry destructor that is called when the cache is purged. */
-
-void silc_idlist_client_destructor(SilcIDCache cache,
-                                  SilcIDCacheEntry entry)
-{
-  SilcClientEntry client;
-
-  client = (SilcClientEntry)entry->context;
-  if (client) {
-    assert(!silc_hash_table_count(client->channels));
-    silc_free(client->nickname);
-    silc_free(client->username);
-    silc_free(client->userinfo);
-    silc_free(client->id);
-    silc_free(client->attrs);
-    silc_hash_table_free(client->channels);
-
-    memset(client, 'A', sizeof(*client));
-    silc_free(client);
-  }
-}
 
 /******************************************************************************
 
 
 /******************************************************************************
 
@@ -602,9 +644,18 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
                        int expire)
 {
   SilcChannelEntry channel;
                        int expire)
 {
   SilcChannelEntry channel;
+  char *channel_namec = NULL;
 
   SILC_LOG_DEBUG(("Adding new channel %s", channel_name));
 
 
   SILC_LOG_DEBUG(("Adding new channel %s", channel_name));
 
+  /* Normalize name.  This is cached, original is in client context.  */
+  if (channel_name) {
+    channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
+                                         SILC_STRING_UTF8, 256, NULL);
+    if (!channel_namec)
+      return NULL;
+  }
+
   channel = silc_calloc(1, sizeof(*channel));
   channel->channel_name = channel_name;
   channel->mode = mode;
   channel = silc_calloc(1, sizeof(*channel));
   channel->channel_name = channel_name;
   channel->mode = mode;
@@ -622,11 +673,12 @@ silc_idlist_add_channel(SilcIDList id_list, char *channel_name, int mode,
   channel->user_list = silc_hash_table_alloc(3, silc_hash_ptr, NULL, NULL,
                                             NULL, NULL, NULL, TRUE);
 
   channel->user_list = silc_hash_table_alloc(3, silc_hash_ptr, NULL, NULL,
                                             NULL, NULL, NULL, TRUE);
 
-  if (!silc_idcache_add(id_list->channels, channel->channel_name,
+  if (!silc_idcache_add(id_list->channels, channel_namec,
                        (void *)channel->id, (void *)channel, expire, NULL)) {
     silc_hmac_free(channel->hmac);
     silc_hash_table_free(channel->user_list);
     silc_free(channel);
                        (void *)channel->id, (void *)channel, expire, NULL)) {
     silc_hmac_free(channel->hmac);
     silc_hash_table_free(channel->user_list);
     silc_free(channel);
+    silc_free(channel_namec);
     return NULL;
   }
 
     return NULL;
   }
 
@@ -706,7 +758,7 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
 }
 
 /* Finds channel by channel name. Channel names are unique and they
 }
 
 /* Finds channel by channel name. Channel names are unique and they
-   are not case-sensitive. */
+   are not case-sensitive.  The 'name' must be normalized already. */
 
 SilcChannelEntry
 silc_idlist_find_channel_by_name(SilcIDList id_list, char *name,
 
 SilcChannelEntry
 silc_idlist_find_channel_by_name(SilcIDList id_list, char *name,
@@ -770,6 +822,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcChannelEntry channel;
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcChannelEntry channel;
+  char *name;
 
   if (!old_id || !new_id)
     return NULL;
 
   if (!old_id || !new_id)
     return NULL;
@@ -781,6 +834,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
     return NULL;
 
   channel = (SilcChannelEntry)id_cache->context;
     return NULL;
 
   channel = (SilcChannelEntry)id_cache->context;
+  name = strdup(id_cache->name);
 
   /* Remove the old entry and add a new one */
 
 
   /* Remove the old entry and add a new one */
 
@@ -789,8 +843,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
   silc_free(channel->id);
   channel->id = new_id;
 
   silc_free(channel->id);
   channel->id = new_id;
 
-  silc_idcache_add(id_list->channels, channel->channel_name, channel->id,
-                  channel, 0, NULL);
+  silc_idcache_add(id_list->channels, name, channel->id, channel, 0, NULL);
 
   SILC_LOG_DEBUG(("Replaced"));
 
 
   SILC_LOG_DEBUG(("Replaced"));
 
index dd2b8eb24753e73e354d2294443f7f242a30973c..cff9c43c161f1dc219339e142bd48e2fbc6c99ba 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2003 Pekka Riikonen
+  Copyright (C) 1997 - 2005 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -244,7 +244,10 @@ typedef struct SilcChannelClientEntryStruct {
 
    unsigned char *nickname
 
 
    unsigned char *nickname
 
-       The nickname of the client.
+       The nickname of the client.  This is nickname in original format,
+       not casefolded or normalized.  However, it is checked to assure
+       that prohibited characters do not exist.  The casefolded version
+       is in the ID Cache.
 
    char *servername
 
 
    char *servername
 
@@ -367,7 +370,7 @@ struct SilcClientEntryStruct {
      reply identifier. */
   SilcUInt16 resolve_cmd_ident;
 
      reply identifier. */
   SilcUInt16 resolve_cmd_ident;
 
-  /* we need this so nobody can resume more than once at the same time - 
+  /* we need this so nobody can resume more than once at the same time -
    * server crashes, really odd behaviour, ... */
   SilcClientEntry resuming_client;
 };
    * server crashes, really odd behaviour, ... */
   SilcClientEntry resuming_client;
 };
@@ -392,7 +395,10 @@ struct SilcClientEntryStruct {
 
    char *channel_name
 
 
    char *channel_name
 
-       Logical name of the channel.
+       Logical name of the channel.  This is the original format, not
+       the casefolded or normalized.  However, this is checked to assure
+       that prohibited characters do not exist.  The casefolded version
+       is in the ID Cache.
 
    SilcUInt32 mode
 
 
    SilcUInt32 mode
 
index 01b072a095b94c2686f5d7d574069696f162904e..4263164293682712d2ba4b43de1591fb5cf1aa84 100644 (file)
@@ -2258,8 +2258,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   SilcUInt16 username_len;
   SilcUInt32 id_len, tmp_len;
   int ret;
   SilcUInt16 username_len;
   SilcUInt32 id_len, tmp_len;
   int ret;
-  char *hostname, *nickname, *tmp;
-  int nickfail = 0;
+  char *hostname, *nickname, *nicknamec;
 
   SILC_LOG_DEBUG(("Creating new client"));
 
 
   SILC_LOG_DEBUG(("Creating new client"));
 
@@ -2328,9 +2327,9 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   }
 
   /* Check for valid username string */
   }
 
   /* Check for valid username string */
-  tmp = silc_identifier_check(username, username_len, SILC_STRING_UTF8, 128,
-                             &tmp_len);
-  if (!tmp) {
+  nicknamec = silc_identifier_check(username, username_len,
+                                   SILC_STRING_UTF8, 128, &tmp_len);
+  if (!nicknamec) {
     silc_free(username);
     silc_free(realname);
     SILC_LOG_ERROR(("Client %s (%s) sent bad username string, closing "
     silc_free(username);
     silc_free(realname);
     SILC_LOG_ERROR(("Client %s (%s) sent bad username string, closing "
@@ -2342,12 +2341,9 @@ SilcClientEntry silc_server_new_client(SilcServer server,
       silc_server_free_sock_user_data(server, sock, NULL);
     return NULL;
   }
       silc_server_free_sock_user_data(server, sock, NULL);
     return NULL;
   }
-  silc_free(username);
-  username = tmp;
-  username_len = tmp_len;
 
   /* Nickname is initially same as username */
 
   /* Nickname is initially same as username */
-  nickname = silc_memdup(username, username_len);
+  nickname = strdup(username);
 
   /* Make sanity checks for the hostname of the client. If the hostname
      is provided in the `username' check that it is the same than the
 
   /* Make sanity checks for the hostname of the client. If the hostname
      is provided in the `username' check that it is the same than the
@@ -2437,18 +2433,14 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   }
 
   /* Create Client ID */
   }
 
   /* Create Client ID */
-  while (!silc_id_create_client_id(server, server->id, server->rng,
-                                  server->md5hash, nickname,
-                                  strlen(nickname), &client_id)) {
-    nickfail++;
-    if (nickfail > 9) {
-      silc_server_disconnect_remote(server, sock,
-                                   SILC_STATUS_ERR_BAD_NICKNAME, NULL);
-      if (sock->user_data)
-       silc_server_free_sock_user_data(server, sock, NULL);
-      return NULL;
-    }
-    snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail);
+  if (!silc_id_create_client_id(server, server->id, server->rng,
+                               server->md5hash, nicknamec,
+                               strlen(nicknamec), &client_id)) {
+    silc_server_disconnect_remote(server, sock,
+                                 SILC_STATUS_ERR_BAD_NICKNAME, NULL);
+    if (sock->user_data)
+      silc_server_free_sock_user_data(server, sock, NULL);
+    return NULL;
   }
 
   /* If client marked as anonymous, scramble the username and hostname */
   }
 
   /* If client marked as anonymous, scramble the username and hostname */
@@ -2479,7 +2471,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
 
   /* Add the client again to the ID cache */
   id_len = silc_id_get_len(client_id, SILC_ID_CLIENT);
 
   /* Add the client again to the ID cache */
-  silc_idcache_add(server->local_list->clients, client->nickname,
+  silc_idcache_add(server->local_list->clients, nicknamec,
                   client_id, client, 0, NULL);
 
   /* Notify our router about new client on the SILC network */
                   client_id, client, 0, NULL);
 
   /* Notify our router about new client on the SILC network */
@@ -2525,7 +2517,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   SilcServerEntry new_server, server_entry;
   SilcServerID *server_id;
   SilcIDListData idata;
   SilcServerEntry new_server, server_entry;
   SilcServerID *server_id;
   SilcIDListData idata;
-  unsigned char *server_name, *id_string;
+  unsigned char *server_name, *server_namec, *id_string;
   SilcUInt16 id_len, name_len;
   int ret;
   bool local = TRUE;
   SilcUInt16 id_len, name_len;
   int ret;
   bool local = TRUE;
@@ -2598,8 +2590,10 @@ SilcServerEntry silc_server_new_server(SilcServer server,
     return NULL;
   }
 
     return NULL;
   }
 
-  if (name_len > 256)
-    server_name[255] = '\0';
+  if (name_len > 256) {
+    server_name[256] = '\0';
+    name_len = 256;
+  }
 
   /* Get Server ID */
   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
 
   /* Get Server ID */
   server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
@@ -2663,6 +2657,20 @@ SilcServerEntry silc_server_new_server(SilcServer server,
     }
   }
 
     }
   }
 
+  /* Check server name */
+  server_namec = silc_identifier_check(server_name, strlen(server_name),
+                                      SILC_STRING_UTF8, 256, NULL);
+  if (!server_namec) {
+    SILC_LOG_ERROR(("Malformed server name from %s (%s)",
+                   sock->ip, sock->hostname));
+    silc_server_disconnect_remote(server, sock,
+                                 SILC_STATUS_ERR_OPERATION_ALLOWED,
+                                 "Malfromed server name");
+    if (sock->user_data)
+      silc_server_free_sock_user_data(server, sock, NULL);
+    return NULL;
+  }
+
   /* Update server entry */
   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
   new_server->server_name = server_name;
   /* Update server entry */
   idata->status |= SILC_IDLIST_STATUS_REGISTERED;
   new_server->server_name = server_name;
@@ -2673,7 +2681,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
 
   /* Add again the entry to the ID cache. */
   silc_idcache_add(local ? server->local_list->servers :
 
   /* Add again the entry to the ID cache. */
   silc_idcache_add(local ? server->local_list->servers :
-                  server->global_list->servers, server_name, server_id,
+                  server->global_list->servers, server_namec, server_id,
                   new_server, 0, NULL);
 
   /* Distribute the information about new server in the SILC network
                   new_server, 0, NULL);
 
   /* Distribute the information about new server in the SILC network
@@ -3053,7 +3061,7 @@ void silc_server_new_channel(SilcServer server,
 {
   SilcChannelPayload payload;
   SilcChannelID *channel_id;
 {
   SilcChannelPayload payload;
   SilcChannelID *channel_id;
-  char *channel_name;
+  char *channel_name, *channel_namec = NULL;
   SilcUInt32 name_len;
   unsigned char *id;
   SilcUInt32 id_len, cipher_len;
   SilcUInt32 name_len;
   unsigned char *id;
   SilcUInt32 id_len, cipher_len;
@@ -3080,8 +3088,16 @@ void silc_server_new_channel(SilcServer server,
   }
 
   channel_name = silc_channel_get_name(payload, &name_len);
   }
 
   channel_name = silc_channel_get_name(payload, &name_len);
-  if (name_len > 256)
-    channel_name[255] = '\0';
+  if (name_len > 256) {
+    channel_name[256] = '\0';
+    name_len = 256;
+  }
+
+  /* Check channel name */
+  channel_namec = silc_identifier_check(channel_name, strlen(channel_name),
+                                       SILC_STRING_UTF8, 256, NULL);
+  if (!channel_namec)
+    return;
 
   id = silc_channel_get_id(payload, &id_len);
 
 
   id = silc_channel_get_id(payload, &id_len);
 
@@ -3093,10 +3109,10 @@ void silc_server_new_channel(SilcServer server,
 
     /* Check that we don't already have this channel */
     channel = silc_idlist_find_channel_by_name(server->local_list,
 
     /* Check that we don't already have this channel */
     channel = silc_idlist_find_channel_by_name(server->local_list,
-                                              channel_name, NULL);
+                                              channel_namec, NULL);
     if (!channel)
       channel = silc_idlist_find_channel_by_name(server->global_list,
     if (!channel)
       channel = silc_idlist_find_channel_by_name(server->global_list,
-                                                channel_name, NULL);
+                                                channel_namec, NULL);
     if (!channel) {
       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
                      silc_id_render(channel_id, SILC_ID_CHANNEL),
     if (!channel) {
       SILC_LOG_DEBUG(("New channel id(%s) from [Router] %s",
                      silc_id_render(channel_id, SILC_ID_CHANNEL),
@@ -3127,10 +3143,10 @@ void silc_server_new_channel(SilcServer server,
 
     /* Check that we don't already have this channel */
     channel = silc_idlist_find_channel_by_name(server->local_list,
 
     /* Check that we don't already have this channel */
     channel = silc_idlist_find_channel_by_name(server->local_list,
-                                              channel_name, NULL);
+                                              channel_namec, NULL);
     if (!channel)
       channel = silc_idlist_find_channel_by_name(server->global_list,
     if (!channel)
       channel = silc_idlist_find_channel_by_name(server->global_list,
-                                                channel_name, NULL);
+                                                channel_namec, NULL);
 
     /* If the channel does not exist, then create it. This creates a new
        key to the channel as well that we will send to the server. */
 
     /* If the channel does not exist, then create it. This creates a new
        key to the channel as well that we will send to the server. */
@@ -3317,6 +3333,7 @@ void silc_server_new_channel(SilcServer server,
                            FALSE, TRUE);
   }
 
                            FALSE, TRUE);
   }
 
+  silc_free(channel_namec);
   silc_channel_payload_free(payload);
 }
 
   silc_channel_payload_free(payload);
 }
 
@@ -3629,9 +3646,9 @@ void silc_server_resume_client(SilcServer server,
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry detached_client;
   SilcClientID *client_id = NULL;
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry detached_client;
   SilcClientID *client_id = NULL;
-  unsigned char *id_string, *auth = NULL;
+  unsigned char *id_string, *auth = NULL, *nicknamec = NULL;
   SilcUInt16 id_len, auth_len = 0;
   SilcUInt16 id_len, auth_len = 0;
-  int ret, nickfail = 0;
+  int ret;
   bool resolved, local, nick_change = FALSE, resolve = FALSE;
   SilcChannelEntry channel;
   SilcHashTableList htl;
   bool resolved, local, nick_change = FALSE, resolve = FALSE;
   SilcChannelEntry channel;
   SilcHashTableList htl;
@@ -3851,35 +3868,32 @@ void silc_server_resume_client(SilcServer server,
       return;
     }
 
       return;
     }
 
+    /* Check nickname */
+    nicknamec = silc_identifier_check(detached_client->nickname,
+                                     strlen(detached_client->nickname),
+                                     SILC_STRING_UTF8, 128, NULL);
+    if (!nicknamec) {
+      silc_server_disconnect_remote(server, sock,
+                                   SILC_STATUS_ERR_BAD_NICKNAME,
+                                   "Malformed nickname, cannot resume");
+      if (sock->user_data)
+       silc_server_free_sock_user_data(server, sock, NULL);
+      return;
+    }
+
     /* If the ID is not based in our ID then change it */
     if (!SILC_ID_COMPARE(detached_client->id, server->id,
                         server->id->ip.data_len)) {
       silc_free(client_id);
     /* If the ID is not based in our ID then change it */
     if (!SILC_ID_COMPARE(detached_client->id, server->id,
                         server->id->ip.data_len)) {
       silc_free(client_id);
-      while (!silc_id_create_client_id(server, server->id, server->rng,
-                                      server->md5hash,
-                                      detached_client->nickname,
-                                      strlen(detached_client->nickname),
-                                      &client_id)) {
-       nickfail++;
-       if (nickfail > 9) {
-         silc_server_disconnect_remote(server, sock,
-                                       SILC_STATUS_ERR_BAD_NICKNAME,
-                                       "Resuming not possible");
-         if (sock->user_data)
-           silc_server_free_sock_user_data(server, sock, NULL);
-         return;
-       }
-       if (nickfail < 2) {
-         detached_client->nickname =
-           silc_realloc(detached_client->nickname,
-                        sizeof(*detached_client->nickname) *
-                        (strlen(detached_client->nickname) + 2));
-         detached_client->
-           nickname[strlen(detached_client->nickname) - 1] = '\0';
-       }
-       snprintf(&detached_client->
-                nickname[strlen(detached_client->nickname) - 2], 1,
-                "%d", nickfail);
+      if (!silc_id_create_client_id(server, server->id, server->rng,
+                                   server->md5hash, nicknamec,
+                                   strlen(nicknamec), &client_id)) {
+       silc_server_disconnect_remote(server, sock,
+                                     SILC_STATUS_ERR_BAD_NICKNAME,
+                                     "Resuming not possible");
+       if (sock->user_data)
+         silc_server_free_sock_user_data(server, sock, NULL);
+       return;
       }
       nick_change = TRUE;
     }
       }
       nick_change = TRUE;
     }
@@ -4013,7 +4027,7 @@ void silc_server_resume_client(SilcServer server,
     silc_free(client->id);
     client->id = client_id;
     client_id = NULL;
     silc_free(client->id);
     client->id = client_id;
     client_id = NULL;
-    silc_idcache_add(server->local_list->clients, client->nickname,
+    silc_idcache_add(server->local_list->clients, nicknamec,
                     client->id, client, 0, NULL);
 
     /* Send some nice info to the client */
                     client->id, client, 0, NULL);
 
     /* Send some nice info to the client */
@@ -4110,6 +4124,17 @@ void silc_server_resume_client(SilcServer server,
       return;
     }
 
       return;
     }
 
+    /* Check nickname */
+    if (detached_client->nickname) {
+      nicknamec = silc_identifier_check(detached_client->nickname,
+                                       strlen(detached_client->nickname),
+                                       SILC_STRING_UTF8, 128, NULL);
+      if (!nicknamec) {
+       silc_free(client_id);
+       return;
+      }
+    }
+
     SILC_LOG_DEBUG(("Resuming detached client"));
 
     /* If the sender of this packet is server and we are router we need to
     SILC_LOG_DEBUG(("Resuming detached client"));
 
     /* If the sender of this packet is server and we are router we need to
@@ -4184,8 +4209,7 @@ void silc_server_resume_client(SilcServer server,
                                  detached_client);
     silc_idcache_add(local && server->server_type == SILC_ROUTER ?
                     server->local_list->clients :
                                  detached_client);
     silc_idcache_add(local && server->server_type == SILC_ROUTER ?
                     server->local_list->clients :
-                    server->global_list->clients,
-                    detached_client->nickname,
+                    server->global_list->clients, nicknamec,
                     detached_client->id, detached_client, FALSE, NULL);
 
     /* Change the owner of the client */
                     detached_client->id, detached_client, FALSE, NULL);
 
     /* Change the owner of the client */
index 7f9dd5d58ba41ce54debeaf4feeef9b6cc53fe29..6111c5f2ff01ffdddeb504cbda8c4fbdbf0d822b 100644 (file)
@@ -342,17 +342,23 @@ bool silc_server_init(SilcServer server)
 
   /* Initialize ID caches */
   server->local_list->clients =
 
   /* Initialize ID caches */
   server->local_list->clients =
-    silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
-  server->local_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
-  server->local_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
+    silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
+                      FALSE, TRUE);
+  server->local_list->servers =
+    silc_idcache_alloc(0, SILC_ID_SERVER, NULL, FALSE, TRUE);
+  server->local_list->channels =
+    silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, FALSE, TRUE);
 
   /* These are allocated for normal server as well as these hold some
      global information that the server has fetched from its router. For
      router these are used as they are supposed to be used on router. */
   server->global_list->clients =
 
   /* These are allocated for normal server as well as these hold some
      global information that the server has fetched from its router. For
      router these are used as they are supposed to be used on router. */
   server->global_list->clients =
-    silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor);
-  server->global_list->servers = silc_idcache_alloc(0, SILC_ID_SERVER, NULL);
-  server->global_list->channels = silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL);
+    silc_idcache_alloc(0, SILC_ID_CLIENT, silc_idlist_client_destructor,
+                      FALSE, TRUE);
+  server->global_list->servers =
+    silc_idcache_alloc(0, SILC_ID_SERVER, NULL, FALSE, TRUE);
+  server->global_list->channels =
+    silc_idcache_alloc(0, SILC_ID_CHANNEL, NULL, FALSE, TRUE);
 
   /* Init watcher lists */
   server->watcher_list =
 
   /* Init watcher lists */
   server->watcher_list =
@@ -427,20 +433,11 @@ bool silc_server_init(SilcServer server)
   if (!id)
     goto err;
 
   if (!id)
     goto err;
 
-  /* Check server name */
-  server->server_name =
-    silc_identifier_check(server->config->server_info->server_name,
-                         strlen(server->config->server_info->server_name),
-                         SILC_STRING_LOCALE, 256, NULL);
-  if (!server->server_name) {
-    SILC_LOG_ERROR(("Malformed server name string '%s'",
-                   server->config->server_info->server_name));
-    goto err;
-  }
-
   server->id = id;
   server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
   server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
   server->id = id;
   server->id_string = silc_id_id2str(id, SILC_ID_SERVER);
   server->id_string_len = silc_id_get_len(id, SILC_ID_SERVER);
+  server->server_name = server->config->server_info->server_name;
+  server->config->server_info->server_name = NULL;
 
   /* Add ourselves to the server list. We don't have a router yet
      beacuse we haven't established a route yet. It will be done later.
 
   /* Add ourselves to the server list. We don't have a router yet
      beacuse we haven't established a route yet. It will be done later.
@@ -613,7 +610,7 @@ bool silc_server_rehash(SilcServer server)
                                     server->id_entry))
       return FALSE;
     if (!silc_idcache_add(server->local_list->servers,
                                     server->id_entry))
       return FALSE;
     if (!silc_idcache_add(server->local_list->servers,
-                         server->id_entry->server_name,
+                         strdup(server->id_entry->server_name),
                          server->id_entry->id, server->id_entry, 0, NULL))
       return FALSE;
   }
                          server->id_entry->id, server->id_entry, 0, NULL))
       return FALSE;
   }
index 48ecd78d56d7b346bf443f953675a39d42ec7f84..7ccdd809da4d79dd84afbdf50e34a7415e841d2e 100644 (file)
@@ -51,10 +51,10 @@ typedef struct {
 /* Query session context */
 typedef struct {
   /* Queried data */
 /* Query session context */
 typedef struct {
   /* Queried data */
-  char *nickname;                  /* Queried nickname */
+  char *nickname;                  /* Queried nickname, normalized */
   char *nick_server;               /* Queried nickname's server */
   char *nick_server;               /* Queried nickname's server */
-  char *server_name;               /* Queried server name */
-  char *channel_name;              /* Queried channel name */
+  char *server_name;               /* Queried server name, normalized */
+  char *channel_name;              /* Queried channel name, normalized */
   SilcServerQueryID ids;           /* Queried IDs */
   SilcUInt32 ids_count;                    /* number of queried IDs */
   SilcUInt32 reply_count;          /* Requested reply count */
   SilcServerQueryID ids;           /* Queried IDs */
   SilcUInt32 ids_count;                    /* number of queried IDs */
   SilcUInt32 reply_count;          /* Requested reply count */
@@ -400,15 +400,18 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query)
       }
 
       /* Check nickname */
       }
 
       /* Check nickname */
-      tmp = silc_identifier_check(query->nickname, strlen(query->nickname),
-                                 SILC_STRING_UTF8, 128, &tmp_len);
-      if (!tmp) {
-       silc_server_query_send_error(server, query,
-                                    SILC_STATUS_ERR_BAD_NICKNAME, 0);
-       silc_server_query_free(query);
+      if (query->nickname) {
+       tmp = silc_identifier_check(query->nickname, strlen(query->nickname),
+                                   SILC_STRING_UTF8, 128, &tmp_len);
+       if (!tmp) {
+         silc_server_query_send_error(server, query,
+                                      SILC_STATUS_ERR_BAD_NICKNAME, 0);
+         silc_server_query_free(query);
+         return;
+       }
+       silc_free(query->nickname);
+       query->nickname = tmp;
       }
       }
-      silc_free(query->nickname);
-      query->nickname = tmp;
 
     } else {
       /* Parse the IDs included in the query */
 
     } else {
       /* Parse the IDs included in the query */
@@ -484,6 +487,7 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query)
       silc_server_query_send_error(server, query,
                                   SILC_STATUS_ERR_BAD_NICKNAME, 0);
       silc_server_query_free(query);
       silc_server_query_send_error(server, query,
                                   SILC_STATUS_ERR_BAD_NICKNAME, 0);
       silc_server_query_free(query);
+      return;
     }
     silc_free(query->nickname);
     query->nickname = tmp;
     }
     silc_free(query->nickname);
     query->nickname = tmp;
@@ -507,17 +511,45 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query)
            !silc_parse_userfqdn(tmp, &query->nickname, &query->nick_server))
          silc_server_query_add_error(server, query, 1, 1,
                                      SILC_STATUS_ERR_BAD_NICKNAME);
            !silc_parse_userfqdn(tmp, &query->nickname, &query->nick_server))
          silc_server_query_add_error(server, query, 1, 1,
                                      SILC_STATUS_ERR_BAD_NICKNAME);
+
+       /* Check nickname */
+       tmp = silc_identifier_check(query->nickname, strlen(query->nickname),
+                                   SILC_STRING_UTF8, 128, &tmp_len);
+       silc_free(query->nickname);
+       if (!tmp) {
+         silc_server_query_add_error(server, query, 1, 1,
+                                     SILC_STATUS_ERR_BAD_NICKNAME);
+         query->nickname = NULL;
+       } else {
+         query->nickname = tmp;
+       }
       }
 
       /* Try get server name */
       tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
       }
 
       /* Try get server name */
       tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
-      if (tmp)
-       query->server_name = silc_memdup(tmp, tmp_len);
+      if (tmp) {
+       /* Check server name */
+       tmp = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8,
+                                   256, &tmp_len);
+       if (!tmp)
+         silc_server_query_add_error(server, query, 1, 1,
+                                     SILC_STATUS_ERR_BAD_SERVER);
+       else
+         query->server_name = tmp;
+      }
 
       /* Get channel name */
       tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
 
       /* Get channel name */
       tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
-      if (tmp && tmp_len <= 256)
-       query->channel_name = silc_memdup(tmp, tmp_len);
+      if (tmp && tmp_len <= 256) {
+       /* Check channel name */
+       tmp = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8,
+                                   256, &tmp_len);
+       if (!tmp)
+         silc_server_query_add_error(server, query, 1, 1,
+                                     SILC_STATUS_ERR_BAD_SERVER);
+       else
+         query->channel_name = tmp;
+      }
 
       if (!query->nickname && !query->server_name && !query->channel_name) {
        silc_server_query_send_error(server, query,
 
       if (!query->nickname && !query->server_name && !query->channel_name) {
        silc_server_query_send_error(server, query,
index a65a2c1938ad77bdfe4a56c31c5715b365999760..b19f495d858664d9661d29637881075beade1e8d 100644 (file)
@@ -1728,8 +1728,13 @@ bool silc_server_check_watcher_list(SilcServer server,
 
   /* Make hash from the nick, or take it from Client ID */
   if (client->nickname) {
 
   /* Make hash from the nick, or take it from Client ID */
   if (client->nickname) {
-    silc_hash_make(server->md5hash, client->nickname,
-                  strlen(client->nickname), hash);
+    unsigned char *nickc;
+    nickc = silc_identifier_check(client->nickname, strlen(client->nickname),
+                                 SILC_STRING_UTF8, 128, NULL);
+    if (!nickc)
+      return FALSE;
+    silc_hash_make(server->md5hash, nickc, strlen(nickc), hash);
+    silc_free(nickc);
   } else {
     memset(hash, 0, sizeof(hash));
     memcpy(hash, client->id->hash, sizeof(client->id->hash));
   } else {
     memset(hash, 0, sizeof(hash));
     memcpy(hash, client->id->hash, sizeof(client->id->hash));
index aa1dee54b32ff51d7a3252b7270302fd79249cf9..3d4ea8e0970aedbde57203aa4ef8ab332ea2e64c 100644 (file)
@@ -67,7 +67,8 @@ bool silc_id_create_client_id(SilcServer server,
 
   *new_id = silc_calloc(1, sizeof(**new_id));
 
 
   *new_id = silc_calloc(1, sizeof(**new_id));
 
-  /* Create hash of the nickanem */
+  /* Create hash of the nickname (it's already checked as valid identifier
+     string). */
   silc_hash_make(md5hash, nickname, nick_len, hash);
 
   /* Create the ID */
   silc_hash_make(md5hash, nickname, nick_len, hash);
 
   /* Create the ID */