Merged from silc_1_0_branch (second merge).
[silc.git] / apps / silcd / command.c
index e5f6d0a40410a72789ba8abd4374d567ddbf0055..f5fcb1b4846bf6d5dc3e1bcb6741268decb8ace7 100644 (file)
@@ -160,6 +160,7 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout)
     SILC_LOG_DEBUG(("Client entry is invalid"));
     silc_server_command_free(timeout->ctx);
     silc_free(timeout);
+    return;
   }
 
   /* Update access time */
@@ -239,6 +240,7 @@ void silc_server_command_process(SilcServer server,
     if (!client) {
       SILC_LOG_DEBUG(("Client entry is invalid"));
       silc_server_command_free(ctx);
+      return;
     }
 
     timeout = silc_calloc(1, sizeof(*timeout));
@@ -1106,8 +1108,6 @@ SILC_SERVER_CMD_FUNC(invite)
                                  silc_server_command_invite, 
                                  silc_server_command_dup(cmd));
       cmd->pending = TRUE;
-      silc_free(channel_id);
-      silc_free(dest_id);
       goto out;
     }
 
@@ -1133,9 +1133,10 @@ SILC_SERVER_CMD_FUNC(invite)
 
     /* Allocate hash table for invite list if it doesn't exist yet */
     if (!channel->invite_list)
-      channel->invite_list = silc_hash_table_alloc(0, silc_hash_ptr,
-                                                  NULL, NULL, NULL,
-                                                  NULL, NULL, TRUE);
+      channel->invite_list =
+       silc_hash_table_alloc(0, silc_hash_ptr,
+                             NULL, NULL, NULL,
+                             silc_server_inviteban_destruct, channel, TRUE);
 
     /* Check if the ID is in the list already */
     silc_hash_table_list(channel->invite_list, &htl);
@@ -1190,9 +1191,11 @@ SILC_SERVER_CMD_FUNC(invite)
       if (tmp[0] == 0x00) {
        /* Allocate hash table for invite list if it doesn't exist yet */
        if (!channel->invite_list)
-         channel->invite_list = silc_hash_table_alloc(0, silc_hash_ptr,
-                                                      NULL, NULL, NULL,
-                                                      NULL, NULL, TRUE);
+         channel->invite_list =
+           silc_hash_table_alloc(0, silc_hash_ptr,
+                                 NULL, NULL, NULL,
+                                 silc_server_inviteban_destruct, channel,
+                                 TRUE);
     
        /* Check for resource limit */
        if (silc_hash_table_count(channel->invite_list) > 64) {
@@ -1219,14 +1222,9 @@ SILC_SERVER_CMD_FUNC(invite)
                                          channel->invite_list)),
                       SILC_STR_END);
     silc_hash_table_list(channel->invite_list, &htl);
-    while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
-      if (type == 1)
-       list = silc_argument_payload_encode_one(list, (char *)tmp2,
-                                               strlen((char *)tmp2), type);
-      else
-       list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
-                                               type);
-    }
+    while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2))
+      list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
+                                             type);
     silc_hash_table_list_reset(&htl);
   }
 
@@ -1237,13 +1235,23 @@ SILC_SERVER_CMD_FUNC(invite)
                         silc_argument_get_arg_type(cmd->args, 3, NULL),
                         list);
 
+  /* Send invite list back only if the list was modified, or now arguments
+     was given. */
+  type = 0;
+  argc = silc_argument_get_arg_num(cmd->args);
+  if (argc == 1)
+    type = 1;
+  if (silc_argument_get_arg_type(cmd->args, 3, &len))
+    type = 1;
+
   /* Send command reply */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE,
                                                SILC_STATUS_OK, 0, ident, 2,
                                                2, tmp, len,
-                                               3, list ? list->data : NULL,
-                                               list ? list->len : 0);
+                                               3, type && list ? 
+                                               list->data : NULL,
+                                               type && list ? list->len : 0);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
   silc_buffer_free(packet);
@@ -1421,6 +1429,8 @@ SILC_SERVER_CMD_FUNC(kill)
 
     /* Do normal signoff for the destination client */
     sock = remote_client->connection;
+    silc_server_remove_from_channels(server, NULL, remote_client,
+                                    TRUE, (char *)"Killed", TRUE, TRUE);
     silc_server_free_client_data(server, NULL, remote_client, TRUE,
                                 comment ? comment :
                                 (unsigned char *)"Killed");
@@ -1922,10 +1932,10 @@ static void silc_server_command_join_channel(SilcServer server,
                                      3, client->id) ||
          silc_server_inviteban_match(server, channel->ban_list,
                                      2, client->data.public_key) ||
-         !silc_server_inviteban_match(server, channel->ban_list,
-                                      1, check) ||
-         !silc_server_inviteban_match(server, channel->ban_list,
-                                      1, check2)) {
+         silc_server_inviteban_match(server, channel->ban_list,
+                                     1, check) ||
+         silc_server_inviteban_match(server, channel->ban_list,
+                                     1, check2)) {
        silc_server_command_send_status_reply(
                                      cmd, SILC_COMMAND_JOIN,
                                      SILC_STATUS_ERR_BANNED_FROM_CHANNEL, 0);
@@ -2035,17 +2045,10 @@ static void silc_server_command_join_channel(SilcServer server,
                       SILC_STR_END);
 
     silc_hash_table_list(channel->invite_list, &htl);
-    while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) {
-      if (tmp_len == 1)
-       invite_list = silc_argument_payload_encode_one(invite_list,
-                                                      (char *)reply,
-                                                      strlen((char *)reply),
-                                                      tmp_len);
-      else
-       invite_list = silc_argument_payload_encode_one(invite_list,
-                                                      reply->data,
-                                                      reply->len, tmp_len);
-    }
+    while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply))
+      invite_list = silc_argument_payload_encode_one(invite_list,
+                                                    reply->data,
+                                                    reply->len, tmp_len);
     silc_hash_table_list_reset(&htl);
   }
 
@@ -2061,17 +2064,10 @@ static void silc_server_command_join_channel(SilcServer server,
                       SILC_STR_END);
 
     silc_hash_table_list(channel->ban_list, &htl);
-    while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) {
-      if (tmp_len == 1)
-       ban_list = silc_argument_payload_encode_one(ban_list,
-                                                   (char *)reply,
-                                                   strlen((char *)reply),
-                                                   tmp_len);
-      else
-       ban_list = silc_argument_payload_encode_one(ban_list,
-                                                   reply->data,
-                                                   reply->len, tmp_len);
-    }
+    while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply))
+      ban_list = silc_argument_payload_encode_one(ban_list,
+                                                 reply->data,
+                                                 reply->len, tmp_len);
     silc_hash_table_list_reset(&htl);
   }
 
@@ -2169,6 +2165,8 @@ static void silc_server_command_join_channel(SilcServer server,
   silc_buffer_free(ban_list);
 
  out:
+  if (passphrase)
+    memset(passphrase, 0, strlen(passphrase));
   silc_free(passphrase);
 }
 
@@ -2924,7 +2922,6 @@ SILC_SERVER_CMD_FUNC(cmode)
       hmac = channel->hmac_name;
 
       /* Delete old hmac and allocate default one */
-      silc_hmac_free(channel->hmac);
       if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) {
        silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
                                       SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
@@ -2957,6 +2954,11 @@ SILC_SERVER_CMD_FUNC(cmode)
                                                0);
          goto out;
        }
+      } else {
+       /* If key was not sent and the channel mode has already founder
+          then the key was not to be changed. */
+       if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
+         goto has_founder;
       }
 
       /* Set the founder authentication */
@@ -3001,6 +3003,7 @@ SILC_SERVER_CMD_FUNC(cmode)
        channel->founder_key = NULL;
        goto out;
       }
+    has_founder:
     }
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
@@ -3061,7 +3064,6 @@ SILC_SERVER_CMD_FUNC(cumode)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
-  SilcIDListData idata = (SilcIDListData)client;
   SilcChannelID *channel_id = NULL;
   SilcClientID *client_id = NULL;
   SilcChannelEntry channel;
@@ -3193,9 +3195,7 @@ SILC_SERVER_CMD_FUNC(cumode)
       SilcHashTableList htl;
 
       if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
-         !channel->founder_key || !idata->public_key ||
-         !silc_pkcs_public_key_compare(channel->founder_key, 
-                                       idata->public_key)) {
+         !channel->founder_key) {
        silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
                                              SILC_STATUS_ERR_AUTH_FAILED, 0);
        goto out;
@@ -4165,9 +4165,11 @@ SILC_SERVER_CMD_FUNC(ban)
       if (tmp[0] == 0x00) {
        /* Allocate hash table for ban list if it doesn't exist yet */
        if (!channel->ban_list)
-         channel->ban_list = silc_hash_table_alloc(0, silc_hash_ptr,
-                                                   NULL, NULL, NULL,
-                                                   NULL, NULL, TRUE);
+         channel->ban_list =
+           silc_hash_table_alloc(0, silc_hash_ptr,
+                                 NULL, NULL, NULL,
+                                 silc_server_inviteban_destruct, channel,
+                                 TRUE);
     
        /* Check for resource limit */
        if (silc_hash_table_count(channel->ban_list) > 64) {
@@ -4194,14 +4196,9 @@ SILC_SERVER_CMD_FUNC(ban)
                                          channel->ban_list)),
                       SILC_STR_END);
     silc_hash_table_list(channel->ban_list, &htl);
-    while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) {
-      if (type == 1)
-       list = silc_argument_payload_encode_one(list, (char *)tmp2,
-                                               strlen((char *)tmp2), type);
-      else
-       list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
-                                               type);
-    }
+    while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2))
+      list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len,
+                                             type);
     silc_hash_table_list_reset(&htl);
   }
 
@@ -4750,17 +4747,19 @@ SILC_SERVER_CMD_FUNC(close)
   /* Close the connection to the server */
   sock = (SilcSocketConnection)server_entry->connection;
 
-  /* If we shutdown primary router connection manually then don't trigger
-     any reconnect or backup router connections, by setting the router
-     to NULL here. */
+  server->backup_noswitch = TRUE;
   if (server->router == server_entry) {
     server->id_entry->router = NULL;
     server->router = NULL;
     server->standalone = TRUE;
   }
-  silc_server_free_sock_user_data(server, sock, NULL);
-  silc_server_close_connection(server, sock);
-  
+  silc_server_disconnect_remote(server, sock,
+                               SILC_STATUS_ERR_BANNED_FROM_SERVER,
+                               "Closed by administrator");
+  if (sock->user_data)
+    silc_server_free_sock_user_data(server, sock, NULL);
+  server->backup_noswitch = FALSE;
+
  out:
   silc_server_command_free(cmd);
 }