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;
-  unsigned char *nick = NULL;
+  unsigned char *nick, *nickc = NULL;
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
-  int nickfail = 0;
 
   if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT || !client)
     goto out;
@@ -649,46 +648,31 @@ SILC_SERVER_CMD_FUNC(nick)
     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_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);
-    silc_free(nick);
-    nick = client->nickname;
+    silc_free(nickc);
     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
@@ -715,7 +699,7 @@ SILC_SERVER_CMD_FUNC(nick)
   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);
@@ -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) {
-    /* 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) {
@@ -1615,7 +1599,7 @@ SILC_SERVER_CMD_FUNC(info)
   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];
 
@@ -1693,11 +1677,15 @@ SILC_SERVER_CMD_FUNC(info)
   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));
+      dest_server = NULL;
+    }
     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;
-  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;
@@ -2364,11 +2352,13 @@ SILC_SERVER_CMD_FUNC(join)
     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;
@@ -2398,7 +2388,7 @@ SILC_SERVER_CMD_FUNC(join)
 
   /* 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;
@@ -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,
-                                                  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,
@@ -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,
-                                                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,
@@ -2708,10 +2698,13 @@ SILC_SERVER_CMD_FUNC(motd)
     }
 
     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));
+      dest_server = NULL;
       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);
-  char *channel_name = NULL;
+  char *channel_name, *channel_namec = NULL;
 
   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) {
-    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;
@@ -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_name, NULL);
+                                              channel_namec, NULL);
 
   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_name, NULL);
+                                                channel_namec, NULL);
     if (!channel) {
       /* Channel really does not exist */
       if (id)
@@ -4894,7 +4887,7 @@ SILC_SERVER_CMD_FUNC(users)
   silc_free(id);
 
  out:
-  silc_free(channel_name);
+  silc_free(channel_namec);
   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);
 
-  /* 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,
@@ -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 (server->server_type != SILC_SERVER) {
-      silc_free(username);
+    if (server->server_type != SILC_SERVER)
       return FALSE;
-    }
 
     /* 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
-       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);
-      silc_free(username);
       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"));
-      silc_free(username);
       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 :
@@ -293,7 +276,7 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
 
     /* 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);
   }
@@ -397,7 +380,6 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     }
   }
 
-  silc_free(username);
   return TRUE;
 }
 
@@ -489,14 +471,6 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
   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,
@@ -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 (server->server_type != SILC_SERVER) {
-      silc_free(username);
+    if (server->server_type != SILC_SERVER)
       return FALSE;
-    }
 
     /* 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. */
@@ -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);
-      silc_free(username);
       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"));
-      silc_free(username);
       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);
@@ -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 :
-                    server->local_list->clients, nick, client->id,
+                    server->local_list->clients, nickname, client->id,
                     client, 0, NULL);
   }
 
@@ -595,7 +560,6 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
   }
 
   silc_free(client_id);
-  silc_free(username);
 
   return TRUE;
 }
@@ -686,25 +650,13 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
        goto error;
 
       /* Take nickname */
-      if (name) {
+      if (name)
        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. */
-      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) {
@@ -712,6 +664,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
        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;
@@ -731,8 +684,6 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
          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 :
@@ -740,6 +691,11 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
 
        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) {
@@ -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;
 
-      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) {
@@ -823,16 +772,24 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
 
     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,
-                                              name, NULL);
+                                              info, NULL);
     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 (server->server_type != SILC_SERVER)
+      if (server->server_type != SILC_SERVER) {
+       silc_free(info);
        goto error;
+      }
 
       /* 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);
+       silc_free(info);
        goto error;
       }
+      silc_free(info);
       channel_id = NULL;
     }
 
@@ -900,7 +859,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
   SilcServerEntry entry;
   SilcServerID *server_id;
   SilcUInt32 tmp_len;
-  unsigned char *tmp, *name = NULL;
+  unsigned char *tmp, *name;
 
   COMMAND_CHECK_STATUS;
 
@@ -917,12 +876,6 @@ SILC_SERVER_CMD_REPLY_FUNC(info)
   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) {
@@ -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);
-      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);
-       silc_free(name);
        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;
 
-  silc_free(name);
-
  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;
-  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;
@@ -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. */
+  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,
-                                          channel_name, &cache);
+                                          channel_namec, &cache);
   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,
-                                            channel_name, &cache);
+                                            channel_namec, &cache);
     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:
+  silc_free(channel_namec);
   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;
-  unsigned char *tmp, *name, *topic;
+  unsigned char *tmp, *name, *namec = NULL, *topic;
   SilcUInt32 usercount = 0;
   bool global_list = FALSE;
 
@@ -1538,12 +1493,17 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   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,
-                                            name, &cache);
+                                            namec, &cache);
   if (!channel) {
     channel = silc_idlist_find_channel_by_name(server->global_list,
-                                              name, &cache);
+                                              namec, &cache);
     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_free(namec);
   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;
+  char *server_namec = NULL;
 
   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;
@@ -129,9 +138,10 @@ silc_idlist_add_server(SilcIDList id_list,
   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);
+    silc_free(server_namec);
     return NULL;
   }
 
@@ -171,7 +181,7 @@ silc_idlist_find_server_by_id(SilcIDList id_list, SilcServerID *id,
   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,
@@ -259,6 +269,7 @@ silc_idlist_replace_server_id(SilcIDList id_list, SilcServerID *old_id,
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcServerEntry server;
+  char *name;
 
   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;
+  name = strdup(id_cache->name);
 
   /* 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_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"));
 
@@ -337,12 +348,29 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username,
                       int expire)
 {
   SilcClientEntry client;
+  char *nicknamec = NULL, *usernamec = NULL;
 
   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->username = username;
+  client->username = usernamec;
   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);
 
-  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);
+    silc_free(nicknamec);
+    silc_free(usernamec);
     return NULL;
   }
 
@@ -368,7 +398,7 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry 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;
@@ -376,7 +406,6 @@ int silc_idlist_del_client(SilcIDList id_list, SilcClientEntry entry)
 
     assert(!silc_hash_table_count(entry->channels));
 
-    /* Free data */
     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;
 }
 
+/* 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
-   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,
@@ -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
-   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,
@@ -517,12 +571,21 @@ silc_idlist_replace_client_id(SilcServer server,
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client;
+  char *nicknamec = NULL;
 
   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
@@ -548,14 +611,14 @@ silc_idlist_replace_client_id(SilcServer server,
   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);
 
-  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;
 
@@ -564,27 +627,6 @@ silc_idlist_replace_client_id(SilcServer server,
   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;
+  char *channel_namec = NULL;
 
   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;
@@ -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);
 
-  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);
+    silc_free(channel_namec);
     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
-   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,
@@ -770,6 +822,7 @@ silc_idlist_replace_channel_id(SilcIDList id_list, SilcChannelID *old_id,
 {
   SilcIDCacheEntry id_cache = NULL;
   SilcChannelEntry channel;
+  char *name;
 
   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;
+  name = strdup(id_cache->name);
 
   /* 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_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"));
 
index dd2b8eb24753e73e354d2294443f7f242a30973c..cff9c43c161f1dc219339e142bd48e2fbc6c99ba 100644 (file)
@@ -4,7 +4,7 @@
 
   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
@@ -244,7 +244,10 @@ typedef struct SilcChannelClientEntryStruct {
 
    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
 
@@ -367,7 +370,7 @@ struct SilcClientEntryStruct {
      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;
 };
@@ -392,7 +395,10 @@ struct SilcClientEntryStruct {
 
    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
 
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;
-  char *hostname, *nickname, *tmp;
-  int nickfail = 0;
+  char *hostname, *nickname, *nicknamec;
 
   SILC_LOG_DEBUG(("Creating new client"));
 
@@ -2328,9 +2327,9 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   }
 
   /* 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 "
@@ -2342,12 +2341,9 @@ SilcClientEntry silc_server_new_client(SilcServer server,
       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 = 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
@@ -2437,18 +2433,14 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   }
 
   /* 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 */
@@ -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 */
-  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 */
@@ -2525,7 +2517,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   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;
@@ -2598,8 +2590,10 @@ SilcServerEntry silc_server_new_server(SilcServer server,
     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);
@@ -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;
@@ -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 :
-                  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
@@ -3053,7 +3061,7 @@ void silc_server_new_channel(SilcServer server,
 {
   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;
@@ -3080,8 +3088,16 @@ void silc_server_new_channel(SilcServer server,
   }
 
   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);
 
@@ -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,
-                                              channel_name, NULL);
+                                              channel_namec, NULL);
     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),
@@ -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,
-                                              channel_name, NULL);
+                                              channel_namec, NULL);
     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. */
@@ -3317,6 +3333,7 @@ void silc_server_new_channel(SilcServer server,
                            FALSE, TRUE);
   }
 
+  silc_free(channel_namec);
   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;
-  unsigned char *id_string, *auth = NULL;
+  unsigned char *id_string, *auth = NULL, *nicknamec = NULL;
   SilcUInt16 id_len, auth_len = 0;
-  int ret, nickfail = 0;
+  int ret;
   bool resolved, local, nick_change = FALSE, resolve = FALSE;
   SilcChannelEntry channel;
   SilcHashTableList htl;
@@ -3851,35 +3868,32 @@ void silc_server_resume_client(SilcServer server,
       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);
-      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;
     }
@@ -4013,7 +4027,7 @@ void silc_server_resume_client(SilcServer server,
     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 */
@@ -4110,6 +4124,17 @@ void silc_server_resume_client(SilcServer server,
       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
@@ -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 :
-                    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 */
index 7f9dd5d58ba41ce54debeaf4feeef9b6cc53fe29..6111c5f2ff01ffdddeb504cbda8c4fbdbf0d822b 100644 (file)
@@ -342,17 +342,23 @@ bool silc_server_init(SilcServer server)
 
   /* 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 =
-    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 =
@@ -427,20 +433,11 @@ bool silc_server_init(SilcServer server)
   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->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.
@@ -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->server_name,
+                         strdup(server->id_entry->server_name),
                          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 */
-  char *nickname;                  /* Queried nickname */
+  char *nickname;                  /* Queried nickname, normalized */
   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 */
@@ -400,15 +400,18 @@ void silc_server_query_parse(SilcServer server, SilcServerQuery query)
       }
 
       /* 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 */
@@ -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);
+      return;
     }
     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);
+
+       /* 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);
-      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);
-      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,
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) {
-    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));
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));
 
-  /* 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 */