updates.
[silc.git] / apps / silcd / command.c
index 44ef1f94153b85498253684ae4bc7add3d0ed08a..6f34122867a862bef6bb1a4e820339003e6dd4c4 100644 (file)
@@ -4,7 +4,7 @@
 
   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
@@ -351,17 +351,29 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd,
 
     *client_id = silc_calloc(1, sizeof(**client_id));
     (*client_id)[0] = silc_id_payload_parse_id(tmp, len);
+    if ((*client_id)[0] == NULL) {
+      silc_free(*client_id);
+      return FALSE;
+    }
     *client_id_count = 1;
 
     /* Take all ID's from the command packet */
     if (argc > 3) {
-      for (k = 1, i = 4; i < argc; i++) {
+      for (k = 1, i = 4; i < argc + 1; i++) {
        tmp = silc_argument_get_arg_type(cmd->args, i, &len);
        if (tmp) {
          *client_id = silc_realloc(*client_id, sizeof(**client_id) *
                                    (*client_id_count + 1));
-         (*client_id)[k++] = silc_id_payload_parse_id(tmp, len);
+         (*client_id)[k] = silc_id_payload_parse_id(tmp, len);
+         if ((*client_id)[k] == NULL) {
+           /* Cleanup all and fail */
+           for (i = 0; i < *client_id_count; i++)
+             silc_free((*client_id)[i]);
+           silc_free(*client_id);
+           return FALSE;
+         }
          (*client_id_count)++;
+         k++;
        }
       }
     }
@@ -391,7 +403,7 @@ silc_server_command_whois_check(SilcServerCommandContext cmd,
   for (i = 0; i < clients_count; i++) {
     entry = clients[i];
 
-    if (!entry->nickname || !entry->username || !entry->userinfo) {
+    if (!entry->nickname || !entry->username) {
       SilcBuffer tmpbuf;
       unsigned short old_ident;
 
@@ -452,6 +464,11 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
     if (clients_count > 1 && i == clients_count - 1)
       status = SILC_STATUS_LIST_END;
 
+    /* Sanity check, however these should never fail. However, as
+       this sanity check has been added here they have failed. */
+    if (!entry->nickname || !entry->username)
+      continue;
+      
     /* Send WHOIS reply */
     idp = silc_id_payload_encode(entry->id, SILC_ID_CLIENT);
     tmp = silc_argument_get_first_arg(cmd->args, NULL);
@@ -464,7 +481,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
 
       memset(uh, 0, sizeof(uh));
       memset(nh, 0, sizeof(nh));
-      
+
       strncat(nh, entry->nickname, strlen(entry->nickname));
       if (!strchr(entry->nickname, '@')) {
        strncat(nh, "@", 1);
@@ -624,8 +641,7 @@ silc_server_command_whois_from_client(SilcServerCommandContext cmd)
      mandatory fields that WHOIS command reply requires. Check for these and
      make query from the server who owns the client if some fields are 
      missing. */
-  if (server->server_type == SILC_ROUTER &&
-      !silc_server_command_whois_check(cmd, clients, clients_count)) {
+  if (!silc_server_command_whois_check(cmd, clients, clients_count)) {
     ret = -1;
     goto out;
   }
@@ -735,8 +751,7 @@ silc_server_command_whois_from_server(SilcServerCommandContext cmd)
      mandatory fields that WHOIS command reply requires. Check for these and
      make query from the server who owns the client if some fields are 
      missing. */
-  if (server->server_type == SILC_ROUTER &&
-      !silc_server_command_whois_check(cmd, clients, clients_count)) {
+  if (!silc_server_command_whois_check(cmd, clients, clients_count)) {
     ret = -1;
     goto out;
   }
@@ -1029,7 +1044,7 @@ silc_server_command_identify_from_client(SilcServerCommandContext cmd)
 
   /* Check that all mandatory fields are present and request those data
      from the server who owns the client if necessary. */
-  if (!cmd->pending && server->server_type == SILC_ROUTER &&
+  if (!cmd->pending && 
       !silc_server_command_identify_check(cmd, clients, clients_count)) {
     ret = -1;
     goto out;
@@ -1137,7 +1152,7 @@ silc_server_command_identify_from_server(SilcServerCommandContext cmd)
 
   /* Check that all mandatory fields are present and request those data
      from the server who owns the client if necessary. */
-  if (!cmd->pending && server->server_type == SILC_ROUTER &&
+  if (!cmd->pending && 
       !silc_server_command_identify_check(cmd, clients, clients_count)) {
     ret = -1;
     goto out;
@@ -1309,6 +1324,11 @@ SILC_SERVER_CMD_FUNC(topic)
     goto out;
   }
   channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+  if (!channel_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_TOPIC,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* Check whether the channel exists */
   channel = silc_idlist_find_channel_by_id(server->local_list, 
@@ -1411,6 +1431,11 @@ SILC_SERVER_CMD_FUNC(invite)
     goto out;
   }
   dest_id = silc_id_payload_parse_id(tmp, len);
+  if (!dest_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+                                         SILC_STATUS_ERR_NO_CLIENT_ID);
+    goto out;
+  }
 
   /* Get Channel ID */
   tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
@@ -1420,6 +1445,11 @@ SILC_SERVER_CMD_FUNC(invite)
     goto out;
   }
   channel_id = silc_id_payload_parse_id(tmp, len);
+  if (!channel_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* Check whether the channel exists */
   channel = silc_idlist_find_channel_by_id(server->local_list, 
@@ -1610,7 +1640,7 @@ SILC_SERVER_CMD_FUNC(ping)
                                          SILC_STATUS_ERR_NO_SERVER_ID);
     goto out;
   }
-  id = silc_id_str2id(tmp, SILC_ID_SERVER);
+  id = silc_id_str2id(tmp, len, SILC_ID_SERVER);
   if (!id)
     goto out;
 
@@ -1660,6 +1690,13 @@ void silc_server_command_send_users(SilcServer server,
 
   cmd = silc_calloc(1, sizeof(*cmd));
   cmd->payload = silc_command_payload_parse(buffer);
+  if (!cmd->payload) {
+    silc_free(cmd);
+    silc_buffer_free(buffer);
+    silc_buffer_free(idp);
+    silc_packet_context_free(packet);
+    return;
+  }
   cmd->args = silc_command_get_args(cmd->payload);
   cmd->server = server;
   cmd->sock = sock;
@@ -1674,16 +1711,16 @@ void silc_server_command_send_users(SilcServer server,
     silc_server_command_pending(server, SILC_COMMAND_USERS, 0,
                                silc_server_command_users, (void *)cmd);
     cmd->pending = TRUE;
-    silc_free(buffer);
-    silc_free(idp);
+    silc_buffer_free(buffer);
+    silc_buffer_free(idp);
     return;
   }
 
   /* Process USERS command. */
   silc_server_command_users((void *)cmd);
  
-  silc_free(buffer);
-  silc_free(idp);
+  silc_buffer_free(buffer);
+  silc_buffer_free(idp);
   silc_packet_context_free(packet);
 }
 
@@ -1916,8 +1953,11 @@ SILC_SERVER_CMD_FUNC(join)
     goto out;
   }
   client_id = silc_id_payload_parse_id(tmp, tmp_len);
-  if (!client_id)
+  if (!client_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
     goto out;
+  }
 
   /* Get cipher name */
   cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
@@ -2165,6 +2205,11 @@ SILC_SERVER_CMD_FUNC(cmode)
     goto out;
   }
   channel_id = silc_id_payload_parse_id(tmp_id, tmp_len2);
+  if (!channel_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* Get the channel mode mask */
   tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
@@ -2519,6 +2564,11 @@ SILC_SERVER_CMD_FUNC(cumode)
     goto out;
   }
   channel_id = silc_id_payload_parse_id(tmp_id, tmp_len);
+  if (!channel_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* Get channel entry */
   channel = silc_idlist_find_channel_by_id(server->local_list, 
@@ -2569,6 +2619,11 @@ SILC_SERVER_CMD_FUNC(cumode)
     goto out;
   }
   client_id = silc_id_payload_parse_id(tmp_id, tmp_len);
+  if (!client_id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* Get target client's entry */
   target_client = silc_idlist_find_client_by_id(server->local_list, 
@@ -2707,6 +2762,11 @@ SILC_SERVER_CMD_FUNC(leave)
     goto out;
   }
   id = silc_id_payload_parse_id(tmp, len);
+  if (!id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* Get channel entry */
   channel = silc_idlist_find_channel_by_id(server->local_list, id, NULL);
@@ -2759,7 +2819,7 @@ SILC_SERVER_CMD_FUNC(leave)
       silc_server_packet_send(server, 
                              cmd->server->router->connection,
                              SILC_PACKET_CHANNEL_KEY, 0, packet->data,
-                             packet->len, TRUE);
+                             packet->len, FALSE);
   } else {
 
   }
@@ -2807,6 +2867,11 @@ SILC_SERVER_CMD_FUNC(users)
     goto out;
   }
   id = silc_id_payload_parse_id(channel_id, channel_id_len);
+  if (!id) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_USERS,
+                                         SILC_STATUS_ERR_NO_CHANNEL_ID);
+    goto out;
+  }
 
   /* If we are server and we don't know about this channel we will send
      the command to our router. If we know about the channel then we also