Improved UTF-8 encoding and decoding, improved toolkit doc,
[silc.git] / apps / silcd / command.c
index 28c4663405244fb4d450307feeb6bf9852e40070..1a5c7c5faebe1ff6b555adc9cd8f5b3f19209b5e 100644 (file)
@@ -97,15 +97,15 @@ SilcServerCommand silc_command_list[] =
 do {                                                                        \
   SilcUInt32 _argc;                                                         \
                                                                             \
-  SILC_LOG_DEBUG(("Start"));                                                \
-                                                                            \
   if (silc_server_command_pending_error_check(cmd, context2, command)) {     \
+    SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \
     silc_server_command_free(cmd);                                          \
     return;                                                                 \
   }                                                                         \
                                                                             \
   _argc = silc_argument_get_arg_num(cmd->args);                                     \
   if (_argc < min) {                                                        \
+    SILC_LOG_DEBUG(("Not enough parameters in command"));                   \
     silc_server_command_send_status_reply(cmd, command,                             \
                                          SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
                                          0);                                \
@@ -113,6 +113,7 @@ do {                                                                             \
     return;                                                                 \
   }                                                                         \
   if (_argc > max) {                                                        \
+    SILC_LOG_DEBUG(("Too many parameters in command"));                             \
     silc_server_command_send_status_reply(cmd, command,                             \
                                          SILC_STATUS_ERR_TOO_MANY_PARAMS,   \
                                          0);                                \
@@ -157,6 +158,7 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout)
   SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
 
   if (!client) {
+    SILC_LOG_DEBUG(("Client entry is invalid"));
     silc_server_command_free(timeout->ctx);
     silc_free(timeout);
   }
@@ -164,15 +166,21 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout)
   /* Update access time */
   client->last_command = time(NULL);
 
-  if (!(timeout->cmd->flags & SILC_CF_REG))
+  if (!(timeout->cmd->flags & SILC_CF_REG)) {
+    SILC_LOG_DEBUG(("Calling %s command",
+                   silc_get_command_name(timeout->cmd->cmd)));
     timeout->cmd->cb(timeout->ctx, NULL);
-  else if (silc_server_is_registered(timeout->ctx->server, 
-                                    timeout->ctx->sock, 
-                                    timeout->ctx, 
-                                    timeout->cmd->cmd))
+  } else if (silc_server_is_registered(timeout->ctx->server, 
+                                      timeout->ctx->sock, 
+                                      timeout->ctx, 
+                                      timeout->cmd->cmd)) {
+    SILC_LOG_DEBUG(("Calling %s command",
+                   silc_get_command_name(timeout->cmd->cmd)));
     timeout->cmd->cb(timeout->ctx, NULL);
-  else
+  } else {
+    SILC_LOG_DEBUG(("Client is not registered"));
     silc_server_command_free(timeout->ctx);
+  }
 
   silc_free(timeout);
 }
@@ -199,7 +207,6 @@ void silc_server_command_process(SilcServer server,
                                            packet->buffer->len);
   if (!ctx->payload) {
     SILC_LOG_ERROR(("Bad command payload, packet dropped"));
-    silc_buffer_free(packet->buffer);
     silc_packet_context_free(packet);
     silc_socket_free(ctx->sock);
     silc_free(ctx);
@@ -214,6 +221,7 @@ void silc_server_command_process(SilcServer server,
       break;
 
   if (!cmd || !cmd->cb) {
+    SILC_LOG_DEBUG(("Unknown command %d", command));
     silc_server_command_send_status_reply(ctx, command,
                                          SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
     silc_server_command_free(ctx);
@@ -260,12 +268,16 @@ void silc_server_command_process(SilcServer server,
 
   /* Execute for server */
 
-  if (!(cmd->flags & SILC_CF_REG))
+  if (!(cmd->flags & SILC_CF_REG)) {
+    SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
     cmd->cb(ctx, NULL);
-  else if (silc_server_is_registered(server, sock, ctx, cmd->cmd))
+  } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) {
+    SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
     cmd->cb(ctx, NULL);
-  else
+  } else {
+    SILC_LOG_DEBUG(("Server is not registered"));
     silc_server_command_free(ctx);
+  }
 }
 
 /* Allocate Command Context */
@@ -3174,8 +3186,10 @@ static void silc_server_command_join_channel(SilcServer server,
   char check[512], check2[512];
   bool founder = FALSE;
   bool resolve;
+  unsigned char *fkey = NULL;
+  SilcUInt32 fkey_len = 0;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Joining client to channel"));
 
   if (!channel)
     return;
@@ -3217,6 +3231,8 @@ static void silc_server_command_join_channel(SilcServer server,
    */
   if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
     SilcIDListData idata = (SilcIDListData)client;
+    SilcChannelClientEntry chl2;
+    SilcHashTableList htl;
 
     if (channel->founder_key && idata->public_key &&
        silc_pkcs_public_key_compare(channel->founder_key, 
@@ -3225,6 +3241,19 @@ static void silc_server_command_join_channel(SilcServer server,
       if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
                                channel->founder_key, 0, server->sha1hash,
                                client->id, SILC_ID_CLIENT)) {
+
+       /* There cannot be anyone else as founder on the channel now.  This
+          client is definitely the founder due to this authentication */
+       silc_hash_table_list(channel->user_list, &htl);
+       while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+         if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+           chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+           silc_server_force_cumode_change(server, NULL, channel, chl2,
+                                           chl2->mode);
+           break;
+         }
+       silc_hash_table_list_reset(&htl);
+
        umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
        founder = TRUE;
       }
@@ -3370,9 +3399,12 @@ static void silc_server_command_join_channel(SilcServer server,
     silc_free(tmp);
   }
 
+  if (channel->founder_key)
+    fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
+
   reply = 
     silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
-                                        SILC_STATUS_OK, 0, ident, 13,
+                                        SILC_STATUS_OK, 0, ident, 14,
                                         2, channel->channel_name,
                                         strlen(channel->channel_name),
                                         3, chidp->data, chidp->len,
@@ -3396,7 +3428,8 @@ static void silc_server_command_join_channel(SilcServer server,
                                         12, tmp3, 4,
                                         13, user_list->data, user_list->len,
                                         14, mode_list->data, 
-                                        mode_list->len);
+                                        mode_list->len,
+                                        15, fkey, fkey_len);
 
   /* Send command reply */
   silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, 
@@ -3408,11 +3441,19 @@ static void silc_server_command_join_channel(SilcServer server,
      we'll ignore it (in packet_receive.c) so we must send it here. If
      we are router then this will send it to local clients and local
      servers. */
+  SILC_LOG_DEBUG(("Send JOIN notify to channel"));
   silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
                                     SILC_NOTIFY_TYPE_JOIN, 2,
                                     clidp->data, clidp->len,
                                     chidp->data, chidp->len);
 
+  /* Update statistics */
+  server->stat.my_chanclients++;
+  if (server->server_type == SILC_ROUTER) {
+    server->stat.cell_chanclients++;
+    server->stat.chanclients++;
+  }
+
   if (!cmd->pending) {
     /* Send JOIN notify packet to our primary router */
     if (!server->standalone)
@@ -3429,30 +3470,30 @@ static void silc_server_command_join_channel(SilcServer server,
        notify the mode change to the channel. */
     if (founder) {
       SILC_PUT32_MSB(chl->mode, mode);
-      tmp = silc_pkcs_public_key_encode(channel->founder_key, &tmp_len);
+      SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
       silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
                                         SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
                                         clidp->data, clidp->len,
                                         mode, 4, clidp->data, clidp->len,
-                                        tmp, tmp_len);
-      silc_free(tmp);
-      
-      /* Set CUMODE notify type to network */
-      if (!server->standalone)
-       silc_server_send_notify_cumode(server, server->router->connection,
-                                      server->server_type == SILC_ROUTER ? 
-                                      TRUE : FALSE, channel,
-                                      chl->mode, client->id, SILC_ID_CLIENT,
-                                      client->id, channel->founder_key);
+                                        fkey, fkey_len);
     }
   }
 
+  /* Set CUMODE notify type to network */
+  if (founder && !server->standalone)
+    silc_server_send_notify_cumode(server, server->router->connection,
+                                  server->server_type == SILC_ROUTER ?
+                                  TRUE : FALSE, channel,
+                                  chl->mode, client->id, SILC_ID_CLIENT,
+                                  client->id, channel->founder_key);
+
   silc_buffer_free(reply);
   silc_buffer_free(clidp);
   silc_buffer_free(chidp);
   silc_buffer_free(keyp);
   silc_buffer_free(user_list);
   silc_buffer_free(mode_list);
+  silc_free(fkey);
 
  out:
   silc_free(passphrase);
@@ -3521,6 +3562,7 @@ SILC_SERVER_CMD_FUNC(join)
 
   if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
     SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
+    silc_free(client_id);
     client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
 
     if (!channel || 
@@ -3537,6 +3579,7 @@ SILC_SERVER_CMD_FUNC(join)
                                         cmd, SILC_COMMAND_JOIN,
                                         SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
                                         0);
+         silc_free(client_id);
          goto out;
        }
        
@@ -3557,8 +3600,10 @@ SILC_SERVER_CMD_FUNC(join)
          /* If this is pending command callback then we've resolved
             it and it didn't work, return since we've notified the
             client already in the command reply callback. */
-         if (cmd->pending)
+         if (cmd->pending) {
+           silc_free(client_id);
            goto out;
+         }
          
          old_ident = silc_command_get_ident(cmd->payload);
          silc_command_set_ident(cmd->payload, ++server->cmd_ident);
@@ -3578,6 +3623,7 @@ SILC_SERVER_CMD_FUNC(join)
          cmd->pending = TRUE;
           silc_command_set_ident(cmd->payload, old_ident);
          silc_buffer_free(tmpbuf);
+         silc_free(client_id);
          goto out;
        }
        
@@ -3593,6 +3639,7 @@ SILC_SERVER_CMD_FUNC(join)
            silc_server_command_send_status_reply(
                                       cmd, SILC_COMMAND_JOIN,
                                       SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
+           silc_free(client_id);
            goto out;
          }
 
@@ -3610,8 +3657,10 @@ SILC_SERVER_CMD_FUNC(join)
         something went wrong with the joining as the channel was not found.
         We can't do anything else but ignore this. */
       if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
-         server->server_type != SILC_ROUTER)
+         server->server_type != SILC_ROUTER) {
+       silc_free(client_id);
        goto out;
+      }
       
       /* We are router and the channel does not seem exist so we will check
         our global list as well for the channel. */
@@ -3625,6 +3674,7 @@ SILC_SERVER_CMD_FUNC(join)
          silc_server_command_send_status_reply(
                                       cmd, SILC_COMMAND_JOIN,
                                       SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
+         silc_free(client_id);
          goto out;
        }
 
@@ -3644,10 +3694,22 @@ SILC_SERVER_CMD_FUNC(join)
       SILC_GET32_MSB(created, tmp);
       if (silc_argument_get_arg_type(reply->args, 7, NULL))
        create_key = FALSE;     /* Router returned the key already */
+
+      if (silc_command_get_status(reply->payload, NULL, NULL) &&
+         channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
+       /* Save channel passphrase, if user provided it successfully */
+       unsigned char *pa;
+       SilcUInt32 pa_len;
+       pa = silc_argument_get_arg_type(reply->args, 3, &pa_len);
+       if (pa) {
+         silc_free(channel->passphrase);
+         channel->passphrase = silc_memdup(pa, pa_len);
+       }
+      }
     }
 
     if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
-       !silc_hash_table_count(channel->user_list))
+       !channel->disabled && !silc_hash_table_count(channel->user_list))
       created = TRUE;
   }
 
@@ -3698,7 +3760,8 @@ SILC_SERVER_CMD_FUNC(motd)
     if (server->config && server->config->server_info &&
        server->config->server_info->motd_file) {
       /* Send motd */
-      motd = silc_file_readfile(server->config->server_info->motd_file, &motd_len);
+      motd = silc_file_readfile(server->config->server_info->motd_file,
+                               &motd_len);
       if (!motd)
        goto out;
       
@@ -3853,6 +3916,15 @@ SILC_SERVER_CMD_FUNC(umode)
       }
     }
 
+    /* Update statistics */
+    if (mask & SILC_UMODE_GONE) {
+      if (!(client->mode & SILC_UMODE_GONE))
+       server->stat.my_aways++;
+    } else {
+      if (client->mode & SILC_UMODE_GONE)
+       server->stat.my_aways--;
+    }
+
     /* Change the mode */
     client->mode = mask;
 
@@ -4406,6 +4478,8 @@ SILC_SERVER_CMD_FUNC(cumode)
       /* The client tries to claim the founder rights. */
       unsigned char *tmp_auth;
       SilcUInt32 tmp_auth_len;
+      SilcChannelClientEntry chl2;
+      SilcHashTableList htl;
 
       if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
          !channel->founder_key || !idata->public_key ||
@@ -4432,7 +4506,6 @@ SILC_SERVER_CMD_FUNC(cumode)
        goto out;
       }
 
-      sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
       notify = TRUE;
       founder_key = channel->founder_key;
       fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
@@ -4441,6 +4514,20 @@ SILC_SERVER_CMD_FUNC(cumode)
                                              SILC_STATUS_ERR_AUTH_FAILED, 0);
        goto out;
       }
+
+      /* There cannot be anyone else as founder on the channel now.  This
+        client is definitely the founder due to this authentication */
+      silc_hash_table_list(channel->user_list, &htl);
+      while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+       if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+         chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+         silc_server_force_cumode_change(server, NULL, channel, chl2,
+                                         chl2->mode);
+         break;
+       }
+      silc_hash_table_list_reset(&htl);
+
+      sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
     }
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
@@ -4459,12 +4546,12 @@ SILC_SERVER_CMD_FUNC(cumode)
   if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
     /* Promote to operator */
     if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
-      if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
-         !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                             SILC_STATUS_ERR_NO_CHANNEL_PRIV,
-                                             0);
-       goto out;
+      if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) && 
+          !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+        silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                              SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+                                              0);
+        goto out;
       }
 
       chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
@@ -4473,13 +4560,13 @@ SILC_SERVER_CMD_FUNC(cumode)
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
       if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
-         !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                             SILC_STATUS_ERR_NO_CHANNEL_PRIV,
-                                             0);
-       goto out;
+          !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+        silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,   
+                                              SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+                                              0);
+        goto out;
       }
-
+      
       /* Demote to normal user */
       chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
       notify = TRUE;
@@ -4558,6 +4645,28 @@ SILC_SERVER_CMD_FUNC(cumode)
     }
   }
 
+  if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
+    if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
+      if (client == target_client) {
+       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                             SILC_STATUS_ERR_PERM_DENIED, 0);
+       goto out;
+      }
+      chl->mode |= SILC_CHANNEL_UMODE_QUIET;
+      notify = TRUE;
+    }
+  } else {
+    if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
+      if (client == target_client) {
+       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                             SILC_STATUS_ERR_PERM_DENIED, 0);
+       goto out;
+      }
+      chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
+      notify = TRUE;
+    }
+  }
+
   idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
   tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
 
@@ -4870,13 +4979,17 @@ SILC_TASK_CALLBACK(silc_server_command_detach_cb)
 SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
 {
   QuitInternal q = (QuitInternal)context;
-  SilcClientEntry client = (SilcClientEntry)q->sock;
+  SilcClientID *client_id = (SilcClientID *)q->sock;
+  SilcClientEntry client;
 
-  SILC_LOG_DEBUG(("Start"));
+  client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
+                                        FALSE, NULL);
 
-  if (client->mode & SILC_UMODE_DETACHED)
+  if (client && client->mode & SILC_UMODE_DETACHED)
     silc_server_free_client_data(q->server, NULL, client, TRUE,
                                 "Detach timeout");
+
+  silc_free(client_id);
   silc_free(q);
 }
 
@@ -4892,8 +5005,7 @@ SILC_SERVER_CMD_FUNC(detach)
 
   if (server->config->detach_disabled) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
-                                         SILC_STATUS_ERR_UNKNOWN_COMMAND,
-                                         0);
+                                         SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
     goto out;
   }
 
@@ -4911,6 +5023,7 @@ SILC_SERVER_CMD_FUNC(detach)
     silc_server_send_notify_umode(server, server->router->connection,
                                  server->server_type == SILC_SERVER ?
                                  FALSE : TRUE, client->id, client->mode);
+  server->stat.my_detached++;
 
   /* Check if anyone is watching this nickname */
   if (server->server_type == SILC_ROUTER)
@@ -4926,7 +5039,7 @@ SILC_SERVER_CMD_FUNC(detach)
   if (server->config->detach_timeout) {
     q = silc_calloc(1, sizeof(*q));
     q->server = server;
-    q->sock = (void *)client;
+    q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
     silc_schedule_task_add(server->schedule, 0, 
                           silc_server_command_detach_timeout,
                           q, server->config->detach_timeout * 60,
@@ -5098,6 +5211,17 @@ SILC_SERVER_CMD_FUNC(watch)
       silc_free(tmp);
   }
 
+  /* Distribute the watch list to backup routers too */
+  if (server->backup) {
+    SilcBuffer tmpbuf;
+    silc_command_set_ident(cmd->payload, ++server->cmd_ident);
+    tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+    silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
+                           cmd->packet->flags, tmpbuf->data, tmpbuf->len,
+                           FALSE, TRUE);
+    silc_buffer_free(tmpbuf);
+  }
+
   silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
                                        SILC_STATUS_OK, 0);
 
@@ -5467,7 +5591,8 @@ SILC_SERVER_CMD_FUNC(users)
     channel = silc_idlist_find_channel_by_name(server->local_list, 
                                               channel_name, NULL);
 
-  if (!channel || channel->disabled || !channel->users_resolved) {
+  if (!channel || (!server->standalone && (channel->disabled || 
+                   !channel->users_resolved))) {
     if (server->server_type != SILC_ROUTER && !server->standalone &&
        !cmd->pending) {
       SilcBuffer tmpbuf;
@@ -5520,8 +5645,12 @@ SILC_SERVER_CMD_FUNC(users)
   }
 
   /* Get the users list */
-  silc_server_get_users_on_channel(server, channel, &client_id_list,
-                                  &client_mode_list, &list_count);
+  if (!silc_server_get_users_on_channel(server, channel, &client_id_list,
+                                       &client_mode_list, &list_count)) {
+    list_count = 0;
+    client_id_list = NULL;
+    client_mode_list = NULL;
+  }
 
   /* List count */
   SILC_PUT32_MSB(list_count, lc);
@@ -5532,17 +5661,23 @@ SILC_SERVER_CMD_FUNC(users)
                                                SILC_STATUS_OK, 0, ident, 4,
                                                2, idp->data, idp->len,
                                                3, lc, 4,
-                                               4, client_id_list->data,
-                                               client_id_list->len,
-                                               5, client_mode_list->data,
-                                               client_mode_list->len);
+                                               4, client_id_list ? 
+                                               client_id_list->data : NULL,
+                                               client_id_list ?
+                                               client_id_list->len : 0,
+                                               5, client_mode_list ?
+                                               client_mode_list->data : NULL,
+                                               client_mode_list ?
+                                               client_mode_list->len : 0);
   silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
                          packet->data, packet->len, FALSE);
     
   silc_buffer_free(idp);
   silc_buffer_free(packet);
-  silc_buffer_free(client_id_list);
-  silc_buffer_free(client_mode_list);
+  if (client_id_list)
+    silc_buffer_free(client_id_list);
+  if (client_mode_list)
+    silc_buffer_free(client_mode_list);
   silc_free(id);
 
  out:
@@ -5569,8 +5704,6 @@ SILC_SERVER_CMD_FUNC(getkey)
   SilcIdType id_type;
   SilcPublicKey public_key;
 
-  SILC_LOG_DEBUG(("Start"));
-
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
   if (!tmp) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,