updates.
[silc.git] / apps / silcd / command.c
index c72a18c970d2d4d533610a281991f3bb605a6bec..779c0385f6cee58c88eccd6ac2083a4defdbf02d 100644 (file)
@@ -541,25 +541,15 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
       
       SILC_PUT32_MSB((time(NULL) - entry->data.last_receive), idle);
       
-      /* XXX */
-      if (entry->userinfo)
-       packet = 
-         silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
-                                              status, ident, 5, 
-                                              2, idp->data, idp->len,
-                                              3, nh, strlen(nh),
-                                              4, uh, strlen(uh),
-                                              5, entry->userinfo, 
-                                              strlen(entry->userinfo),
-                                              7, idle, 4);
-      else
-       packet = 
-         silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
-                                              status, ident, 4, 
-                                              2, idp->data, idp->len,
-                                              3, nh, strlen(nh),
-                                              4, uh, strlen(uh),
-                                              7, idle, 4);
+      packet = 
+       silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
+                                            status, ident, 5, 
+                                            2, idp->data, idp->len,
+                                            3, nh, strlen(nh),
+                                            4, uh, strlen(uh),
+                                            5, entry->userinfo, 
+                                            strlen(entry->userinfo),
+                                            7, idle, 4);
     }
     
     silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
@@ -1893,14 +1883,15 @@ static void silc_server_command_join_channel(SilcServer server,
   }
 
   /* Generate new channel key as protocol dictates */
-  if (!created || !channel->channel_key)
+  if ((!created && silc_list_count(channel->user_list) > 0) || 
+      !channel->channel_key)
     silc_server_create_channel_key(server, channel, 0);
 
   /* Send the channel key. This is broadcasted to the channel but is not
      sent to the client who is joining to the channel. */
   silc_server_send_channel_key(server, NULL, channel, 
                               server->server_type == SILC_ROUTER ? 
-                              FALSE : server->standalone);
+                              FALSE : !server->standalone);
 
   /* Join the client to the channel by adding it to channel's user list.
      Add also the channel to client entry's channels list for fast cross-
@@ -1921,7 +1912,8 @@ static void silc_server_command_join_channel(SilcServer server,
   SILC_PUT32_MSB(created, tmp2);
   tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
   keyp = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, tmp, 
-                                        SILC_ID_CHANNEL_LEN,
+                                        strlen(channel->channel_key->
+                                               cipher->name),
                                         channel->channel_key->cipher->name,
                                         channel->key_len / 8, channel->key);
   silc_free(tmp);
@@ -1945,7 +1937,7 @@ static void silc_server_command_join_channel(SilcServer server,
                                           4, mode, 4,
                                           5, tmp2, 4,
                                           6, keyp->data, keyp->len,
-                                          8, channel->topic, 
+                                          9, channel->topic, 
                                           strlen(channel->topic));
   }
 
@@ -1990,7 +1982,7 @@ SILC_SERVER_CMD_FUNC(join)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   int tmp_len;
-  char *tmp, *channel_name = NULL, *cipher = NULL;
+  char *tmp, *channel_name = NULL, *cipher, *hmac;
   SilcChannelEntry channel;
   unsigned int umode = 0;
   int created = FALSE;
@@ -2028,8 +2020,9 @@ SILC_SERVER_CMD_FUNC(join)
     goto out;
   }
 
-  /* Get cipher name */
+  /* Get cipher and hmac name */
   cipher = silc_argument_get_arg_type(cmd->args, 4, NULL);
+  hmac = silc_argument_get_arg_type(cmd->args, 5, NULL);
 
   /* See if the channel exists */
   channel = silc_idlist_find_channel_by_name(server->local_list, 
@@ -2054,7 +2047,7 @@ SILC_SERVER_CMD_FUNC(join)
         the channel by ourselves. */
       if (server->standalone) {
        channel = silc_server_create_new_channel(server, server->id, cipher, 
-                                                channel_name, TRUE);
+                                                hmac, channel_name, TRUE);
        umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
        created = TRUE;
 
@@ -2095,7 +2088,7 @@ SILC_SERVER_CMD_FUNC(join)
        if (!channel) {
          /* Channel really does not exist, create it */
          channel = silc_server_create_new_channel(server, server->id, cipher, 
-                                                  channel_name, TRUE);
+                                                  hmac, channel_name, TRUE);
          umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
          created = TRUE;
        }
@@ -2119,7 +2112,7 @@ SILC_SERVER_CMD_FUNC(join)
       if (!channel) {
        /* Channel really does not exist, create it */
        channel = silc_server_create_new_channel(server, server->id, cipher, 
-                                                channel_name, TRUE);
+                                                hmac, channel_name, TRUE);
        umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
        created = TRUE;
       }
@@ -2472,32 +2465,26 @@ SILC_SERVER_CMD_FUNC(cmode)
   if (mode_mask & SILC_CHANNEL_MODE_CIPHER) {
     if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) {
       /* Cipher to use protect the traffic */
-      unsigned int key_len = 128;
-      char *cp;
+      unsigned int key_len;
 
       /* Get cipher */
       tmp = silc_argument_get_arg_type(cmd->args, 8, NULL);
       if (!tmp) {
        silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
-                                             SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+                                  SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
        goto out;
       }
 
-      cp = strchr(tmp, ':');
-      if (cp) {
-       key_len = atoi(cp);
-       *cp = '\0';
-      }
-
       /* XXX Duplicated code, make own function for this!! */
     
       /* Delete old cipher and allocate the new one */
       silc_cipher_free(channel->channel_key);
-      silc_cipher_alloc(tmp, &channel->channel_key);
-
-      key_len /= 8;
-      if (key_len > 32)
-       key_len = 32;
+      if (!silc_cipher_alloc(tmp, &channel->channel_key)) {
+       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+                                      SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+       goto out;
+      }
+      key_len = silc_cipher_get_key_len(channel->channel_key) / 8;
 
       /* Re-generate channel key */
       silc_server_create_channel_key(server, channel, key_len);
@@ -2547,9 +2534,14 @@ SILC_SERVER_CMD_FUNC(cmode)
       /* Delete old cipher and allocate default one */
       silc_cipher_free(channel->channel_key);
       if (!channel->cipher)
-       silc_cipher_alloc("twofish", &channel->channel_key);
-      else
-       silc_cipher_alloc(channel->cipher, &channel->channel_key);
+       silc_cipher_alloc("aes-256-cbc", &channel->channel_key);
+      else {
+       if (!silc_cipher_alloc(channel->cipher, &channel->channel_key)) {
+         silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+                                 SILC_STATUS_ERR_UNKNOWN_ALGORITHM);
+         goto out;
+       }
+      }
 
       /* Re-generate channel key */
       silc_server_create_channel_key(server, channel, 0);
@@ -2952,7 +2944,7 @@ SILC_SERVER_CMD_FUNC(kick)
      to the client who joined the channel. */
   silc_server_send_channel_key(server, target_client->connection, channel, 
                               server->server_type == SILC_ROUTER ? 
-                              FALSE : server->standalone);
+                              FALSE : !server->standalone);
 
  out:
   silc_server_command_free(cmd);
@@ -2976,20 +2968,23 @@ SILC_SERVER_CMD_FUNC(connect)
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   unsigned char *tmp;
   unsigned int tmp_len;
-  unsigned int port;
+  unsigned int port = SILC_PORT;
+
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CONNECT, cmd, 1, 2);
 
-  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CONNECT, cmd, 0, 0);
+  if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
+    goto out;
 
   /* Check whether client has the permissions. */
   if (client->mode == SILC_UMODE_NONE) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
                                          SILC_STATUS_ERR_NO_SERVER_PRIV);
     goto out;
   }
 
   if (server->server_type == SILC_ROUTER && 
       client->mode & SILC_UMODE_SERVER_OPERATOR) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
                                          SILC_STATUS_ERR_NO_ROUTER_PRIV);
     goto out;
   }
@@ -2997,7 +2992,7 @@ SILC_SERVER_CMD_FUNC(connect)
   /* Get the remote server */
   tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
   if (!tmp) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
                                          SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
     goto out;
   }
@@ -3011,7 +3006,7 @@ SILC_SERVER_CMD_FUNC(connect)
   silc_server_create_connection(server, tmp, port);
 
   /* Send reply to the sender */
-  silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+  silc_server_command_send_status_reply(cmd, SILC_COMMAND_CONNECT,
                                        SILC_STATUS_OK);
 
  out:
@@ -3029,12 +3024,16 @@ SILC_SERVER_CMD_FUNC(close)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
-  SilcServerID *server_id;
   SilcServerEntry server_entry;
   unsigned char *tmp;
   unsigned int tmp_len;
+  unsigned char *name;
+  unsigned int port = SILC_PORT;
 
-  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 0, 0);
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 1, 2);
+
+  if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
+    goto out;
 
   /* Check whether client has the permissions. */
   if (client->mode == SILC_UMODE_NONE) {
@@ -3043,25 +3042,21 @@ SILC_SERVER_CMD_FUNC(close)
     goto out;
   }
 
-  /* Get the server ID */
-  tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
-  if (!tmp) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
-                                         SILC_STATUS_ERR_NO_SERVER_ID);
-    goto out;
-  }
-  server_id = silc_id_payload_parse_id(tmp, tmp_len);
-  if (!server_id) {
+  /* Get the remote server */
+  name = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+  if (!name) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
-                                         SILC_STATUS_ERR_NO_SERVER_ID);
+                                         SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
     goto out;
   }
 
-  /* Check that the server ID is valid and that I have an active
-     connection to it. Check only local list as it holds the local
-     connections. */
-  server_entry = silc_idlist_find_server_by_id(server->local_list,
-                                              server_id, NULL);
+  /* Get port */
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+  if (tmp)
+    SILC_GET32_MSB(port, tmp);
+
+  server_entry = silc_idlist_find_server_by_conn(server->local_list,
+                                                name, port, NULL);
   if (!server_entry) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
                                          SILC_STATUS_ERR_NO_SERVER_ID);
@@ -3075,7 +3070,7 @@ SILC_SERVER_CMD_FUNC(close)
                                "Closed by operator");
   
   /* Send reply to the sender */
-  silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+  silc_server_command_send_status_reply(cmd, SILC_COMMAND_CLOSE,
                                        SILC_STATUS_OK);
 
  out:
@@ -3093,6 +3088,9 @@ SILC_SERVER_CMD_FUNC(shutdown)
 
   SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_SHUTDOWN, cmd, 0, 0);
 
+  if (!client || cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
+    goto out;
+
   /* Check whether client has the permission. */
   if (client->mode == SILC_UMODE_NONE) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_SHUTDOWN,
@@ -3104,7 +3102,7 @@ SILC_SERVER_CMD_FUNC(shutdown)
   silc_server_stop(server);
 
   /* Send reply to the sender */
-  silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
+  silc_server_command_send_status_reply(cmd, SILC_COMMAND_SHUTDOWN,
                                        SILC_STATUS_OK);
 
  out: