Code auditing weekend results and fixes committing.
[silc.git] / apps / silcd / packet_receive.c
index a5c2493012bb6476f403860d20a85fdf4a4d40c2..df24e8351162d229081ce6006376b4a3b00c52f0 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 1997 - 2000 Pekka Riikonen
+  Copyright (C) 1997 - 2001 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
@@ -49,7 +49,7 @@ void silc_server_private_message(SilcServer server,
     goto err;
 
   /* Decode destination Client ID */
     goto err;
 
   /* Decode destination Client ID */
-  id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
+  id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
   if (!id) {
     SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
     goto err;
   if (!id) {
     SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
     goto err;
@@ -152,7 +152,9 @@ void silc_server_command_reply(SilcServer server,
 
   if (packet->dst_id_type == SILC_ID_CLIENT) {
     /* Destination must be one of ours */
 
   if (packet->dst_id_type == SILC_ID_CLIENT) {
     /* Destination must be one of ours */
-    id = silc_id_str2id(packet->dst_id, SILC_ID_CLIENT);
+    id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CLIENT);
+    if (!id)
+      return;
     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
     if (!client) {
       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
     client = silc_idlist_find_client_by_id(server->local_list, id, NULL);
     if (!client) {
       SILC_LOG_ERROR(("Cannot process command reply to unknown client"));
@@ -216,7 +218,9 @@ void silc_server_channel_message(SilcServer server,
   }
 
   /* Find channel entry */
   }
 
   /* Find channel entry */
-  id = silc_id_str2id(packet->dst_id, SILC_ID_CHANNEL);
+  id = silc_id_str2id(packet->dst_id, packet->dst_id_len, SILC_ID_CHANNEL);
+  if (!id)
+    goto out;
   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
   if (!channel) {
     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
   if (!channel) {
     channel = silc_idlist_find_channel_by_id(server->global_list, id, NULL);
@@ -230,7 +234,10 @@ void silc_server_channel_message(SilcServer server,
      from router we won't do the check as the message is from client that
      we don't know about. Also, if the original sender is not client
      (as it can be server as well) we don't do the check. */
      from router we won't do the check as the message is from client that
      we don't know about. Also, if the original sender is not client
      (as it can be server as well) we don't do the check. */
-  sender = silc_id_str2id(packet->src_id, packet->src_id_type);
+  sender = silc_id_str2id(packet->src_id, packet->src_id_len, 
+                         packet->src_id_type);
+  if (!sender)
+    goto out;
   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
       packet->src_id_type == SILC_ID_CLIENT) {
     silc_list_start(channel->user_list);
   if (sock->type != SILC_SOCKET_TYPE_ROUTER && 
       packet->src_id_type == SILC_ID_CLIENT) {
     silc_list_start(channel->user_list);
@@ -291,6 +298,7 @@ void silc_server_replace_id(SilcServer server,
   SilcIdType old_id_type, new_id_type;
   unsigned short old_id_len, new_id_len;
   void *id = NULL, *id2 = NULL;
   SilcIdType old_id_type, new_id_type;
   unsigned short old_id_len, new_id_len;
   void *id = NULL, *id2 = NULL;
+  int ret;
 
   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
       packet->src_id_type == SILC_ID_CLIENT)
 
   if (sock->type == SILC_SOCKET_TYPE_CLIENT ||
       packet->src_id_type == SILC_ID_CLIENT)
@@ -298,12 +306,14 @@ void silc_server_replace_id(SilcServer server,
 
   SILC_LOG_DEBUG(("Replacing ID"));
 
 
   SILC_LOG_DEBUG(("Replacing ID"));
 
-  silc_buffer_unformat(buffer,
-                      SILC_STR_UI_SHORT(&old_id_type),
-                      SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
-                      SILC_STR_UI_SHORT(&new_id_type),
-                      SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
-                      SILC_STR_END);
+  ret = silc_buffer_unformat(buffer,
+                            SILC_STR_UI_SHORT(&old_id_type),
+                            SILC_STR_UI16_NSTRING_ALLOC(&old_id, &old_id_len),
+                            SILC_STR_UI_SHORT(&new_id_type),
+                            SILC_STR_UI16_NSTRING_ALLOC(&new_id, &new_id_len),
+                            SILC_STR_END);
+  if (ret == -1)
+    goto out;
 
   if (old_id_type != new_id_type)
     goto out;
 
   if (old_id_type != new_id_type)
     goto out;
@@ -312,11 +322,11 @@ void silc_server_replace_id(SilcServer server,
       new_id_len != silc_id_get_len(new_id_type))
     goto out;
 
       new_id_len != silc_id_get_len(new_id_type))
     goto out;
 
-  id = silc_id_str2id(old_id, old_id_type);
+  id = silc_id_str2id(old_id, old_id_len, old_id_type);
   if (!id)
     goto out;
 
   if (!id)
     goto out;
 
-  id2 = silc_id_str2id(new_id, new_id_type);
+  id2 = silc_id_str2id(new_id, new_id_len, new_id_type);
   if (!id2)
     goto out;
 
   if (!id2)
     goto out;
 
@@ -412,6 +422,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   SilcBuffer reply;
   SilcIDListData idata;
   char *username = NULL, *realname = NULL, *id_string;
   SilcBuffer reply;
   SilcIDListData idata;
   char *username = NULL, *realname = NULL, *id_string;
+  int ret;
 
   SILC_LOG_DEBUG(("Creating new client"));
 
 
   SILC_LOG_DEBUG(("Creating new client"));
 
@@ -430,10 +441,17 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   }
 
   /* Parse incoming packet */
   }
 
   /* Parse incoming packet */
-  silc_buffer_unformat(buffer,
-                      SILC_STR_UI16_STRING_ALLOC(&username),
-                      SILC_STR_UI16_STRING_ALLOC(&realname),
-                      SILC_STR_END);
+  ret = silc_buffer_unformat(buffer,
+                            SILC_STR_UI16_STRING_ALLOC(&username),
+                            SILC_STR_UI16_STRING_ALLOC(&realname),
+                            SILC_STR_END);
+  if (ret == -1) {
+    if (username)
+      silc_free(username);
+    if (realname)
+      silc_free(realname);
+    return NULL;
+  }
 
   /* Create Client ID */
   silc_id_create_client_id(server->id, server->rng, server->md5hash,
 
   /* Create Client ID */
   silc_id_create_client_id(server->id, server->rng, server->md5hash,
@@ -545,6 +563,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   SilcIDListData idata;
   unsigned char *server_name, *id_string;
   unsigned short id_len;
   SilcIDListData idata;
   unsigned char *server_name, *id_string;
   unsigned short id_len;
+  int ret;
 
   SILC_LOG_DEBUG(("Creating new server"));
 
 
   SILC_LOG_DEBUG(("Creating new server"));
 
@@ -564,10 +583,17 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   }
 
   /* Parse the incoming packet */
   }
 
   /* Parse the incoming packet */
-  silc_buffer_unformat(buffer,
-                      SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
-                      SILC_STR_UI16_STRING_ALLOC(&server_name),
-                      SILC_STR_END);
+  ret = silc_buffer_unformat(buffer,
+                            SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len),
+                            SILC_STR_UI16_STRING_ALLOC(&server_name),
+                            SILC_STR_END);
+  if (ret == -1) {
+    if (id_string)
+      silc_free(id_string);
+    if (server_name)
+      silc_free(server_name);
+    return NULL;
+  }
 
   if (id_len > buffer->len) {
     silc_free(id_string);
 
   if (id_len > buffer->len) {
     silc_free(id_string);
@@ -576,7 +602,12 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   }
 
   /* Get Server ID */
   }
 
   /* Get Server ID */
-  server_id = silc_id_str2id(id_string, SILC_ID_SERVER);
+  server_id = silc_id_str2id(id_string, id_len, SILC_ID_SERVER);
+  if (!server_id) {
+    silc_free(id_string);
+    silc_free(server_name);
+    return NULL;
+  }
   silc_free(id_string);
 
   /* Update client entry */
   silc_free(id_string);
 
   /* Update client entry */
@@ -751,10 +782,12 @@ void silc_server_remove_channel_user(SilcServer server,
 {
   SilcBuffer buffer = packet->buffer;
   unsigned char *tmp1 = NULL, *tmp2 = NULL;
 {
   SilcBuffer buffer = packet->buffer;
   unsigned char *tmp1 = NULL, *tmp2 = NULL;
+  unsigned int tmp1_len, tmp2_len;
   SilcClientID *client_id = NULL;
   SilcChannelID *channel_id = NULL;
   SilcChannelEntry channel;
   SilcClientEntry client;
   SilcClientID *client_id = NULL;
   SilcChannelID *channel_id = NULL;
   SilcChannelEntry channel;
   SilcClientEntry client;
+  int ret;
 
   SILC_LOG_DEBUG(("Removing user from channel"));
 
 
   SILC_LOG_DEBUG(("Removing user from channel"));
 
@@ -762,16 +795,15 @@ void silc_server_remove_channel_user(SilcServer server,
       server->server_type == SILC_SERVER)
     return;
 
       server->server_type == SILC_SERVER)
     return;
 
-  silc_buffer_unformat(buffer,
-                      SILC_STR_UI16_STRING_ALLOC(&tmp1),
-                      SILC_STR_UI16_STRING_ALLOC(&tmp2),
-                      SILC_STR_END);
-
-  if (!tmp1 || !tmp2)
+  ret = silc_buffer_unformat(buffer,
+                            SILC_STR_UI16_NSTRING_ALLOC(&tmp1, &tmp1_len),
+                            SILC_STR_UI16_NSTRING_ALLOC(&tmp2, &tmp2_len),
+                            SILC_STR_END);
+  if (ret == -1)
     goto out;
 
     goto out;
 
-  client_id = silc_id_str2id(tmp1, SILC_ID_CLIENT);
-  channel_id = silc_id_str2id(tmp2, SILC_ID_CHANNEL);
+  client_id = silc_id_str2id(tmp1, tmp1_len, SILC_ID_CLIENT);
+  channel_id = silc_id_str2id(tmp2, tmp2_len, SILC_ID_CHANNEL);
   if (!client_id || !channel_id)
     goto out;
 
   if (!client_id || !channel_id)
     goto out;
 
@@ -833,6 +865,7 @@ void silc_server_new_channel(SilcServer server,
   SilcChannelID *channel_id;
   unsigned short channel_id_len;
   char *channel_name;
   SilcChannelID *channel_id;
   unsigned short channel_id_len;
   char *channel_name;
+  int ret;
 
   SILC_LOG_DEBUG(("Processing New Channel"));
 
 
   SILC_LOG_DEBUG(("Processing New Channel"));
 
@@ -842,17 +875,20 @@ void silc_server_new_channel(SilcServer server,
     return;
 
   /* Parse payload */
     return;
 
   /* Parse payload */
-  if (!silc_buffer_unformat(packet->buffer, 
-                           SILC_STR_UI16_STRING_ALLOC(&channel_name),
-                           SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
-                           SILC_STR_END))
+  ret = silc_buffer_unformat(packet->buffer, 
+                            SILC_STR_UI16_STRING_ALLOC(&channel_name),
+                            SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
+                            SILC_STR_END);
+  if (ret == -1) {
+    if (channel_name)
+      silc_free(channel_name);
+    if (id)
+      silc_free(id);
     return;
     return;
+  }
     
     
-  if (!channel_name || !id)
-    return;
-
   /* Decode the channel ID */
   /* Decode the channel ID */
-  channel_id = silc_id_str2id(id, SILC_ID_CHANNEL);
+  channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
   if (!channel_id)
     return;
   silc_free(id);
   if (!channel_id)
     return;
   silc_free(id);
@@ -916,7 +952,8 @@ void silc_server_notify(SilcServer server,
      */
     SILC_LOG_DEBUG(("JOIN notify"));
 
      */
     SILC_LOG_DEBUG(("JOIN notify"));
 
-    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
+    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+                               packet->dst_id_type);
     if (!channel_id)
       goto out;
 
     if (!channel_id)
       goto out;
 
@@ -935,6 +972,10 @@ void silc_server_notify(SilcServer server,
       goto out;
     }
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
       goto out;
     }
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!client_id) {
+      silc_free(channel_id);
+      goto out;
+    }
 
     /* Send to channel */
     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
 
     /* Send to channel */
     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
@@ -951,9 +992,15 @@ void silc_server_notify(SilcServer server,
 
       client = silc_idlist_find_client_by_id(server->global_list, 
                                             client_id, NULL);
 
       client = silc_idlist_find_client_by_id(server->global_list, 
                                             client_id, NULL);
-      if (!client)
+      if (!client) {
        client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
                                        client_id, sock->user_data, sock);
        client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
                                        client_id, sock->user_data, sock);
+       if (!client) {
+         silc_free(channel_id);
+         silc_free(client_id);
+         goto out;
+       }
+      }
 
       /* The channel is global now */
       channel->global_users = TRUE;
 
       /* The channel is global now */
       channel->global_users = TRUE;
@@ -975,7 +1022,8 @@ void silc_server_notify(SilcServer server,
      */
     SILC_LOG_DEBUG(("LEAVE notify"));
 
      */
     SILC_LOG_DEBUG(("LEAVE notify"));
 
-    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_type);
+    channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len,
+                               packet->dst_id_type);
     if (!channel_id)
       goto out;
 
     if (!channel_id)
       goto out;
 
@@ -994,6 +1042,10 @@ void silc_server_notify(SilcServer server,
       goto out;
     }
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
       goto out;
     }
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!client_id) {
+      silc_free(channel_id);
+      goto out;
+    }
 
     /* Send to channel */
     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
 
     /* Send to channel */
     silc_server_packet_send_to_channel(server, NULL, channel, packet->type, 
@@ -1007,6 +1059,7 @@ void silc_server_notify(SilcServer server,
       client = silc_idlist_find_client_by_id(server->local_list, 
                                             client_id, NULL);
       if (!client) {
       client = silc_idlist_find_client_by_id(server->local_list, 
                                             client_id, NULL);
       if (!client) {
+       silc_free(client_id);
        silc_free(channel_id);
        goto out;
       }
        silc_free(channel_id);
        goto out;
       }
@@ -1028,6 +1081,8 @@ void silc_server_notify(SilcServer server,
     if (!tmp)
       goto out;
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
     if (!tmp)
       goto out;
     client_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!client_id)
+      goto out;
 
     /* Get client entry */
     client = silc_idlist_find_client_by_id(server->global_list, 
 
     /* Get client entry */
     client = silc_idlist_find_client_by_id(server->global_list, 
@@ -1063,12 +1118,16 @@ void silc_server_notify(SilcServer server,
       if (!id)
        goto out;
       client_id = silc_id_payload_parse_id(id, tmp_len);
       if (!id)
        goto out;
       client_id = silc_id_payload_parse_id(id, tmp_len);
+      if (!client_id)
+       goto out;
       
       /* Get new client ID */
       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
       if (!id2)
        goto out;
       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
       
       /* Get new client ID */
       id2 = silc_argument_get_arg_type(args, 2, &tmp_len);
       if (!id2)
        goto out;
       client_id2 = silc_id_payload_parse_id(id2, tmp_len);
+      if (!client_id2)
+       goto out;
       
       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
                      silc_id_render(client_id, SILC_ID_CLIENT)));
       
       SILC_LOG_DEBUG(("Old Client ID id(%s)", 
                      silc_id_render(client_id, SILC_ID_CLIENT)));
@@ -1147,6 +1206,7 @@ void silc_server_new_channel_user(SilcServer server,
   SilcChannelEntry channel;
   SilcChannelClientEntry chl;
   SilcBuffer clidp;
   SilcChannelEntry channel;
   SilcChannelClientEntry chl;
   SilcBuffer clidp;
+  int ret;
 
   SILC_LOG_DEBUG(("Start"));
 
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -1156,24 +1216,27 @@ void silc_server_new_channel_user(SilcServer server,
     return;
 
   /* Parse payload */
     return;
 
   /* Parse payload */
-  if (!silc_buffer_unformat(packet->buffer, 
-                           SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
-                                                       &channel_id_len),
-                           SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
-                                                       &client_id_len),
-                           SILC_STR_END))
-    return;
-
-  if (!tmpid1 || !tmpid2)
+  ret = silc_buffer_unformat(packet->buffer, 
+                            SILC_STR_UI16_NSTRING_ALLOC(&tmpid1, 
+                                                        &channel_id_len),
+                            SILC_STR_UI16_NSTRING_ALLOC(&tmpid2, 
+                                                        &client_id_len),
+                            SILC_STR_END);
+  if (ret == -1) {
+    if (tmpid1)
+      silc_free(tmpid1);
+    if (tmpid2)
+      silc_free(tmpid2);
     return;
     return;
+  }
 
   /* Decode the channel ID */
 
   /* Decode the channel ID */
-  channel_id = silc_id_str2id(tmpid1, SILC_ID_CHANNEL);
+  channel_id = silc_id_str2id(tmpid1, channel_id_len, SILC_ID_CHANNEL);
   if (!channel_id)
     goto out;
 
   /* Decode the client ID */
   if (!channel_id)
     goto out;
 
   /* Decode the client ID */
-  client_id = silc_id_str2id(tmpid2, SILC_ID_CLIENT);
+  client_id = silc_id_str2id(tmpid2, client_id_len, SILC_ID_CLIENT);
   if (!client_id)
     goto out;
 
   if (!client_id)
     goto out;