updates.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 25 Mar 2001 13:23:06 +0000 (13:23 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 25 Mar 2001 13:23:06 +0000 (13:23 +0000)
20 files changed:
CHANGES
README
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/command.h
apps/silcd/command_reply.c
apps/silcd/idlist.h
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/testi2.conf
doc/draft-riikonen-silc-spec-01.nroff
lib/silcclient/command.c
lib/silcclient/command.h
lib/silcclient/command_reply.c
lib/silcclient/command_reply.h
lib/silccore/silccommand.c
lib/silccore/silcnotify.c
lib/silcutil/silcutil.c
lib/silcutil/silcutil.h

diff --git a/CHANGES b/CHANGES
index c6c440a78453c4647ab84801c1380d5cc1da2edd..c835fdbefe44d9fd9110f0a8d44d724cbffc52f5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,39 @@
+Sun Mar 25 13:52:51 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Implemented the BAN command to the client library.
+
+       * The JOIN command in the server now checks the invite list
+         and the ban list.
+
+       * Changed the silc_command_reply_payload_encode_va and the
+         silc_command_payload_encode_va to support that if argument is
+         NULL it ignores and checks the next argument.  Affected file
+         lib/silccore/silccommand.c.
+
+       * Added silc_server_send_notify_ban to send the BAN notify
+         type between routers.
+
+       * Chaned the silc_notify_payload_encode to support that if 
+         argument is NULL it ignores and checks the next argument.
+         Affected file lib/silccore/silcnotify.c.
+
+       * Tested ban lists in router environment successfully.
+
+Sat Mar 24 14:47:25 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Implemented BAN command to the server, in silcd/command.[ch].
+
+       * Removed the BAN and INVITE_LIST modes from the CMODE command
+         in the server code.
+
+       * Added function silc_string_match to regex match two strings.
+         Affected files lib/silcutil/silcutil.[ch].
+
+Fri Mar 23 22:02:40 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Redefined parts of the SilcChannelEntry in the server to support
+         the new ban and invite lists.
+
 Fri Mar 23 16:25:11 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Redefined the INVITE command.  The same command can be used to
 Fri Mar 23 16:25:11 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Redefined the INVITE command.  The same command can be used to
diff --git a/README b/README
index ac9e349f63e609888cacb77ff73bffef11620f88..215f04f96d85c82c3441986eb09f7c1fc59cffcf 100644 (file)
--- a/README
+++ b/README
@@ -86,12 +86,7 @@ SILC Commands
                l <limit>       Set/unset channel's user limit
                a <passphrase>  Set/unset passphrase for channel that must
                                be provided when joining to the channel.
                l <limit>       Set/unset channel's user limit
                a <passphrase>  Set/unset passphrase for channel that must
                                be provided when joining to the channel.
-               b <username!nickname@server>    
-                               Add client to/remove client from ban list
-               I <username!nickname@server>    
-                               Add client to/remove client from invite list
-               c <cipher>
-                               Set/unset channel's cipher
+               c <cipher>      Set/unset channel's cipher
 
                Multiple modes can be set/unset at once if the modes does not
                require any arguments.  If mode requires an argument then only
 
                Multiple modes can be set/unset at once if the modes does not
                require any arguments.  If mode requires an argument then only
index 690584b8be44206118dded0b790e8772637b9478..e71e8ac9bc90506aa5777ad1a96b0012a1d7629a 100644 (file)
@@ -712,8 +712,30 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
          silc_screen_print_bottom_line(app->screen, 0);
          break;
        }
          silc_screen_print_bottom_line(app->screen, 0);
          break;
        }
+      }
       break;
       break;
+
+    case SILC_COMMAND_BAN:
+      {
+       SilcChannelEntry channel;
+       char *ban_list;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       ban_list = va_arg(vp, char *);
+
+       if (ban_list)
+         silc_say(client, conn, "%s ban list: %s", channel->channel_name,
+                  ban_list);
+       else
+         silc_say(client, conn, "%s ban list not set", channel->channel_name);
       }
       }
+      break;
+
+    default:
+      break;
     }
 }
 
     }
 }
 
index f92e8a39b30e6a646b2ee114a40dcde7781b8378..7bfbc62d63b79e0ce0195313cd5050b1dafc6053 100644 (file)
@@ -72,6 +72,7 @@ SilcServerCommand silc_command_list[] =
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
   SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG_STRICT | SILC_CF_REG),
   SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
   SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG_STRICT | SILC_CF_REG),
   SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
+  SILC_SERVER_CMD(ban, BAN, SILC_CF_LAG_STRICT | SILC_CF_REG),
 
   { NULL, 0 },
 };
 
   { NULL, 0 },
 };
@@ -2569,43 +2570,73 @@ static void silc_server_command_join_channel(SilcServer server,
   SilcChannelClientEntry chl;
   SilcBuffer reply, chidp, clidp, keyp, user_list, mode_list;
   unsigned short ident = silc_command_get_ident(cmd->payload);
   SilcChannelClientEntry chl;
   SilcBuffer reply, chidp, clidp, keyp, user_list, mode_list;
   unsigned short ident = silc_command_get_ident(cmd->payload);
+  char check[512];
 
   SILC_LOG_DEBUG(("Start"));
 
   if (!channel)
     return;
 
 
   SILC_LOG_DEBUG(("Start"));
 
   if (!channel)
     return;
 
-  /* Get passphrase */
-  tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
-  if (tmp) {
-    passphrase = silc_calloc(tmp_len, sizeof(*passphrase));
-    memcpy(passphrase, tmp, tmp_len);
+  /* Get the client entry */
+  if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
+    client = (SilcClientEntry)sock->user_data;
+  } else {
+    client = silc_idlist_find_client_by_id(server->local_list, client_id, 
+                                          NULL);
+    if (!client)
+      goto out;
   }
   }
-  
+
   /*
    * Check channel modes
    */
 
   /*
    * Check channel modes
    */
 
-  /* Check invite list if channel is invite-only channel */
-  if (channel->mode & SILC_CHANNEL_MODE_INVITE) {
-    if (channel->mode & SILC_CHANNEL_MODE_INVITE_LIST) {
-      /* Invite list is specified. Check whether client is invited in the
-        list. If not, then check whether it has been invited otherwise. */
-
-    } else {
-      /* XXX client must be invited to be able to join the channel */
+  if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
+    strncat(check, client->nickname, strlen(client->nickname));
+    if (!strchr(client->nickname, '@')) {
+      strncat(check, "@", 1);
+      strncat(check, server->server_name, strlen(server->server_name));
+    }
+    strncat(check, "!", 1);
+    strncat(check, client->username, strlen(client->username));
+    if (!strchr(client->username, '@')) {
+      strncat(check, "@", 1);
+      strncat(check, cmd->sock->hostname, strlen(cmd->sock->hostname));
     }
   }
 
     }
   }
 
-  /* Check ban list if set */
-  if (channel->mode & SILC_CHANNEL_MODE_BAN) {
+  /* Check invite list if channel is invite-only channel */
+  if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT && 
+      channel->mode & SILC_CHANNEL_MODE_INVITE && channel->invite_list) {
+    if (!silc_string_match(channel->invite_list, check)) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+                                           SILC_STATUS_ERR_NOT_INVITED);
+      goto out;
+    }
+  }
 
 
+  /* Check ban list if it exists. If the client's nickname, server,
+     username and/or hostname is in the ban list the access to the
+     channel is denied. */
+  if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT && channel->ban_list) {
+    if (silc_string_match(channel->ban_list, check)) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
+                             SILC_STATUS_ERR_BANNED_FROM_CHANNEL);
+      goto out;
+    }
   }
 
   }
 
+  /* Get passphrase */
+  tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
+  if (tmp) {
+    passphrase = silc_calloc(tmp_len, sizeof(*passphrase));
+    memcpy(passphrase, tmp, tmp_len);
+  }
+  
   /* Check the channel passphrase if set. */
   if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
   /* Check the channel passphrase if set. */
   if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
-    if (!passphrase || memcmp(channel->mode_data.passphrase, passphrase,
-                             strlen(channel->mode_data.passphrase))) {
+    if (!passphrase || memcmp(channel->passphrase, passphrase,
+                             strlen(channel->passphrase))) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                            SILC_STATUS_ERR_BAD_PASSWORD);
       goto out;
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                            SILC_STATUS_ERR_BAD_PASSWORD);
       goto out;
@@ -2615,7 +2646,7 @@ static void silc_server_command_join_channel(SilcServer server,
   /* Check user count limit if set. */
   if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
     if (silc_list_count(channel->user_list) + 1 > 
   /* Check user count limit if set. */
   if (channel->mode & SILC_CHANNEL_MODE_ULIMIT) {
     if (silc_list_count(channel->user_list) + 1 > 
-       channel->mode_data.user_limit) {
+       channel->user_limit) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                            SILC_STATUS_ERR_CHANNEL_IS_FULL);
       goto out;
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                            SILC_STATUS_ERR_CHANNEL_IS_FULL);
       goto out;
@@ -2626,22 +2657,6 @@ static void silc_server_command_join_channel(SilcServer server,
    * Client is allowed to join to the channel. Make it happen.
    */
 
    * Client is allowed to join to the channel. Make it happen.
    */
 
-  /* Get the client entry */
-  if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
-    client = (SilcClientEntry)sock->user_data;
-  } else {
-    client = silc_idlist_find_client_by_id(server->local_list, client_id, 
-                                          NULL);
-    if (!client) {
-      /* XXX actually this is useless since router finds always cell's
-        local clients from its local lists. */
-      client = silc_idlist_find_client_by_id(server->global_list, client_id, 
-                                            NULL);
-      if (!client)
-       goto out;
-    }
-  }
-
   /* Check whether the client already is on the channel */
   if (silc_server_client_on_channel(client, channel)) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
   /* Check whether the client already is on the channel */
   if (silc_server_client_on_channel(client, channel)) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
@@ -2689,39 +2704,31 @@ static void silc_server_command_join_channel(SilcServer server,
                                         channel->channel_key->cipher->name,
                                         channel->key_len / 8, channel->key);
   silc_free(tmp);
                                         channel->channel_key->cipher->name,
                                         channel->key_len / 8, channel->key);
   silc_free(tmp);
-  if (!channel->topic) {
-    reply = 
-      silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
-                                          SILC_STATUS_OK, ident, 9,
-                                          2, channel->channel_name,
-                                          strlen(channel->channel_name),
-                                          3, chidp->data, chidp->len,
-                                          4, clidp->data, clidp->len,
-                                          5, mode, 4,
-                                          6, tmp2, 4,
-                                          7, keyp->data, keyp->len,
-                                          12, tmp3, 4,
-                                          13, user_list->data, user_list->len,
-                                          14, mode_list->data, 
-                                          mode_list->len);
-  } else {
-    reply = 
-      silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
-                                          SILC_STATUS_OK, ident, 10, 
-                                          2, channel->channel_name, 
-                                          strlen(channel->channel_name),
-                                          3, chidp->data, chidp->len,
-                                          4, clidp->data, clidp->len,
-                                          5, mode, 4,
-                                          6, tmp2, 4,
-                                          7, keyp->data, keyp->len,
-                                          10, channel->topic, 
-                                          strlen(channel->topic),
-                                          12, tmp3, 4,
-                                          13, user_list->data, user_list->len,
-                                          14, mode_list->data, 
-                                          mode_list->len);
-  }
+  reply = 
+    silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN,
+                                        SILC_STATUS_OK, ident, 13,
+                                        2, channel->channel_name,
+                                        strlen(channel->channel_name),
+                                        3, chidp->data, chidp->len,
+                                        4, clidp->data, clidp->len,
+                                        5, mode, 4,
+                                        6, tmp2, 4,
+                                        7, keyp->data, keyp->len,
+                                        8, channel->ban_list, 
+                                        channel->ban_list ?
+                                        strlen(channel->ban_list) : 0,
+                                        9, channel->invite_list,
+                                        channel->invite_list ?
+                                        strlen(channel->invite_list) : 0,
+                                        10, channel->topic,
+                                        channel->topic ?
+                                        strlen(channel->topic) : 0,
+                                        11, channel->hmac->hmac->name,
+                                        strlen(channel->hmac->hmac->name),
+                                        12, tmp3, 4,
+                                        13, user_list->data, user_list->len,
+                                        14, mode_list->data, 
+                                        mode_list->len);
 
   /* Send command reply */
   silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, 
 
   /* Send command reply */
   silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, 
@@ -3338,12 +3345,12 @@ SILC_SERVER_CMD_FUNC(cmode)
       }
     } else {
       SILC_GET32_MSB(user_limit, tmp);
       }
     } else {
       SILC_GET32_MSB(user_limit, tmp);
-      channel->mode_data.user_limit = user_limit;
+      channel->user_limit = user_limit;
     }
   } else {
     if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
       /* User limit mode is unset. Remove user limit */
     }
   } else {
     if (channel->mode & SILC_CHANNEL_MODE_ULIMIT)
       /* User limit mode is unset. Remove user limit */
-      channel->mode_data.user_limit = 0;
+      channel->user_limit = 0;
   }
 
   if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
   }
 
   if (mode_mask & SILC_CHANNEL_MODE_PASSPHRASE) {
@@ -3359,66 +3366,14 @@ SILC_SERVER_CMD_FUNC(cmode)
       }
 
       /* Save the passphrase */
       }
 
       /* Save the passphrase */
-      channel->mode_data.passphrase = strdup(tmp);
+      channel->passphrase = strdup(tmp);
     }
   } else {
     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
       /* Passphrase mode is unset. remove the passphrase */
     }
   } else {
     if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
       /* Passphrase mode is unset. remove the passphrase */
-      if (channel->mode_data.passphrase) {
-       silc_free(channel->mode_data.passphrase);
-       channel->mode_data.passphrase = NULL;
-      }
-    }
-  }
-
-  if (mode_mask & SILC_CHANNEL_MODE_BAN) {
-    if (!(channel->mode & SILC_CHANNEL_MODE_BAN)) {
-      /* Ban list is specified for channel */
-
-      /* Get ban list */
-      tmp = silc_argument_get_arg_type(cmd->args, 5, NULL);
-      if (!tmp) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
-                                  SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-       goto out;
-      }
-
-      /* XXX check that channel founder is not banned */
-
-      /* Save the ban list */
-      channel->mode_data.ban_list = strdup(tmp);
-    }
-  } else {
-    if (channel->mode & SILC_CHANNEL_MODE_BAN) {
-      /* Ban mode is unset. Remove the entire ban list */
-      if (channel->mode_data.ban_list) {
-       silc_free(channel->mode_data.ban_list);
-       channel->mode_data.ban_list = NULL;
-      }
-    }
-  }
-
-  if (mode_mask & SILC_CHANNEL_MODE_INVITE_LIST) {
-    if (!(channel->mode & SILC_CHANNEL_MODE_INVITE_LIST)) {
-      /* Invite list is specified for channel */
-
-      /* Get invite list */
-      tmp = silc_argument_get_arg_type(cmd->args, 6, NULL);
-      if (!tmp) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
-                                  SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
-       goto out;
-      }
-
-      /* Save the invite linst */
-      channel->mode_data.invite_list = strdup(tmp);
-    }
-  } else {
-    if (channel->mode & SILC_CHANNEL_MODE_INVITE_LIST) {
-      /* Invite list mode is unset. Remove the entire invite list */
-      if (channel->mode_data.invite_list) {
-       silc_free(channel->mode_data.invite_list);
-       channel->mode_data.invite_list = NULL;
+      if (channel->passphrase) {
+       silc_free(channel->passphrase);
+       channel->passphrase = NULL;
       }
     }
   }
       }
     }
   }
@@ -3481,12 +3436,7 @@ SILC_SERVER_CMD_FUNC(cmode)
     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
       /* Cipher mode is unset. Remove the cipher and revert back to 
         default cipher */
     if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
       /* Cipher mode is unset. Remove the cipher and revert back to 
         default cipher */
-
-      if (channel->mode_data.cipher) {
-       silc_free(channel->mode_data.cipher);
-       channel->mode_data.cipher = NULL;
-       channel->mode_data.key_len = 0;
-      }
+      char *cipher = channel->channel_key->cipher->name;
 
       /* Generate new cipher and key for the channel */
 
 
       /* Generate new cipher and key for the channel */
 
@@ -3494,14 +3444,10 @@ SILC_SERVER_CMD_FUNC(cmode)
 
       /* Delete old cipher and allocate default one */
       silc_cipher_free(channel->channel_key);
 
       /* Delete old cipher and allocate default one */
       silc_cipher_free(channel->channel_key);
-      if (!channel->cipher)
-       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;
-       }
+      if (!silc_cipher_alloc(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 */
       }
 
       /* Re-generate channel key */
@@ -4422,3 +4368,139 @@ SILC_SERVER_CMD_FUNC(users)
  out:
   silc_server_command_free(cmd);
 }
  out:
   silc_server_command_free(cmd);
 }
+
+/* Server side of command BAN. This is used to manage the ban list of the
+   channel. To add clients and remove clients from the ban list. */
+
+SILC_SERVER_CMD_FUNC(ban)
+{
+  SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+  SilcServer server = cmd->server;
+  SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+  SilcBuffer packet;
+  SilcChannelEntry channel;
+  SilcChannelClientEntry chl;
+  SilcChannelID *channel_id = NULL;
+  unsigned char *id, *add, *del;
+  unsigned int id_len, tmp_len;
+  unsigned short ident = silc_command_get_ident(cmd->payload);
+
+  if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
+    goto out;
+
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_BAN, cmd, 0, 3);
+
+  /* Get Channel ID */
+  id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
+  if (id) {
+    channel_id = silc_id_payload_parse_id(id, id_len);
+    if (!channel_id) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+                                           SILC_STATUS_ERR_NO_CHANNEL_ID);
+      goto out;
+    }
+  }
+
+  /* Get channel entry. The server must know about the channel since the
+     client is expected to be on the channel. */
+  channel = silc_idlist_find_channel_by_id(server->local_list, 
+                                          channel_id, NULL);
+  if (!channel) {
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
+                                            channel_id, NULL);
+    if (!channel) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+                                           SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+      goto out;
+    }
+  }
+
+  /* Check whether this client is on the channel */
+  if (!silc_server_client_on_channel(client, channel)) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+                                         SILC_STATUS_ERR_NOT_ON_CHANNEL);
+    goto out;
+  }
+
+  /* Get entry to the channel user list */
+  silc_list_start(channel->user_list);
+  while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
+    if (chl->client == client)
+      break;
+
+  /* The client must be at least channel operator. */
+  if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+                                         SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+    goto out;
+  }
+
+  /* Get the new ban and add it to the ban list */
+  add = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+  if (add) {
+    if (!channel->ban_list)
+      channel->ban_list = silc_calloc(tmp_len + 2, sizeof(*channel->ban_list));
+    else
+      channel->ban_list = silc_realloc(channel->ban_list, 
+                                      sizeof(*channel->ban_list) * 
+                                      (tmp_len + 
+                                       strlen(channel->ban_list) + 2));
+    strncat(channel->ban_list, add, tmp_len);
+    strncat(channel->ban_list, ",", 1);
+  }
+
+  /* Get the ban to be removed and remove it from the list */
+  del = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
+  if (del && channel->ban_list) {
+    char *start, *end, *n;
+
+    if (!strncmp(channel->ban_list, del, strlen(channel->ban_list) - 1)) {
+      silc_free(channel->ban_list);
+      channel->ban_list = NULL;
+      goto out0;
+    }
+
+    start = strstr(channel->ban_list, del);
+    if (start && strlen(start) >= tmp_len) {
+      end = start + tmp_len;
+      n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
+      strncat(n, channel->ban_list, start - channel->ban_list);
+      strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) - 
+                          end) - 1);
+      silc_free(channel->ban_list);
+      channel->ban_list = n;
+    }
+  }
+
+ out0:
+
+  /* Send the BAN notify type to our primary router. */
+  if (!server->standalone && (add || del))
+    silc_server_send_notify_ban(server, server->router->connection,
+                               server->server_type == SILC_ROUTER ?
+                               TRUE : FALSE, channel, add, del);
+
+  /* Send the reply back to the client */
+  if (channel->ban_list)
+    packet = 
+      silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
+                                          SILC_STATUS_OK, ident, 2,
+                                          2, id, id_len,
+                                          3, channel->ban_list, 
+                                          strlen(channel->ban_list) - 1);
+  else
+    packet = 
+      silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
+                                          SILC_STATUS_OK, ident, 1,
+                                          2, id, id_len);
+
+  silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, 
+                         packet->data, packet->len, FALSE);
+    
+  silc_buffer_free(packet);
+
+ out:
+  if (channel_id)
+    silc_free(channel_id);
+  silc_server_command_free(cmd);
+}
index 8fc42e1ed2fa91b7e4fae50478e1b2da0ec02ed9..f8b7a5fe20088bef9c6b6de4a2ad3874b7637fb5 100644 (file)
@@ -154,5 +154,6 @@ SILC_SERVER_CMD_FUNC(shutdown);
 SILC_SERVER_CMD_FUNC(silcoper);
 SILC_SERVER_CMD_FUNC(leave);
 SILC_SERVER_CMD_FUNC(users);
 SILC_SERVER_CMD_FUNC(silcoper);
 SILC_SERVER_CMD_FUNC(leave);
 SILC_SERVER_CMD_FUNC(users);
+SILC_SERVER_CMD_FUNC(ban);
 
 #endif
 
 #endif
index b693e2f3711bf1c6eb110b614f5dc8945afe1680..37c2838d8001511c1fc0e6722f9d56e140f84f2d 100644 (file)
@@ -724,6 +724,32 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
     silc_free(id);
   }
 
     silc_free(id);
   }
 
+  /* Get the ban list */
+  tmp = silc_argument_get_arg_type(cmd->args, 8, &len);
+  if (tmp) {
+    if (entry->ban_list)
+      silc_free(entry->ban_list);
+    entry->ban_list = silc_calloc(len, sizeof(*entry->ban_list));
+    memcpy(entry->ban_list, tmp, len);
+  }
+
+  /* Get the invite list */
+  tmp = silc_argument_get_arg_type(cmd->args, 9, &len);
+  if (tmp) {
+    if (entry->invite_list)
+      silc_free(entry->invite_list);
+    entry->invite_list = silc_calloc(len, sizeof(*entry->invite_list));
+    memcpy(entry->invite_list, tmp, len);
+  }
+
+  /* Get the topic */
+  tmp = silc_argument_get_arg_type(cmd->args, 10, &len);
+  if (tmp) {
+    if (entry->topic)
+      silc_free(entry->topic);
+    entry->topic = strdup(tmp);
+  }
+
   /* If channel was not created we know there is global users on the 
      channel. */
   entry->global_users = (created == 0 ? TRUE : FALSE);
   /* If channel was not created we know there is global users on the 
      channel. */
   entry->global_users = (created == 0 ? TRUE : FALSE);
index efca0dbf03cfd73ceee9a94840e641f6baba405d..1198e58af567fba7b9df9514e79700042771e27a 100644 (file)
@@ -211,8 +211,7 @@ typedef struct SilcChannelClientEntryStruct {
 
    char username
 
 
    char username
 
-       Client's (meaning user's) real name. This is defined in following 
-       manner:
+       Client's usename. This is defined in the following manner:
 
        Server type   List type      Contents
        ====================================================
 
        Server type   List type      Contents
        ====================================================
@@ -390,15 +389,10 @@ struct SilcChannelEntryStruct {
   char *topic;
   char *cipher;
 
   char *topic;
   char *cipher;
 
-  /* Data that is related to different channel modes. */
-  struct {
-    unsigned int user_limit;
-    unsigned char *passphrase;
-    unsigned char *ban_list;
-    unsigned char *invite_list;
-    unsigned char *cipher;
-    unsigned int key_len;
-  } mode_data;
+  unsigned int user_limit;
+  unsigned char *passphrase;
+  char *invite_list;
+  char *ban_list;
 
   /* List of users on channel */
   SilcList user_list;
 
   /* List of users on channel */
   SilcList user_list;
index 16e9fa430f1d5f9ed0106329a393ffcd6bd70d94..a938e53c86a21d5fd1e5fb9030c7565ec5098e8c 100644 (file)
@@ -663,6 +663,74 @@ void silc_server_notify(SilcServer server,
 
     break;
 
 
     break;
 
+  case SILC_NOTIFY_TYPE_BAN:
+    /*
+     * Save the ban
+     */
+
+    SILC_LOG_DEBUG(("BAN notify"));
+    
+    /* Get Channel ID */
+    tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+    if (!tmp)
+      goto out;
+    channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!channel_id)
+      goto out;
+    
+    /* Get channel entry */
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
+                                            channel_id, NULL);
+    if (!channel) {
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
+                                              channel_id, NULL);
+      if (!channel) {
+       silc_free(channel_id);
+       goto out;
+      }
+    }
+    silc_free(channel_id);
+
+    /* Get the new ban and add it to the ban list */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+    if (tmp) {
+      if (!channel->ban_list)
+       channel->ban_list = silc_calloc(tmp_len + 2, 
+                                       sizeof(*channel->ban_list));
+      else
+       channel->ban_list = silc_realloc(channel->ban_list, 
+                                        sizeof(*channel->ban_list) * 
+                                        (tmp_len + 
+                                         strlen(channel->ban_list) + 2));
+      strncat(channel->ban_list, tmp, tmp_len);
+      strncat(channel->ban_list, ",", 1);
+    }
+
+    /* Get the ban to be removed and remove it from the list */
+    tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+    if (tmp && channel->ban_list) {
+      char *start, *end, *n;
+      
+      if (!strcmp(channel->ban_list, tmp)) {
+       silc_free(channel->ban_list);
+       channel->ban_list = NULL;
+       break;
+      }
+      
+      start = strstr(channel->ban_list, tmp);
+      if (start && strlen(start) >= tmp_len) {
+       end = start + tmp_len;
+       n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
+       strncat(n, channel->ban_list, start - channel->ban_list);
+       strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) - 
+                            end) - 1);
+       silc_free(channel->ban_list);
+       channel->ban_list = n;
+      }
+    }
+
+    break;
+
     /* Ignore rest of the notify types for now */
   case SILC_NOTIFY_TYPE_NONE:
   case SILC_NOTIFY_TYPE_MOTD:
     /* Ignore rest of the notify types for now */
   case SILC_NOTIFY_TYPE_NONE:
   case SILC_NOTIFY_TYPE_MOTD:
index 7cd1767981447910a54c47e52a9d3c840c0afad8..2dba70f34e4a2c6e4ed17eb294bc92c1066eeea0 100644 (file)
@@ -1125,6 +1125,27 @@ void silc_server_send_notify_umode(SilcServer server,
   silc_buffer_free(idp);
 }
 
   silc_buffer_free(idp);
 }
 
+/* Sends BAN notify type. This tells that `ban' has been either `add'ed
+   or `del'eted on the `channel. This function is used to send the packet
+   between routers as broadcast packet. */
+
+void silc_server_send_notify_ban(SilcServer server,
+                                SilcSocketConnection sock,
+                                int broadcast,
+                                SilcChannelEntry channel,
+                                char *add, char *del)
+{
+  SilcBuffer idp;
+
+  idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL);
+  silc_server_send_notify(server, sock, broadcast,
+                         SILC_NOTIFY_TYPE_BAN, 3,
+                         idp->data, idp->len,
+                         add, add ? strlen(add) : 0,
+                         del, del ? strlen(del) : 0);
+  silc_buffer_free(idp);
+}
+
 /* Sends notify message destined to specific entity. */
 
 void silc_server_send_notify_dest(SilcServer server,
 /* Sends notify message destined to specific entity. */
 
 void silc_server_send_notify_dest(SilcServer server,
index 29b349286c0f8baee00e9812aae211bcceec8f1a..b856e0e44bf01ad1a8efb8e8c6c085510467f70f 100644 (file)
@@ -174,6 +174,11 @@ void silc_server_send_notify_umode(SilcServer server,
                                   SilcClientID *client_id,
                                   unsigned int client_id_len,
                                   unsigned int mode_mask);
                                   SilcClientID *client_id,
                                   unsigned int client_id_len,
                                   unsigned int mode_mask);
+void silc_server_send_notify_ban(SilcServer server,
+                                SilcSocketConnection sock,
+                                int broadcast,
+                                SilcChannelEntry channel,
+                                char *add, char *del);
 void silc_server_send_notify_dest(SilcServer server,
                                  SilcSocketConnection sock,
                                  int broadcast,
 void silc_server_send_notify_dest(SilcServer server,
                                  SilcSocketConnection sock,
                                  int broadcast,
index 42ed3eae557fcc11cf459bdcbb77c8bacb6813ad..1eaa60712ab7aae1843e23183e8026d08547a0f6 100644 (file)
@@ -1,17 +1,23 @@
 [Cipher]
 [Cipher]
-rc6:../lib/silcsim/modules/rc6.sim.so:16:16
-twofish:../lib/silcsim/modules/twofish.sim.so:16:16
-mars:../lib/silcsim/modules/mars.sim.so:16:16
+aes-256-cbc:../lib/silcsim/modules/aes.sim.so:32:16
+aes-192-cbc:../lib/silcsim/modules/aes.sim.so:24:16
+aes-128-cbc:../lib/silcsim/modules/aes.sim.so:16:16
+twofish-256-cbc:../lib/silcsim/modules/twofish.sim.so:32:16
+twofish-192-cbc:../lib/silcsim/modules/twofish.sim.so:24:16
+twofish-128-cbc:../lib/silcsim/modules/twofish.sim.so:16:16
+mars-256-cbc:../lib/silcsim/modules/mars.sim.so:32:16
+mars-192-cbc:../lib/silcsim/modules/mars.sim.so:24:16
+mars-128-cbc:../lib/silcsim/modules/mars.sim.so:16:16
 none:../lib/silcsim/modules/none.sim.so:0:0
 
 none:../lib/silcsim/modules/none.sim.so:0:0
 
-[Hash] 
+[Hash]
 md5::64:16
 sha1::64:20
 
 [hmac]
 hmac-sha1-96:sha1:12
 hmac-md5-96:md5:12
 md5::64:16
 sha1::64:20
 
 [hmac]
 hmac-sha1-96:sha1:12
 hmac-md5-96:md5:12
-hmac-sha1:sha1:20
+hmac-sha1:sha1:20   
 hmac-md5:md5:16
 
 #[PKCS]
 hmac-md5:md5:16
 
 #[PKCS]
@@ -25,10 +31,10 @@ nobody:nobody
 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
 
 [ServerInfo]
 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
 
 [ServerInfo]
-lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334
+lassi.kuo.fi.ssh.com:212.146.42.253:Kuopio, Finland:1334
 
 [ListenPort]
 
 [ListenPort]
-10.2.1.7:10.2.1.7:1334
+212.146.42.253:212.146.42.253:1334
 
 [Logging]
 infologfile:silcd2.log:10000
 
 [Logging]
 infologfile:silcd2.log:10000
@@ -47,16 +53,13 @@ errorlogfile:silcd2.log:10000
 :::1336:1
 
 [AdminConnection]
 :::1336:1
 
 [AdminConnection]
-*:silc:silc:passwd:testi
+*:priikone:*:passwd:testi
 
 [ServerConnection]
 
 [ServerConnection]
-10.2.1.7:passwd:priikone:1333:1:1
+212.146.42.253:passwd:priikone:1333:1:1
 
 [RouterConnection]
 
 [RouterConnection]
-10.2.1.7:passwd:priikone:1335:1:1:0
+212.146.42.253:passwd:priikone:1335:1:1:0
 
 [DenyConnection]
 [RedirectClient]
 
 [DenyConnection]
 [RedirectClient]
-
-[motd]
-./motd
index 2f6582887c555fd8078272b7b213248bc54847e5..d641e083f55b5f31f5d99d2dad755cbc184de5f6 100644 (file)
@@ -2264,7 +2264,7 @@ List of all defined commands in SILC follows.
    7    SILC_COMMAND_INVITE
 
         Max Arguments:  4
    7    SILC_COMMAND_INVITE
 
         Max Arguments:  4
-            Arguments:  (1) [<Client ID>]      (2) [<Channel ID>]
+            Arguments:  (1) [<Client ID>]      (2) <Channel ID>
                         (3) [<adding client>]  (4) [<removing client>]
 
         This command is used to invite other clients to join to the
                         (3) [<adding client>]  (4) [<removing client>]
 
         This command is used to invite other clients to join to the
@@ -2294,12 +2294,12 @@ List of all defined commands in SILC follows.
         nickname and hostname and add to the invite list before sending
         the notify packet.
         
         nickname and hostname and add to the invite list before sending
         the notify packet.
         
-        When this command is given without any arguments then the command
-        merely returns the invite list of the channel.   This command must
-        fail if the requested channel does not exist, the requested
-        <Client ID> is already on the channel or if the channel is invite
-        only channel and the caller of this command does not have at least
-        channel operator privileges.
+        When this command is given with only <Channel ID> argument then
+        the command merely returns the invite list of the channel.   This
+        command must fail if the requested channel does not exist, the
+        requested <Client ID> is already on the channel or if the channel
+        is invite only channel and the caller of this command does not
+        have at least channel operator privileges.
 
         Reply messages to the command:
 
 
         Reply messages to the command:
 
@@ -2551,7 +2551,7 @@ List of all defined commands in SILC follows.
             Arguments:  (1) <Status Payload>      (2) <channel> 
                         (3) <Channel ID>          (4) <Client ID>
                         (5) <channel mode mask>   (6) <created>
             Arguments:  (1) <Status Payload>      (2) <channel> 
                         (3) <Channel ID>          (4) <Client ID>
                         (5) <channel mode mask>   (6) <created>
-                        (7) <Channel Key Payload> (8) [<ban mask>]
+                        (7) <Channel Key Payload> (8) [<ban list>]
                         (9) [<invite list>]       (10) [<topic>]
                         (11) [<hmac>]             (12) <list count>
                         (13) <Client ID list>     (14) <client mode list>
                         (9) [<invite list>]       (10) [<topic>]
                         (11) [<hmac>]             (12) <list count>
                         (13) <Client ID list>     (14) <client mode list>
@@ -3162,7 +3162,7 @@ List of all defined commands in SILC follows.
    26   SILC_COMMAND_BAN
 
         Max Arguments:  3
    26   SILC_COMMAND_BAN
 
         Max Arguments:  3
-            Arguments:  (1) [<Channel ID>]       (2) [<adding client>]
+            Arguments:  (1) <Channel ID>         (2) [<adding client>]
                         (3) [<removing client>]
 
         This command is used to manage the ban list of the channel
                         (3) [<removing client>]
 
         This command is used to manage the ban list of the channel
@@ -3183,7 +3183,7 @@ List of all defined commands in SILC follows.
         from than one clients then the lists are an comma (`,') separated
         list.
 
         from than one clients then the lists are an comma (`,') separated
         list.
 
-        If this command is executed without any arguments the command
+        If this command is executed without the ban arguments the command
         merely replies with the current ban list.
 
 
         merely replies with the current ban list.
 
 
@@ -3202,6 +3202,7 @@ List of all defined commands in SILC follows.
             SILC_STATUS_ERR_NOT_REGISTERED
             SILC_STATUS_ERR_TOO_MANY_PARAMS
             SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID
             SILC_STATUS_ERR_NOT_REGISTERED
             SILC_STATUS_ERR_TOO_MANY_PARAMS
             SILC_STATUS_ERR_NO_SUCH_CHANNEL_ID
+            SILC_STATUS_ERR_NO_CHANNEL_ID
             SILC_STATUS_ERR_NOT_ON_CHANNEL
             SILC_STATUS_ERR_NO_CHANNEL_PRIV
 
             SILC_STATUS_ERR_NOT_ON_CHANNEL
             SILC_STATUS_ERR_NO_CHANNEL_PRIV
 
index 002363fb305077eb4b8410759d1bd845275e2e3b..1ef9975d122c6d08c6b88315710a5b067fee61ff 100644 (file)
@@ -58,6 +58,7 @@ SilcClientCommand silc_command_list[] =
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER, 3),
   SILC_CLIENT_CMD(leave, LEAVE, "LEAVE", SILC_CF_LAG | SILC_CF_REG, 2),
   SILC_CLIENT_CMD(users, USERS, "USERS", SILC_CF_LAG | SILC_CF_REG, 2),
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER, 3),
   SILC_CLIENT_CMD(leave, LEAVE, "LEAVE", SILC_CF_LAG | SILC_CF_REG, 2),
   SILC_CLIENT_CMD(users, USERS, "USERS", SILC_CF_LAG | SILC_CF_REG, 2),
+  SILC_CLIENT_CMD(ban, BAN, "BAN", SILC_CF_LAG | SILC_CF_REG, 3),
 
   { NULL, 0, NULL, 0, 0 },
 };
 
   { NULL, 0, NULL, 0, 0 },
 };
@@ -1180,26 +1181,6 @@ SILC_CLIENT_CMD_FUNC(cmode)
        mode &= ~SILC_CHANNEL_MODE_PASSPHRASE;
       }
       break;
        mode &= ~SILC_CHANNEL_MODE_PASSPHRASE;
       }
       break;
-    case 'b':
-      if (add) {
-       mode |= SILC_CHANNEL_MODE_BAN;
-       type = 5;
-       arg = cmd->argv[3];
-       arg_len = cmd->argv_lens[3];
-      } else {
-       mode &= ~SILC_CHANNEL_MODE_BAN;
-      }
-      break;
-    case 'I':
-      if (add) {
-       mode |= SILC_CHANNEL_MODE_INVITE_LIST;
-       type = 6;
-       arg = cmd->argv[3];
-       arg_len = cmd->argv_lens[3];
-      } else {
-       mode &= ~SILC_CHANNEL_MODE_INVITE_LIST;
-      }
-      break;
     case 'c':
       if (add) {
        mode |= SILC_CHANNEL_MODE_CIPHER;
     case 'c':
       if (add) {
        mode |= SILC_CHANNEL_MODE_CIPHER;
@@ -1963,3 +1944,80 @@ SILC_CLIENT_CMD_FUNC(users)
  out:
   silc_client_command_free(cmd);
 }
  out:
   silc_client_command_free(cmd);
 }
+
+/* Command BAN. This is used to manage the ban list of the channel. */
+
+SILC_CLIENT_CMD_FUNC(ban)
+{
+  SilcClientCommandContext cmd = (SilcClientCommandContext)context;
+  SilcClientConnection conn = cmd->conn;
+  SilcChannelEntry channel;
+  SilcBuffer buffer, chidp;
+  int type = 0;
+  char *name, *ban = NULL;
+
+  if (!cmd->conn) {
+    SILC_NOT_CONNECTED(cmd->client, cmd->conn);
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  if (cmd->argc < 2) {
+    cmd->client->ops->say(cmd->client, conn, 
+                  "Usage: /BAN <channel> "
+                  "[+|-[<nickname>[@<server>[!<username>[@hostname>]]]]]");
+    COMMAND_ERROR;
+    goto out;
+  }
+
+  if (cmd->argv[1][0] == '*') {
+    if (!conn->current_channel) {
+      cmd->client->ops->say(cmd->client, conn, "You are not on any channel");
+      COMMAND_ERROR;
+      goto out;
+    }
+
+    channel = conn->current_channel;
+  } else {
+    name = cmd->argv[1];
+
+    channel = silc_client_get_channel(cmd->client, conn, name);
+    if (!channel) {
+      cmd->client->ops->say(cmd->client, conn, "You are on that channel");
+      COMMAND_ERROR;
+      goto out;
+    }
+  }
+
+  if (cmd->argc == 3) {
+    if (cmd->argv[2][0] == '+')
+      type = 2;
+    else
+      type = 3;
+
+    ban = cmd->argv[2];
+    ban++;
+  }
+
+  chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
+
+  /* Send the command */
+  if (ban)
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_BAN, 0, 2, 
+                                           1, chidp->data, chidp->len,
+                                           type, ban, strlen(ban));
+  else
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_BAN, 0, 1, 
+                                           1, chidp->data, chidp->len);
+
+  silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL, 
+                         0, NULL, NULL, buffer->data, buffer->len, TRUE);
+  silc_buffer_free(buffer);
+  silc_buffer_free(chidp);
+
+  /* Notify application */
+  COMMAND;
+
+ out:
+  silc_client_command_free(cmd);
+}
index fad677509858c2500843ece9ac3dd30761b07410..64af6d8ca24c78fa2ec576b6439da4fe63c21f17 100644 (file)
@@ -153,5 +153,6 @@ SILC_CLIENT_CMD_FUNC(shutdown);
 SILC_CLIENT_CMD_FUNC(silcoper);
 SILC_CLIENT_CMD_FUNC(leave);
 SILC_CLIENT_CMD_FUNC(users);
 SILC_CLIENT_CMD_FUNC(silcoper);
 SILC_CLIENT_CMD_FUNC(leave);
 SILC_CLIENT_CMD_FUNC(users);
+SILC_CLIENT_CMD_FUNC(ban);
 
 #endif
 
 #endif
index 261578cf17a8b19cb0723088875106c39a41cda0..a97b23529fef89d2c432f04a57c6906f384b119c 100644 (file)
@@ -63,6 +63,7 @@ SilcClientCommandReply silc_command_reply_list[] =
   SILC_CLIENT_CMD_REPLY(silcoper, SILCOPER),
   SILC_CLIENT_CMD_REPLY(leave, LEAVE),
   SILC_CLIENT_CMD_REPLY(users, USERS),
   SILC_CLIENT_CMD_REPLY(silcoper, SILCOPER),
   SILC_CLIENT_CMD_REPLY(leave, LEAVE),
   SILC_CLIENT_CMD_REPLY(users, USERS),
+  SILC_CLIENT_CMD_REPLY(ban, BAN),
 
   { NULL, 0 },
 };
 
   { NULL, 0 },
 };
@@ -679,7 +680,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic)
   if (!channel_id)
     goto out;
 
   if (!channel_id)
     goto out;
 
-  /* Get the channel name */
+  /* Get the channel entry */
   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
                                   SILC_ID_CHANNEL, &id_cache)) {
     silc_free(channel_id);
   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
                                   SILC_ID_CHANNEL, &id_cache)) {
     silc_free(channel_id);
@@ -1646,3 +1647,56 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
   SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_USERS);
   silc_client_command_reply_free(cmd);
 }
   SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_USERS);
   silc_client_command_reply_free(cmd);
 }
+
+SILC_CLIENT_CMD_REPLY_FUNC(ban)
+{
+  SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
+  SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
+  SilcCommandStatus status;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcChannelEntry channel;
+  SilcChannelID *channel_id;
+  unsigned char *tmp;
+  unsigned int len;
+
+  tmp = silc_argument_get_arg_type(cmd->args, 1, NULL);
+  SILC_GET16_MSB(status, tmp);
+  if (status != SILC_STATUS_OK) {
+    cmd->client->ops->say(cmd->client, conn,
+            "%s", silc_client_command_status_message(status));
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
+
+  /* Take Channel ID */
+  tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
+  if (!tmp)
+    goto out;
+
+  channel_id = silc_id_payload_parse_id(tmp, len);
+  if (!channel_id)
+    goto out;
+
+  /* Get the channel entry */
+  if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
+                                  SILC_ID_CHANNEL, &id_cache)) {
+    silc_free(channel_id);
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
+  
+  channel = (SilcChannelEntry)id_cache->context;
+
+  /* Get the ban list */
+  tmp = silc_argument_get_arg_type(cmd->args, 3, &len);
+
+  /* Notify application */
+  COMMAND_REPLY((ARGS, channel, tmp));
+
+  /* Execute any pending command callbacks */
+  SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_BAN);
+
+ out:
+  SILC_CLIENT_PENDING_DESTRUCTOR(cmd, SILC_COMMAND_BAN);
+  silc_client_command_reply_free(cmd);
+}
index de788130172d2f8716bc61094ec33ffebbbeddb9..f1ebd1c3c3d20a6f8754e4b1c8c53a06e87fa954 100644 (file)
@@ -98,5 +98,6 @@ SILC_CLIENT_CMD_REPLY_FUNC(shutdown);
 SILC_CLIENT_CMD_REPLY_FUNC(silcoper);
 SILC_CLIENT_CMD_REPLY_FUNC(leave);
 SILC_CLIENT_CMD_REPLY_FUNC(users);
 SILC_CLIENT_CMD_REPLY_FUNC(silcoper);
 SILC_CLIENT_CMD_REPLY_FUNC(leave);
 SILC_CLIENT_CMD_REPLY_FUNC(users);
+SILC_CLIENT_CMD_REPLY_FUNC(ban);
 
 #endif
 
 #endif
index 3185fe305cb064810752a2e2d6ea7b5e54206f37..784bd5bb47bc2be746b52621dcf5657b9d797f39 100644 (file)
@@ -195,7 +195,7 @@ SilcBuffer silc_command_payload_encode_va(SilcCommand cmd,
   unsigned int x_len;
   unsigned int x_type;
   SilcBuffer buffer;
   unsigned int x_len;
   unsigned int x_type;
   SilcBuffer buffer;
-  int i;
+  int i, k;
 
   va_start(ap, argc);
 
 
   va_start(ap, argc);
 
@@ -203,21 +203,25 @@ SilcBuffer silc_command_payload_encode_va(SilcCommand cmd,
   argv_lens = silc_calloc(argc, sizeof(unsigned int));
   argv_types = silc_calloc(argc, sizeof(unsigned int));
 
   argv_lens = silc_calloc(argc, sizeof(unsigned int));
   argv_types = silc_calloc(argc, sizeof(unsigned int));
 
-  for (i = 0; i < argc; i++) {
+  for (i = 0, k = 0; i < argc; i++) {
     x_type = va_arg(ap, unsigned int);
     x = va_arg(ap, unsigned char *);
     x_len = va_arg(ap, unsigned int);
 
     x_type = va_arg(ap, unsigned int);
     x = va_arg(ap, unsigned char *);
     x_len = va_arg(ap, unsigned int);
 
-    argv[i] = silc_calloc(x_len + 1, sizeof(unsigned char));
-    memcpy(argv[i], x, x_len);
-    argv_lens[i] = x_len;
-    argv_types[i] = x_type;
+    if (!x_type || !x || !x_len)
+      continue;
+
+    argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
+    memcpy(argv[k], x, x_len);
+    argv_lens[k] = x_len;
+    argv_types[k] = x_type;
+    k++;
   }
 
   }
 
-  buffer = silc_command_payload_encode(cmd, argc, argv
-                                      argv_lens, argv_types, ident);
+  buffer = silc_command_payload_encode(cmd, k, argv, argv_lens
+                                      argv_types, ident);
 
 
-  for (i = 0; i < argc; i++)
+  for (i = 0; i < k; i++)
     silc_free(argv[i]);
   silc_free(argv);
   silc_free(argv_lens);
     silc_free(argv[i]);
   silc_free(argv);
   silc_free(argv_lens);
@@ -238,27 +242,31 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
   unsigned int x_len;
   unsigned int x_type;
   SilcBuffer buffer;
   unsigned int x_len;
   unsigned int x_type;
   SilcBuffer buffer;
-  int i;
+  int i, k;
 
   argv = silc_calloc(argc, sizeof(unsigned char *));
   argv_lens = silc_calloc(argc, sizeof(unsigned int));
   argv_types = silc_calloc(argc, sizeof(unsigned int));
 
 
   argv = silc_calloc(argc, sizeof(unsigned char *));
   argv_lens = silc_calloc(argc, sizeof(unsigned int));
   argv_types = silc_calloc(argc, sizeof(unsigned int));
 
-  for (i = 0; i < argc; i++) {
+  for (i = 0, k = 0; i < argc; i++) {
     x_type = va_arg(ap, unsigned int);
     x = va_arg(ap, unsigned char *);
     x_len = va_arg(ap, unsigned int);
 
     x_type = va_arg(ap, unsigned int);
     x = va_arg(ap, unsigned char *);
     x_len = va_arg(ap, unsigned int);
 
-    argv[i] = silc_calloc(x_len + 1, sizeof(unsigned char));
-    memcpy(argv[i], x, x_len);
-    argv_lens[i] = x_len;
-    argv_types[i] = x_type;
+    if (!x_type || !x || !x_len)
+      continue;
+
+    argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
+    memcpy(argv[k], x, x_len);
+    argv_lens[k] = x_len;
+    argv_types[k] = x_type;
+    k++;
   }
 
   }
 
-  buffer = silc_command_payload_encode(cmd, argc, argv
-                                      argv_lens, argv_types, ident);
+  buffer = silc_command_payload_encode(cmd, k, argv, argv_lens
+                                      argv_types, ident);
 
 
-  for (i = 0; i < argc; i++)
+  for (i = 0; i < k; i++)
     silc_free(argv[i]);
   silc_free(argv);
   silc_free(argv_lens);
     silc_free(argv[i]);
   silc_free(argv);
   silc_free(argv_lens);
@@ -286,7 +294,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
   unsigned int x_len;
   unsigned int x_type;
   SilcBuffer buffer;
   unsigned int x_len;
   unsigned int x_type;
   SilcBuffer buffer;
-  int i;
+  int i, k;
 
   va_start(ap, argc);
 
 
   va_start(ap, argc);
 
@@ -301,21 +309,25 @@ silc_command_reply_payload_encode_va(SilcCommand cmd,
   argv_lens[0] = sizeof(status_data);
   argv_types[0] = 1;
 
   argv_lens[0] = sizeof(status_data);
   argv_types[0] = 1;
 
-  for (i = 1; i < argc; i++) {
+  for (i = 1, k = 1; i < argc; i++) {
     x_type = va_arg(ap, unsigned int);
     x = va_arg(ap, unsigned char *);
     x_len = va_arg(ap, unsigned int);
 
     x_type = va_arg(ap, unsigned int);
     x = va_arg(ap, unsigned char *);
     x_len = va_arg(ap, unsigned int);
 
-    argv[i] = silc_calloc(x_len + 1, sizeof(unsigned char));
-    memcpy(argv[i], x, x_len);
-    argv_lens[i] = x_len;
-    argv_types[i] = x_type;
+    if (!x_type || !x || !x_len)
+      continue;
+
+    argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
+    memcpy(argv[k], x, x_len);
+    argv_lens[k] = x_len;
+    argv_types[k] = x_type;
+    k++;
   }
 
   }
 
-  buffer = silc_command_payload_encode(cmd, argc, argv
-                                      argv_lens, argv_types, ident);
+  buffer = silc_command_payload_encode(cmd, k, argv, argv_lens
+                                      argv_types, ident);
 
 
-  for (i = 0; i < argc; i++)
+  for (i = 0; i < k; i++)
     silc_free(argv[i]);
   silc_free(argv);
   silc_free(argv_lens);
     silc_free(argv[i]);
   silc_free(argv);
   silc_free(argv_lens);
index d1e739b18e2862f1b18310174b796dde5610bda6..d8f80ca25d28024cd7efd44a343724fd2bfeed56 100644 (file)
@@ -83,27 +83,31 @@ SilcBuffer silc_notify_payload_encode(SilcNotifyType type, unsigned int argc,
   unsigned int *argv_lens = NULL, *argv_types = NULL;
   unsigned char *x;
   unsigned int x_len;
   unsigned int *argv_lens = NULL, *argv_types = NULL;
   unsigned char *x;
   unsigned int x_len;
-  int i, len = 0;
+  int i, k, len = 0;
 
   if (argc) {
     argv = silc_calloc(argc, sizeof(unsigned char *));
     argv_lens = silc_calloc(argc, sizeof(unsigned int));
     argv_types = silc_calloc(argc, sizeof(unsigned int));
     
 
   if (argc) {
     argv = silc_calloc(argc, sizeof(unsigned char *));
     argv_lens = silc_calloc(argc, sizeof(unsigned int));
     argv_types = silc_calloc(argc, sizeof(unsigned int));
     
-    for (i = 0; i < argc; i++) {
+    for (i = 0, k = 0; i < argc; i++) {
       x = va_arg(ap, unsigned char *);
       x_len = va_arg(ap, unsigned int);
       x = va_arg(ap, unsigned char *);
       x_len = va_arg(ap, unsigned int);
+
+      if (!x || !x_len)
+       continue;
       
       
-      argv[i] = silc_calloc(x_len + 1, sizeof(unsigned char));
-      memcpy(argv[i], x, x_len);
-      argv_lens[i] = x_len;
-      argv_types[i] = i + 1;
+      argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
+      memcpy(argv[k], x, x_len);
+      argv_lens[k] = x_len;
+      argv_types[k] = i + 1;
+      k++;
     }
 
     }
 
-    args = silc_argument_payload_encode(argc, argv, argv_lens, argv_types);
+    args = silc_argument_payload_encode(k, argv, argv_lens, argv_types);
     len = args->len;
 
     len = args->len;
 
-    for (i = 0; i < argc; i++)
+    for (i = 0; i < k; i++)
       silc_free(argv[i]);
     silc_free(argv);
     silc_free(argv_lens);
       silc_free(argv[i]);
     silc_free(argv);
     silc_free(argv_lens);
@@ -116,10 +120,10 @@ SilcBuffer silc_notify_payload_encode(SilcNotifyType type, unsigned int argc,
   silc_buffer_format(buffer,
                     SILC_STR_UI_SHORT(type),
                     SILC_STR_UI_SHORT(len),
   silc_buffer_format(buffer,
                     SILC_STR_UI_SHORT(type),
                     SILC_STR_UI_SHORT(len),
-                    SILC_STR_UI_CHAR(argc),
+                    SILC_STR_UI_CHAR(k),
                     SILC_STR_END);
 
                     SILC_STR_END);
 
-  if (argc) {
+  if (k) {
     silc_buffer_pull(buffer, 5);
     silc_buffer_format(buffer,
                       SILC_STR_UI_XNSTRING(args->data, args->len),
     silc_buffer_pull(buffer, 5);
     silc_buffer_format(buffer,
                       SILC_STR_UI_XNSTRING(args->data, args->len),
index c6d9dd308a4eb205a48874bf21e3c8fb2f6278ac..ba4b9cc7bcbd39226373bb6d0a492d55714143cb 100644 (file)
@@ -602,26 +602,21 @@ int silc_string_compare(char *string1, char *string2)
 }
 
 /* Inspects the `string' for wildcards and returns regex string that can
 }
 
 /* Inspects the `string' for wildcards and returns regex string that can
-   be used by the GNU regex library. This has a lot overhead but luckily
-   this is used only for short strings. */
+   be used by the GNU regex library. A comma (`,') in the `string' means
+   that the string is list. */
 
 char *silc_string_regexify(const char *string)
 {
   int i, len, count;
   char *regex;
 
 
 char *silc_string_regexify(const char *string)
 {
   int i, len, count;
   char *regex;
 
-  /* If there is no wildcards then we don't need to regexify the string. */
-  if (!strchr(string, '*') && !strchr(string, '?'))
-    return strdup(string);
-
   len = strlen(string);
   len = strlen(string);
-  count = 0;
-
+  count = 4;
   for (i = 0; i < len; i++)
     if (string[i] == '*' || string[i] == '?')
       count++;
 
   for (i = 0; i < len; i++)
     if (string[i] == '*' || string[i] == '?')
       count++;
 
-  regex = silc_calloc(len + count + 4, sizeof(*regex));
+  regex = silc_calloc(len + count, sizeof(*regex));
 
   count = 0;
   regex[count] = '(';
 
   count = 0;
   regex[count] = '(';
@@ -631,6 +626,10 @@ char *silc_string_regexify(const char *string)
     if (string[i] == '*' || string[i] == '?') {
       regex[count] = '.';
       count++;
     if (string[i] == '*' || string[i] == '?') {
       regex[count] = '.';
       count++;
+    } else if (string[i] == ',') {
+      regex[count] = '|';
+      count++;
+      continue;
     }
 
     regex[count] = string[i];
     }
 
     regex[count] = string[i];
@@ -656,9 +655,9 @@ char *silc_string_regex_combine(const char *string1, const char *string2)
   len2 = strlen(string2);
 
   tmp = silc_calloc(2 + len1 + len2, sizeof(*tmp));
   len2 = strlen(string2);
 
   tmp = silc_calloc(2 + len1 + len2, sizeof(*tmp));
-  memcpy(tmp, string1, len1 - 2);
-  memcpy(tmp, "|", 1);
-  memcpy(tmp, string2 + 1, len2 - 1);
+  strncat(tmp, string1, len1 - 2);
+  strncat(tmp, "|", 1);
+  strncat(tmp, string2 + 1, len2 - 1);
 
   return tmp;
 }
 
   return tmp;
 }
@@ -680,3 +679,18 @@ int silc_string_regex_match(const char *regex, const char *string)
 
   return ret;
 }
 
   return ret;
 }
+
+/* Do regex match to the two strings `string1' and `string2'. If the
+   `string2' matches the `string1' this returns TRUE. */
+
+int silc_string_match(const char *string1, const char *string2)
+{
+  char *s1;
+  int ret = FALSE;
+
+  s1 = silc_string_regexify(string1);
+  ret = silc_string_regex_match(s1, string2);
+  silc_free(s1);
+
+  return ret;
+}
index d58909e03b14116408e1966b8e076155b01698b6..dc6196769afef3667dfc29d98b4780d50da74e70 100644 (file)
@@ -47,5 +47,6 @@ char *silc_id_render(void *id, unsigned short type);
 int silc_string_compare(char *string1, char *string2);
 char *silc_string_regexify(const char *string);
 int silc_string_regex_match(const char *regex, const char *string);
 int silc_string_compare(char *string1, char *string2);
 char *silc_string_regexify(const char *string);
 int silc_string_regex_match(const char *regex, const char *string);
+int silc_string_match(const char *string1, const char *string2);
 
 #endif
 
 #endif