updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 20 Mar 2001 13:19:34 +0000 (13:19 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 20 Mar 2001 13:19:34 +0000 (13:19 +0000)
17 files changed:
CHANGES
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/server.c
apps/silcd/server.h
apps/silcd/testi2.conf
doc/draft-riikonen-silc-pp-01.nroff
doc/draft-riikonen-silc-spec-01.nroff
lib/silcclient/client_channel.c
lib/silcclient/command_reply.c
lib/silccore/silcchannel.c
lib/silccore/silcchannel.h
lib/silccore/silcnotify.h

diff --git a/CHANGES b/CHANGES
index 35c817a551d05ba9ce1b349c2f09c37e1411d556..bf6e1b945e6b10e2b506fd8b09964fdac59c279e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,42 @@
+Tue Mar 20 15:45:14 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Added new notify type SILC_NOTIFY_TYPE_UMODE_CHANGE that is
+         used by routers as broadcast packet to inform other routers
+         about the changed user mode.
+
+         Implemented the notify handling in the server.  Affected file is
+         silcd/packet_receive.c.  Added the function 
+         silc_server_send_notify_umode to the silcd/packet_send.[ch].
+
+       * Added new generic Channel Payload and deprecated the New Channel
+         Payload.  The New Channel Payload is now the generic Channel
+         Payload.
+
+       * Added new argument `mode' to the silc_server_send_new_channel
+         as it is required in the Channel Payload now.
+
+       * Renamed the SilcChannelPayload to SilcChannelMessagePayload
+         and created a new and real SilChannelPayload to represent the
+         new generic Channel Payload.  Implemented the encode/decode
+         for Channel Payload.  Affected file lib/silccore/silcchannel.[ch].
+
+       * Added silc_server_get_client_channel_list to return the list
+         of channels the client has joined for WHOIS command reply.
+         Affected file silcd/server.[ch].
+
+       * Implemented the channel list sending in the WHOIS command reply
+         in server and in the client.
+
+         Implemented the channel list displaying on the user interface
+         as well.  Affected file silc/client_ops.c.
+
+       * Added silc_channel_payload_parse_list to parse list of Channel
+         Payloads.  It returns SilcDList list of SilcChannelPayloads.
+         Client for example can use this function to parse the list of
+         channels it receives in the WHOIS command reply.  The caller
+         must free the list by calling silc_channel_payload_list_free.
+         Affected files lib/silccore/silcchannel.[ch].
+
 Mon Mar 19 21:39:15 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Added one new argument <user mode> to the WHOIS command reply
index e7c3b7f655beb289a9c5710ae85903e3e238d374..2c3ac83d07cbc639a619e697b009cdfc0b5482f1 100644 (file)
@@ -411,6 +411,7 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
        char buf[1024], *nickname, *username, *realname;
        int len;
        unsigned int idle, mode;
+       SilcBuffer channels;
 
        if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
          char *tmp;
@@ -432,7 +433,7 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
        nickname = va_arg(vp, char *);
        username = va_arg(vp, char *);
        realname = va_arg(vp, char *);
-       (void)va_arg(vp, void *);
+       channels = va_arg(vp, SilcBuffer);
        mode = va_arg(vp, unsigned int);
        idle = va_arg(vp, unsigned int);
 
@@ -456,6 +457,32 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
 
        client->ops->say(client, conn, "%s", buf);
 
+       if (channels) {
+         SilcDList list = silc_channel_payload_parse_list(channels);
+         if (list) {
+           SilcChannelPayload entry;
+
+           memset(buf, 0, sizeof(buf));
+           strcat(buf, "on channels: ");
+
+           silc_dlist_start(list);
+           while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
+             char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
+             unsigned int name_len;
+             char *name = silc_channel_get_name(entry, &name_len);
+
+             if (m)
+               strncat(buf, m, strlen(m));
+             strncat(buf, name, name_len);
+             strncat(buf, " ", 1);
+             silc_free(m);
+           }
+
+           client->ops->say(client, conn, "%s", buf);
+           silc_channel_payload_list_free(list);
+         }
+       }
+
        if (mode)
          client->ops->say(client, conn, "%s is %s", nickname,
                           (mode & SILC_UMODE_SERVER_OPERATOR) ?
index 1a8e7d628e4222655de1061730730076639d7662..146c96a7efbcd1731217d5f3b16dbc15fedc5c62 100644 (file)
@@ -529,7 +529,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
   SilcServer server = cmd->server;
   char *tmp;
   int i, count = 0, len;
-  SilcBuffer packet, idp;
+  SilcBuffer packet, idp, channels;
   SilcClientEntry entry;
   SilcCommandStatus status;
   unsigned short ident = silc_command_get_ident(cmd->payload);
@@ -591,28 +591,45 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
       len = strlen(hsock->hostname);
       strncat(uh, hsock->hostname, len);
     }
+
+    channels = silc_server_get_client_channel_list(server, entry);
       
+    SILC_PUT32_MSB(entry->mode, mode);
+
     if (entry->connection) {
       SILC_PUT32_MSB((time(NULL) - entry->data.last_receive), idle);
     }
 
-    SILC_PUT32_MSB(entry->mode, mode);
-
-    packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
-                                                 status, ident, 6, 
-                                                 2, idp->data, idp->len,
-                                                 3, nh, strlen(nh),
-                                                 4, uh, strlen(uh),
-                                                 5, entry->userinfo, 
-                                                 strlen(entry->userinfo),
-                                                 7, mode, 4,
-                                                 8, idle, 4);
+    if (channels)
+      packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
+                                                   status, ident, 7, 
+                                                   2, idp->data, idp->len,
+                                                   3, nh, strlen(nh),
+                                                   4, uh, strlen(uh),
+                                                   5, entry->userinfo, 
+                                                   strlen(entry->userinfo),
+                                                   6, channels->data,
+                                                   channels->len,
+                                                   7, mode, 4,
+                                                   8, idle, 4);
+    else
+      packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS,
+                                                   status, ident, 6, 
+                                                   2, idp->data, idp->len,
+                                                   3, nh, strlen(nh),
+                                                   4, uh, strlen(uh),
+                                                   5, entry->userinfo, 
+                                                   strlen(entry->userinfo),
+                                                   7, mode, 4,
+                                                   8, idle, 4);
     
     silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY,
                            0, packet->data, packet->len, FALSE);
     
     silc_buffer_free(packet);
     silc_buffer_free(idp);
+    if (channels)
+      silc_buffer_free(channels);
   }
 }
 
@@ -2697,6 +2714,12 @@ SILC_SERVER_CMD_FUNC(umode)
       client->mode &= ~SILC_UMODE_ROUTER_OPERATOR;
   }
 
+  /* Send UMODE change to primary router */
+  if (!server->standalone)
+    silc_server_send_notify_umode(server, server->router->connection, TRUE,
+                                 client->id, SILC_ID_CLIENT_LEN,
+                                 client->mode);
+
   /* Send command reply to sender */
   packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
                                                SILC_STATUS_OK, ident, 1,
@@ -3554,6 +3577,12 @@ SILC_SERVER_CMD_FUNC(oper)
   /* Client is now server operator */
   client->mode |= SILC_UMODE_SERVER_OPERATOR;
 
+  /* Send UMODE change to primary router */
+  if (!server->standalone)
+    silc_server_send_notify_umode(server, server->router->connection, TRUE,
+                                 client->id, SILC_ID_CLIENT_LEN,
+                                 client->mode);
+
   /* Send reply to the sender */
   silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
                                        SILC_STATUS_OK);
@@ -3621,6 +3650,12 @@ SILC_SERVER_CMD_FUNC(silcoper)
   /* Client is now router operator */
   client->mode |= SILC_UMODE_ROUTER_OPERATOR;
 
+  /* Send UMODE change to primary router */
+  if (!server->standalone)
+    silc_server_send_notify_umode(server, server->router->connection, TRUE,
+                                 client->id, SILC_ID_CLIENT_LEN,
+                                 client->mode);
+
   /* Send reply to the sender */
   silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
                                        SILC_STATUS_OK);
@@ -3670,9 +3705,8 @@ SILC_SERVER_CMD_FUNC(connect)
 
   /* Get port */
   tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
-  if (tmp) {
+  if (tmp)
     SILC_GET32_MSB(port, tmp);
-  }
 
   /* Create the connection. It is done with timeout and is async. */
   silc_server_create_connection(server, host, port);
@@ -3725,9 +3759,8 @@ SILC_SERVER_CMD_FUNC(close)
 
   /* Get port */
   tmp = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
-  if (tmp) {
+  if (tmp)
     SILC_GET32_MSB(port, tmp);
-  }
 
   server_entry = silc_idlist_find_server_by_conn(server->local_list,
                                                 name, port, NULL);
index 1ff8818f2839d1ffbd6c85f006ee76ba302d70f8..45d0c4604aebce157c205072a97a93c56d430b24 100644 (file)
@@ -150,10 +150,8 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
   }
 
   tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
-  if (tmp) {
+  if (tmp)
     SILC_GET32_MSB(mode, tmp);
-  }
-
 
   client_id = silc_id_payload_parse_id(id_data, id_len);
   if (!client_id)
index 2a40208bc9616c73d89294ede1cf0c8d1c467338..e01f55f64ff58bbb8fdca196ee189299cce74124 100644 (file)
@@ -108,10 +108,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get channel entry */
-    channel = silc_idlist_find_channel_by_id(server->local_list, 
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
                                             channel_id, NULL);
     if (!channel) {
-      channel = silc_idlist_find_channel_by_id(server->global_list, 
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -136,10 +136,10 @@ void silc_server_notify(SilcServer server,
     /* If the the client is not in local list we check global list (ie. the
        channel will be global channel) and if it does not exist then create
        entry for the client. */
-    client = silc_idlist_find_client_by_id(server->local_list, 
+    client = silc_idlist_find_client_by_id(server->global_list, 
                                           client_id, NULL);
     if (!client) {
-      client = silc_idlist_find_client_by_id(server->global_list, 
+      client = silc_idlist_find_client_by_id(server->local_list, 
                                             client_id, NULL);
       if (!client) {
        /* If router did not find the client the it is bogus */
@@ -189,10 +189,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get channel entry */
-    channel = silc_idlist_find_channel_by_id(server->local_list, 
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
                                             channel_id, NULL);
     if (!channel) { 
-      channel = silc_idlist_find_channel_by_id(server->global_list, 
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -288,10 +288,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get channel entry */
-    channel = silc_idlist_find_channel_by_id(server->local_list, 
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
                                             channel_id, NULL);
     if (!channel) {
-      channel = silc_idlist_find_channel_by_id(server->global_list, 
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -389,10 +389,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get channel entry */
-    channel = silc_idlist_find_channel_by_id(server->local_list, 
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
                                             channel_id, NULL);
     if (!channel) {
-      channel = silc_idlist_find_channel_by_id(server->global_list, 
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -432,10 +432,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get channel entry */
-    channel = silc_idlist_find_channel_by_id(server->local_list, 
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
                                             channel_id, NULL);
     if (!channel) {
-      channel = silc_idlist_find_channel_by_id(server->global_list, 
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -514,10 +514,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get channel entry */
-    channel = silc_idlist_find_channel_by_id(server->local_list, 
+    channel = silc_idlist_find_channel_by_id(server->global_list, 
                                             channel_id, NULL);
     if (!channel) {
-      channel = silc_idlist_find_channel_by_id(server->global_list, 
+      channel = silc_idlist_find_channel_by_id(server->local_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -540,10 +540,10 @@ void silc_server_notify(SilcServer server,
                                       packet->buffer->len, FALSE);
 
     /* If the the client is not in local list we check global list */
-    client = silc_idlist_find_client_by_id(server->local_list, 
+    client = silc_idlist_find_client_by_id(server->global_list, 
                                           client_id, NULL);
     if (!client) {
-      client = silc_idlist_find_client_by_id(server->global_list, 
+      client = silc_idlist_find_client_by_id(server->local_list, 
                                             client_id, NULL);
       if (!client) {
        silc_free(client_id);
@@ -575,10 +575,10 @@ void silc_server_notify(SilcServer server,
        goto out;
 
       /* If the the client is not in local list we check global list */
-      client = silc_idlist_find_client_by_id(server->local_list, 
+      client = silc_idlist_find_client_by_id(server->global_list, 
                                             client_id, NULL);
       if (!client) {
-       client = silc_idlist_find_client_by_id(server->global_list, 
+       client = silc_idlist_find_client_by_id(server->local_list, 
                                               client_id, NULL);
        if (!client) {
          silc_free(client_id);
@@ -617,6 +617,44 @@ void silc_server_notify(SilcServer server,
       break;
     }
 
+  case SILC_NOTIFY_TYPE_UMODE_CHANGE:
+    /*
+     * Save the mode of the client.
+     */
+
+    SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
+      
+    /* Get client ID */
+    tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
+    if (!tmp)
+      goto out;
+    client_id = silc_id_payload_parse_id(tmp, tmp_len);
+    if (!client_id)
+      goto out;
+
+    /* Get client entry */
+    client = silc_idlist_find_client_by_id(server->global_list, 
+                                          client_id, NULL);
+    if (!client) {
+      client = silc_idlist_find_client_by_id(server->local_list, 
+                                            client_id, NULL);
+      if (!client) {
+       silc_free(client_id);
+       goto out;
+      }
+    }
+    silc_free(client_id);
+
+    /* Get the mode */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+    if (!tmp)
+      goto out;
+
+    /* Save the mode */
+    SILC_GET32_MSB(client->mode, tmp);
+
+    break;
+
     /* Ignore rest of the notify types for now */
   case SILC_NOTIFY_TYPE_NONE:
   case SILC_NOTIFY_TYPE_MOTD:
@@ -892,10 +930,11 @@ void silc_server_channel_message(SilcServer server,
     
     /* Encode new payload. This encrypts it also. */
     SILC_GET16_MSB(data_len, packet->buffer->data);
-    chp = silc_channel_payload_encode(data_len, packet->buffer->data + 2,
-                                     iv_len, channel->iv,
-                                     channel->channel_key,
-                                     channel->hmac, server->rng);
+    chp = silc_channel_message_payload_encode(data_len, 
+                                             packet->buffer->data + 2,
+                                             iv_len, channel->iv,
+                                             channel->channel_key,
+                                             channel->hmac, server->rng);
     silc_buffer_put(packet->buffer, chp->data, chp->len);
     silc_buffer_free(chp);
   }
@@ -1397,11 +1436,12 @@ void silc_server_new_channel(SilcServer server,
                             SilcSocketConnection sock,
                             SilcPacketContext *packet)
 {
-  unsigned char *id;
+  SilcChannelPayload payload;
   SilcChannelID *channel_id;
-  unsigned short channel_id_len;
   char *channel_name;
-  int ret;
+  unsigned int name_len;
+  unsigned char *id;
+  unsigned int id_len;
 
   SILC_LOG_DEBUG(("Processing New Channel"));
 
@@ -1410,23 +1450,23 @@ void silc_server_new_channel(SilcServer server,
       server->server_type == SILC_SERVER)
     return;
 
-  /* Parse payload */
-  ret = silc_buffer_unformat(packet->buffer, 
-                            SILC_STR_UI16_STRING_ALLOC(&channel_name),
-                            SILC_STR_UI16_NSTRING_ALLOC(&id, &channel_id_len),
-                            SILC_STR_END);
-  if (ret == -1) {
-    if (channel_name)
-      silc_free(channel_name);
-    if (id)
-      silc_free(id);
+  /* Parse the channel payload */
+  payload = silc_channel_payload_parse(packet->buffer);
+  if (!payload)
     return;
-  }
     
-  /* Decode the channel ID */
-  channel_id = silc_id_str2id(id, channel_id_len, SILC_ID_CHANNEL);
-  if (!channel_id)
+  /* Get the channel ID */
+  channel_id = silc_channel_get_id_parse(payload);
+  if (!channel_id) {
+    silc_channel_payload_free(payload);
     return;
+  }
+
+  channel_name = silc_channel_get_name(payload, &name_len);
+  if (name_len > 256)
+    channel_name[255] = '\0';
+
+  id = silc_channel_get_id(payload, &id_len);
 
   if (sock->type == SILC_SOCKET_TYPE_ROUTER) {
     /* Add the server to global list as it is coming from router. It 
@@ -1436,8 +1476,9 @@ void silc_server_new_channel(SilcServer server,
                    silc_id_render(channel_id, SILC_ID_CHANNEL), 
                    sock->hostname));
     
-    silc_idlist_add_channel(server->global_list, channel_name, 0, channel_id, 
-                           server->router->connection, NULL, NULL);
+    silc_idlist_add_channel(server->global_list, strdup(channel_name), 
+                           0, channel_id, server->router->connection, 
+                           NULL, NULL);
 
     server->stat.channels++;
   } else {
@@ -1464,11 +1505,14 @@ void silc_server_new_channel(SilcServer server,
       channel = silc_server_create_new_channel_with_id(server, NULL, NULL,
                                                       channel_name,
                                                       channel_id, FALSE);
-      if (!channel)
+      if (!channel) {
+       silc_channel_payload_free(payload);
+       silc_free(channel_id);
        return;
+      }
 
       /* Send the new channel key to the server */
-      chk = silc_channel_key_payload_encode(channel_id_len, id,
+      chk = silc_channel_key_payload_encode(id_len, id,
                                            strlen(channel->channel_key->
                                                   cipher->name),
                                            channel->channel_key->cipher->name,
@@ -1502,7 +1546,7 @@ void silc_server_new_channel(SilcServer server,
       silc_server_send_channel_key(server, sock, channel, FALSE);
 
       /* Send to the server */
-      chk = silc_channel_key_payload_encode(channel_id_len, id,
+      chk = silc_channel_key_payload_encode(id_len, id,
                                            strlen(channel->channel_key->
                                                   cipher->name),
                                            channel->channel_key->cipher->name,
@@ -1511,6 +1555,7 @@ void silc_server_new_channel(SilcServer server,
       silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, 
                              chk->data, chk->len, FALSE);
       silc_buffer_free(chk);
+      silc_free(channel_id);
 
       /* Since the channel is coming from server and we also know about it
         then send the JOIN notify to the server so that it see's our
@@ -1518,8 +1563,6 @@ void silc_server_new_channel(SilcServer server,
       /* XXX TODO **/
     }
   }
-
-  silc_free(id);
 }
 
 /* Received New Channel List packet, list of New Channel List payloads inside
@@ -1579,14 +1622,14 @@ void silc_server_new_channel_list(SilcServer server,
        (len2 > buffer->truelen))
       break;
 
-    silc_buffer_pull_tail(buffer, 4 + len1 + len2);
-    silc_buffer_put(buffer, packet->buffer->data, 4 + len1 + len2);
+    silc_buffer_pull_tail(buffer, 8 + len1 + len2);
+    silc_buffer_put(buffer, packet->buffer->data, 8 + len1 + len2);
 
     /* Process the New Channel */
     silc_server_new_channel(server, sock, new);
 
-    silc_buffer_push_tail(buffer, 4 + len1 + len2);
-    silc_buffer_pull(packet->buffer, 4 + len1 + len2);
+    silc_buffer_push_tail(buffer, 8 + len1 + len2);
+    silc_buffer_pull(packet->buffer, 8 + len1 + len2);
   }
 
   silc_buffer_free(buffer);
index 4476c4dfb8b689bd6196ff801e4b2cd0b2699238..7cd1767981447910a54c47e52a9d3c840c0afad8 100644 (file)
@@ -655,9 +655,9 @@ void silc_server_packet_relay_to_channel(SilcServer server,
            memcpy(tmp, data, data_len);
 
            /* Decrypt the channel message (we don't check the MAC) */
-           if (!silc_channel_payload_decrypt(tmp, data_len, 
-                                             channel->channel_key,
-                                             NULL)) {
+           if (!silc_channel_message_payload_decrypt(tmp, data_len, 
+                                                     channel->channel_key,
+                                                     NULL)) {
              memset(tmp, 0, data_len);
              silc_free(tmp);
              continue;
@@ -1101,6 +1101,30 @@ void silc_server_send_notify_killed(SilcServer server,
   silc_buffer_free(idp);
 }
 
+/* Sends UMODE_CHANGE notify type. This tells that `client_id' client's
+   user mode in the SILC Network was changed. This function is used to
+   send the packet between routers as broadcast packet. */
+
+void silc_server_send_notify_umode(SilcServer server,
+                                  SilcSocketConnection sock,
+                                  int broadcast,
+                                  SilcClientID *client_id,
+                                  unsigned int client_id_len,
+                                  unsigned int mode_mask)
+{
+  SilcBuffer idp;
+  unsigned char mode[4];
+
+  idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT);
+  SILC_PUT32_MSB(mode_mask, mode);
+
+  silc_server_send_notify(server, sock, broadcast,
+                         SILC_NOTIFY_TYPE_UMODE_CHANGE, 2,
+                         idp->data, idp->len, 
+                         mode, 4);
+  silc_buffer_free(idp);
+}
+
 /* Sends notify message destined to specific entity. */
 
 void silc_server_send_notify_dest(SilcServer server,
@@ -1329,7 +1353,8 @@ void silc_server_send_new_channel(SilcServer server,
                                  int broadcast,
                                  char *channel_name,
                                  void *channel_id, 
-                                 unsigned int channel_id_len)
+                                 unsigned int channel_id_len,
+                                 unsigned int mode)
 {
   SilcBuffer packet;
   unsigned char *cid;
@@ -1341,15 +1366,9 @@ void silc_server_send_new_channel(SilcServer server,
   if (!cid)
     return;
 
-  packet = silc_buffer_alloc(2 + 2 + name_len + channel_id_len);
-  silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
-  silc_buffer_format(packet,
-                    SILC_STR_UI_SHORT(name_len),
-                    SILC_STR_UI_XNSTRING(channel_name, name_len),
-                    SILC_STR_UI_SHORT(channel_id_len),
-                    SILC_STR_UI_XNSTRING(cid, channel_id_len),
-                    SILC_STR_END);
-
+  /* Encode the channel payload */
+  packet = silc_channel_payload_encode(channel_name, name_len,
+                                      cid, channel_id_len, mode);
 
   silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL, 
                          broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, 
index 49520c84dbf8bb32b5e83aad06e0d3fbf2324c43..29b349286c0f8baee00e9812aae211bcceec8f1a 100644 (file)
@@ -168,6 +168,12 @@ void silc_server_send_notify_killed(SilcServer server,
                                    SilcClientID *client_id,
                                    unsigned int client_id_len,
                                    char *comment);
+void silc_server_send_notify_umode(SilcServer server,
+                                  SilcSocketConnection sock,
+                                  int broadcast,
+                                  SilcClientID *client_id,
+                                  unsigned int client_id_len,
+                                  unsigned int mode_mask);
 void silc_server_send_notify_dest(SilcServer server,
                                  SilcSocketConnection sock,
                                  int broadcast,
@@ -196,7 +202,8 @@ void silc_server_send_new_channel(SilcServer server,
                                  int broadcast,
                                  char *channel_name,
                                  void *channel_id, 
-                                 unsigned int channel_id_len);
+                                 unsigned int channel_id_len,
+                                 unsigned int mode);
 void silc_server_send_channel_key(SilcServer server,
                                  SilcSocketConnection sender,
                                  SilcChannelEntry channel,
index 34f7326fb878175055654fc62f1dbbd84b807d86..87ceee969f2f9c2fc469e7e4ab93f195d0d15692 100644 (file)
@@ -2460,10 +2460,10 @@ SilcChannelEntry silc_server_create_new_channel(SilcServer server,
 
   /* Notify other routers about the new channel. We send the packet
      to our primary route. */
-  if (broadcast && server->standalone == FALSE) {
+  if (broadcast && server->standalone == FALSE)
     silc_server_send_new_channel(server, server->router->connection, TRUE, 
-                                channel_name, entry->id, SILC_ID_CHANNEL_LEN);
-  }
+                                channel_name, entry->id, SILC_ID_CHANNEL_LEN,
+                                entry->mode);
 
   server->stat.my_channels++;
 
@@ -2518,10 +2518,10 @@ silc_server_create_new_channel_with_id(SilcServer server,
 
   /* Notify other routers about the new channel. We send the packet
      to our primary route. */
-  if (broadcast && server->standalone == FALSE) {
+  if (broadcast && server->standalone == FALSE)
     silc_server_send_new_channel(server, server->router->connection, TRUE, 
-                                channel_name, entry->id, SILC_ID_CHANNEL_LEN);
-  }
+                                channel_name, entry->id, SILC_ID_CHANNEL_LEN,
+                                entry->mode);
 
   server->stat.my_channels++;
 
@@ -2861,7 +2861,7 @@ static void silc_server_announce_get_channels(SilcServer server,
        cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
        name_len = strlen(channel->channel_name);
 
-       len = 4 + name_len + SILC_ID_CHANNEL_LEN;
+       len = 4 + name_len + SILC_ID_CHANNEL_LEN + 4;
        *channels = 
          silc_buffer_realloc(*channels, 
                              (*channels ? (*channels)->truelen + len : len));
@@ -2873,6 +2873,7 @@ static void silc_server_announce_get_channels(SilcServer server,
                                                name_len),
                           SILC_STR_UI_SHORT(SILC_ID_CHANNEL_LEN),
                           SILC_STR_UI_XNSTRING(cid, SILC_ID_CHANNEL_LEN),
+                          SILC_STR_UI_INT(0),
                           SILC_STR_END);
        silc_buffer_pull(*channels, len);
 
@@ -3174,3 +3175,46 @@ SilcSocketConnection silc_server_get_client_route(SilcServer server,
   silc_free(id);
   return NULL;
 }
+
+/* Encodes and returns channel list of channels the `client' has joined.
+   Secret channels are not put to the list. */
+
+SilcBuffer silc_server_get_client_channel_list(SilcServer server,
+                                              SilcClientEntry client)
+{
+  SilcBuffer buffer = NULL;
+  SilcChannelEntry channel;
+  SilcChannelClientEntry chl;
+  unsigned char *cid;
+  unsigned short name_len;
+  int len;
+
+  silc_list_start(client->channels);
+  while ((chl = silc_list_get(client->channels)) != SILC_LIST_END) {
+    channel = chl->channel;
+
+    if (channel->mode & SILC_CHANNEL_MODE_SECRET)
+      continue;
+
+    cid = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+    name_len = strlen(channel->channel_name);
+    
+    len = 4 + name_len + SILC_ID_CHANNEL_LEN + 4;
+    buffer = silc_buffer_realloc(buffer, 
+                                (buffer ? (buffer)->truelen + len : len));
+    silc_buffer_pull_tail(buffer, ((buffer)->end - (buffer)->data));
+    silc_buffer_format(buffer,
+                      SILC_STR_UI_SHORT(name_len),
+                      SILC_STR_UI_XNSTRING(channel->channel_name, 
+                                           name_len),
+                      SILC_STR_UI_SHORT(SILC_ID_CHANNEL_LEN),
+                      SILC_STR_UI_XNSTRING(cid, SILC_ID_CHANNEL_LEN),
+                      SILC_STR_UI_INT(chl->mode), /* Client's mode */
+                      SILC_STR_END);
+    silc_buffer_pull(buffer, len);
+    silc_free(cid);
+  }
+
+  silc_buffer_push(buffer, buffer->data - buffer->head);
+  return buffer;
+}
index 28a87518aeb05d7c2f1777dfb925c7338e32f306..d65394e138db120194b464248608ba9133838afc 100644 (file)
@@ -161,5 +161,7 @@ SilcSocketConnection silc_server_get_client_route(SilcServer server,
                                                  unsigned char *id_data,
                                                  unsigned int id_len,
                                                  SilcIDListData *idata);
+SilcBuffer silc_server_get_client_channel_list(SilcServer server,
+                                              SilcClientEntry client);
 
 #endif
index d0c7bbf22cc8343d38f39ca6be0e691ae675c096..9948361e405f855127b7d7c2bf085ffa4dbb1fa3 100644 (file)
@@ -1,23 +1,17 @@
 [Cipher]
-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
+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
 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
-hmac-sha1:sha1:20   
+hmac-sha1:sha1:20
 hmac-md5:md5:16
 
 #[PKCS]
@@ -31,10 +25,10 @@ nobody:nobody
 Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi
 
 [ServerInfo]
-lassi.kuo.fi.ssh.com:212.146.42.253:Kuopio, Finland:1334
+lassi.kuo.fi.ssh.com:10.2.1.7:Kuopio, Finland:1334
 
 [ListenPort]
-212.146.42.253:212.146.42.253:1334
+10.2.1.7:10.2.1.7:1334
 
 [Logging]
 infologfile:silcd2.log:10000
@@ -53,13 +47,13 @@ errorlogfile:silcd2.log:10000
 :::1336:1
 
 [AdminConnection]
-*:priikone:*:passwd:testi
+*:silc:silc:passwd:testi
 
 [ServerConnection]
-212.146.42.253:passwd:priikone:1336:1:1
+10.2.1.7:passwd:priikone:1333:1:1
 
 [RouterConnection]
-212.146.42.253:passwd:priikone:1335:1:1:0
+10.2.1.7:passwd:priikone:1335:1:1:0
 
 [DenyConnection]
 [RedirectClient]
index 2a1dd374e41beaf6e2563dd45158ff7d9d9c15ea..72cacb809c55d8b3c5617f76b8e141682fadeaf0 100644 (file)
@@ -80,6 +80,7 @@ Table of Contents
       2.3.2 Generic payloads .................................... 16
             2.3.2.1 ID Payload .................................. 16
             2.3.2.2 Argument Payload ............................ 16
+            2.3.2.3 Channel Payload ............................. XXX
       2.3.3 Disconnect Payload .................................. 17
       2.3.4 Success Payload ..................................... 18
       2.3.5 Failure Payload ..................................... 18
@@ -123,21 +124,23 @@ Figure 1:   Typical SILC Packet
 Figure 2:   SILC Packet Header
 Figure 3:   ID Payload
 Figure 4:   Argument Payload
-Figure 5:   Disconnect Payload
-Figure 6:   Success Payload
-Figure 7:   Failure Payload
-Figure 8:   Reject Payload
-Figure 9:   Notify Payload
-Figure 10:  Error Payload
-Figure 11:  Channel Message Payload
-Figure 12:  Channel Key Payload
-Figure 13:  Private Message Payload
-Figure 14:  Private Message Key Payload
-Figure 15:  Command Payload
-Figure 16:  Connection Auth Request Payload
-Figure 17:  New Client Payload
-Figure 18:  New Server Payload
-Figure 19:  New Channel Payload
+Figure 5:   Channel Payload
+Figure 6:   Disconnect Payload
+Figure 7:   Success Payload
+Figure 8:   Failure Payload
+Figure 9:   Reject Payload
+Figure 10:  Notify Payload
+Figure 11:  Error Payload
+Figure 12:  Channel Message Payload
+Figure 13:  Channel Key Payload
+Figure 14:  Private Message Payload
+Figure 15:  Private Message Key Payload
+Figure 16:  Command Payload
+Figure 17:  Connection Auth Request Payload
+Figure 18:  New Client Payload
+Figure 19:  New Server Payload
+Figure 20:  Key Agreement Payload
+Figure 21:  Cell Routers Payload
 
 
 .ti 0
@@ -833,6 +836,7 @@ the packet payload needing the arguments.  Incorrect amount of argument
 payloads must cause rejection of the packet.  The following diagram represents
 the Argument Payload.
 
+The following diagram represents the Argument Payload.
 
 .in 5
 .nf
@@ -868,6 +872,58 @@ o Argument Data (variable length) - Argument data.
 .in 3
 
 
+.ti 0
+2.3.2.3 Channel Payload
+
+Generic Channel Payload may be used information about channel, its name,
+the Channel ID and a mode.
+
+The following diagram represents the Channel Payload Payload.
+
+
+.in 5
+.nf
+                     1                   2                   3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|      Channel Name Length      |                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+|                                                               |
+~                         Channel Name                          ~
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|       Channel ID Length       |                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
+|                                                               |
+~                          Channel ID                           ~
+|                                                               |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+|                           Mode Mask                           |
++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+.in 3
+
+.ce
+Figure 5:  New Channel Payload
+
+
+.in 6
+o Channel Name Length (2 bytes) - Length of the channel name
+  field.
+
+o Channel Name (variable length) - The name of the channel.
+
+o Channel ID Length (2 bytes) - Length of the Channel ID field.
+
+o Channel ID (variable length) - The Channel ID.
+
+o Mode Mask (4 bytes) - A mode.  This can be the mode of the
+  channel but it can also be the mode of the client on the
+  channel.  The contents of this field is dependent of the
+  usage of this payload.  The usage is defined separately
+  when this payload is used.  This is a 32 bit MSB first value.
+.in 3
+
+
 .ti 0
 2.3.3 Disconnect Payload
 
@@ -896,7 +952,7 @@ the Disconnect Payload.
 .in 3
 
 .ce
-Figure 5:  Disconnect Payload
+Figure 6:  Disconnect Payload
 
 
 
@@ -926,7 +982,7 @@ This maybe any data, including binary or human readable data.
 .in 3
 
 .ce
-Figure 6:  Success Payload
+Figure 7:  Success Payload
 
 
 .in 6
@@ -958,7 +1014,7 @@ some protocol is sent in the payload.
 .in 3
 
 .ce
-Figure 7:  Failure Payload
+Figure 8:  Failure Payload
 
 
 .in 6
@@ -992,7 +1048,7 @@ may be binary or human readable data.
 .in 3
 
 .ce
-Figure 8:  Reject Payload
+Figure 9:  Reject Payload
 
 
 .in 6
@@ -1033,7 +1089,7 @@ Notify Payload.
 .in 3
 
 .ce
-Figure 9:  Notify Payload
+Figure 10:  Notify Payload
 
 
 .in 6
@@ -1245,6 +1301,18 @@ ID's sent in arguments are sent inside ID Payload.
       The killer may have set the <comment> to indicate the reason for
       the killing.
 
+
+14    SILC_NOTIFY_TYPE_UMODE_CHANGE
+
+      Sent when user's mode in the SILC changes.  This type is sent only
+      between routers as broadcast packet.
+
+      Max Arguments:  2
+          Arguments:  (1) <Client ID>  (2) <mode mask>
+
+      The <Client ID> is the client which mode was changed.  The <mode mask>
+      is the new mode mask.
+
 .in 3
 
 Notify types starting from 16384 are reserved for private notify
@@ -1274,7 +1342,7 @@ that the client takes error packet seriously.
 .in 3
 
 .ce
-Figure 10:  Error Payload
+Figure 11:  Error Payload
 
 
 .in 6
@@ -1349,7 +1417,7 @@ represents the Channel Message Payload.
 .in 3
 
 .ce
-Figure 11:  Channel Message Payload
+Figure 12:  Channel Message Payload
 
 
 .in 6
@@ -1459,7 +1527,7 @@ represents the Channel Key Payload.
 .in 3
 
 .ce
-Figure 12:  Channel Key Payload
+Figure 13:  Channel Key Payload
 
 
 
@@ -1537,7 +1605,7 @@ diagram represents the Private Message Payload.
 .in 3
 
 .ce
-Figure 13:  Private Message Payload
+Figure 14:  Private Message Payload
 
 
 .in 6
@@ -1597,7 +1665,7 @@ diagram represents the Private Message Key Payload.
 .in 3
 
 .ce
-Figure 14:  Private Message Key Payload
+Figure 15:  Private Message Key Payload
 
 
 
@@ -1642,7 +1710,7 @@ represents the Command Payload.
 .in 3
 
 .ce
-Figure 15:  Command Payload
+Figure 16:  Command Payload
 
 
 .in 6
@@ -1724,7 +1792,7 @@ diagram represents the Connection Auth Request Payload.
 .in 3
 
 .ce
-Figure 16:  Connection Auth Request Payload
+Figure 17:  Connection Auth Request Payload
 
 
 .in 6
@@ -1842,7 +1910,7 @@ represents the New Client Payload.
 .in 3
 
 .ce
-Figure 17:  New Client Payload
+Figure 18:  New Client Payload
 
 
 .in 6
@@ -1897,7 +1965,7 @@ the New Server Payload.
 .in 3
 
 .ce
-Figure 18:  New Server Payload
+Figure 19:  New Server Payload
 
 
 .in 6
@@ -1925,45 +1993,9 @@ to the router (after it has received JOIN command from client) which
 then processes the command and creates the channel.  Client never sends
 this packet.
 
-The payload may only be sent with SILC_PACKET_NEW_CHANNEL packet.
-It must not be sent in any other packet type.  The following diagram
-represents the New Channel Payload.
-
-
-.in 5
-.nf
-                     1                   2                   3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|      Channel Name Length      |                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
-|                                                               |
-~                         Channel Name                          ~
-|                                                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-|       Channel ID Length       |                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                               +
-|                                                               |
-~                          Channel ID                           ~
-|                                                               |
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-.in 3
-
-.ce
-Figure 19:  New Channel Payload
-
-
-
-.in 6
-o Channel Name Length (2 bytes) - Length of the channel name.
-
-o Channel Name (variable length) - The name of the created
-  channel.
-
-o Channel ID Length (2 bytes) - Length of the Channel ID.
-
-o Channel ID (variable length) - The created Channel ID.
-.in 3
+The packet uses generic Channel Payload as New Channel Payload.  See
+section 2.3.2.3 for generic Channel Payload.  The Mode Mask field in the
+Channel Payload is the mode of the channel.
 
 
 .ti 0
index 509a8e93fa2af8997cfdf5dcd471aab78ce2b6a9..1f37aeca568268e98703a772765330413f561447 100644 (file)
@@ -208,7 +208,7 @@ keep global information up to date at all time.
 This, on the other hand, leads to cellular like network, where routers 
 are in the center of the cell and servers are connected to the router.
 
-Following diagram represents SILC network topology.
+The following diagram represents SILC network topology.
 
 
 
@@ -280,7 +280,7 @@ to other server in the same cell, will have its messages delivered from
 its local server first to the router of the cell, and from the router 
 to the other server in the cell.
 
-Following diagram represents this scenario:
+The following diagram represents this scenario:
 
 
 .in 25
@@ -318,7 +318,7 @@ If the message is destined to server that does not belong to local cell
 the message is routed to the router server to which the destination 
 server belongs, if the local router is connected to destination router.
 If there is no direct connection to the destination router, the local
-router routes the message to its primary route.  Following diagram
+router routes the message to its primary route.  The following diagram
 represents message sending between cells.
 
 
@@ -683,7 +683,7 @@ distributing it to the router.
 .ti 0
 3.2.3 SILC Server Ports
 
-Following ports has been assigned by IANA for the SILC protocol:
+The following ports has been assigned by IANA for the SILC protocol:
 
 .in 10
 silc            706/tcp    SILC
@@ -816,7 +816,7 @@ not contain any spaces (`  '), any non-printable ASCII characters,
 commas (`,') and wildcard characters.
 
 Channels can have operators that can administrate the channel and
-operate all of its modes.  Following operators on channel exist on SILC
+operate all of its modes.  The following operators on channel exist on SILC
 network.
 
 .in 6
@@ -1230,7 +1230,7 @@ in the SILC packets.  See [SILC2] of the actual encryption process and
 definition of how it must be done.  SILC has a mandatory algorithm that
 must be supported in order to be compliant with this protocol.
 
-Following ciphers are defined in SILC protocol:
+The following ciphers are defined in SILC protocol:
 
 .in 6
 aes-256-cbc         AES in CBC mode, 256 bit key       (mandatory)
@@ -1269,7 +1269,7 @@ Public keys are used in SILC to authenticate entities in SILC network
 and to perform other tasks related to public key cryptography.  The 
 public keys are also used in the SILC Key Exchange protocol [SILC3].
 
-Following public key algorithms are defined in SILC protocol:
+The following public key algorithms are defined in SILC protocol:
 
 .in 6
 rsa        RSA  (mandatory)
@@ -1278,7 +1278,7 @@ dss        DSS  (optional)
 
 DSS is described in [Menezes].  The RSA must be implemented according
 PKCS #1 [PKCS1].  The mandatory PKCS #1 implementation in SILC must be
-compliant to either PKCS #1 version 1.5 or newer with the following
+compliant to either PKCS #1 version 1.5 or newer with the the following
 notes: The signature encoding is always in same format as the encryption
 encoding regardles of the PKCS #1 version.  The signature with appendix
 (with hash algorithm OID in the data) must not be used in the SILC.  The
@@ -1296,7 +1296,7 @@ Hash functions are used as part of MAC algorithms defined in the next
 section.  They are also used in the SILC Key Exchange protocol defined
 in the [SILC3].
 
-Following Hash algorithm are defined in SILC protocol:
+The following Hash algorithm are defined in SILC protocol:
 
 sha1             SHA-1, length = 20      (mandatory)
 md5              MD5, length = 16        (optional)
@@ -1309,7 +1309,7 @@ Data integrity is protected by computing a message authentication code
 (MAC) of the packet data.  See [SILC2] for details how to compute the
 MAC.
 
-Following MAC algorithms are defined in SILC protocol:
+The following MAC algorithms are defined in SILC protocol:
 
 .in 6
 hmac-sha1-96     HMAC-SHA1, length = 12  (mandatory)
@@ -1340,7 +1340,7 @@ significantly speed up the data transmission.  By default, SILC does not
 use compression which is the mode that must be supported by all SILC
 implementations.
 
-Following compression algorithms are defined:
+The following compression algorithms are defined:
 
 .in 6
 none        No compression               (mandatory)
@@ -1407,7 +1407,7 @@ o Identifier Length (2 bytes) - Indicates the length of
 
 o Identifier (variable length) - Indicates the identifier
   of the public key.  This data can be used to identify
-  the owner of the key.  The identifier is of following
+  the owner of the key.  The identifier is of the following
   format:
 
      UN   User name
@@ -1470,13 +1470,13 @@ order.
 The version detection of both client and server is performed at the
 connection phase while executing the SILC Key Exchange protocol.  The
 version identifier is exchanged between initiator and responder.  The
-version identifier is of following format:
+version identifier is of the following format:
 
 .in 6
 SILC-<protocol version>-<software version>
 .in 3
 
-The version strings are of following format:
+The version strings are of the following format:
 
 .in 6
 protocol version = <major>.<minor>
@@ -1793,7 +1793,7 @@ protocol.  If the digest length of the hash function is too short for the
 key, then the key is distributed as described in section Processing the
 Key Material in [SILC3].  After both parties has regenerated the session
 key, both send SILC_PACKET_REKEY_DONE packet to each other.  These packets
-are still secured with the old key.  After these packets, following
+are still secured with the old key.  After these packets, the following
 packets must be protected with the new key.
 
 
@@ -1975,7 +1975,7 @@ List of all defined commands in SILC follows.
         so that all users are searched.  However, the server still must
         search its locally connected clients.  The router must send
         this command to the server who owns the requested client.  That
-        server must reply to the command.  Server should not send whois
+        server must reply to the command.  Server must not send whois
        replies to the client until it has received the reply from its
        router.
 
@@ -1984,7 +1984,8 @@ List of all defined commands in SILC follows.
         Max Arguments:  8
             Arguments:  (1) <Status Payload>       (2) <Client ID> 
                         (3) <nickname>[@<server>]  (4) <username@host> 
-                        (5) <real name>            (6) [<channel list>] 
+                        (5) <real name>            (6) [<Channel Payload 
+                                                         list>] 
                         (7) [<user mode>]          (8) [<idle time>]
 
 
@@ -2002,6 +2003,12 @@ List of all defined commands in SILC follows.
         <count> option were defined in the query there will be only
         <count> many replies from the server.
 
+        The server may return the list of channel the client has joined.
+        In this case the list is list of Channel Payloads.  The Mode Mask
+        in the Channel Payload (see [SILC2] and section 2.3.2.3 for the
+        Channel Payload) is the client's mode on the channel.  The list
+        is encoded by adding the Channel Payloads one after the other.
+
         Status messages:
 
             SILC_STATUS_OK
@@ -2014,8 +2021,6 @@ List of all defined commands in SILC follows.
             SILC_STATUS_ERR_TOO_MANY_PARAMS
 
 
-
-
    2    SILC_COMMAND_WHOWAS
 
         Max Arguments:  2
@@ -2316,6 +2321,13 @@ List of all defined commands in SILC follows.
         give to the removed client some information why it was removed
         from the network.
 
+        When killing a client the router must first send notify type
+        SILC_NOTIFY_TYPE_KILLED to all channels the client has joined.
+        The packet must not be sent to the killed client on the channel.
+        Then, the router must send the same notify type to its primary
+        router.  Finally, the router must send the same notify type to
+        the client who was killed.
+
         Reply messages to the command:
 
         Max Arguments:  1
@@ -2440,6 +2452,9 @@ List of all defined commands in SILC follows.
         for user on client's screen or it may be public key or certificate
         authentication data (data signed with private key).
 
+        After changing the mode server must send the notify type
+        SILC_NOTIFY_TYPE_UMODE_CHANGE to its primary router.
+
         Reply messages to the command:
 
         Max Arguments:  1
@@ -2578,7 +2593,10 @@ List of all defined commands in SILC follows.
         locally so that the mode setting/unsetting would work without
         problems.  Client may change only its own modes.
 
-        Following client modes are defined:
+        After changing the mode server must send the notify type
+        SILC_NOTIFY_TYPE_UMODE_CHANGE to its primary router.
+
+        The following client modes are defined:
 
            0x0000    SILC_UMODE_NONE
 
@@ -2646,7 +2664,7 @@ List of all defined commands in SILC follows.
         When the mode is changed SILC_NOTIFY_TYPE_CMODE_CHANGE notify
         type is distributed to the channel.
 
-        Following channel modes are defined:
+        The following channel modes are defined:
 
            0x0000    SILC_CMODE_NONE
 
@@ -2872,7 +2890,7 @@ List of all defined commands in SILC follows.
         When the mode is changed SILC_NOTIFY_TYPE_CUMODE_CHANGE notify
         type is distributed to the channel.
 
-        Following channel modes are defined:
+        The following channel modes are defined:
 
            0x0000    SILC_CUMODE_NONE
 
@@ -3049,6 +3067,9 @@ List of all defined commands in SILC follows.
         local properties, such as, local connections and normal server
         administration.
 
+        After changing the mode server must send the notify type
+        SILC_NOTIFY_TYPE_UMODE_CHANGE to its primary router.
+
         Reply messages to the command:
 
         Max Arguments:  1
@@ -3165,7 +3186,7 @@ List of all defined commands in SILC follows.
 Command Status Payload is sent in command reply messages to indicate
 the status of the command.  The payload is one of argument in the
 command thus this is the data area in Command Argument Payload described
-in [SILC2].  The payload is only 2 bytes of length.  Following diagram
+in [SILC2].  The payload is only 2 bytes of length.  The following diagram
 represents the Command Status Payload (field is always in MSB order).
 
 
index 46190226fecaf19b85cfc65f843ff38211afe9dd..2eec830d3f24ac3565bb154c6f31be7fc16aba9c 100644 (file)
@@ -98,9 +98,9 @@ void silc_client_send_channel_message(SilcClient client,
     silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
 
   /* Encode the channel payload. This also encrypts the message payload. */
-  payload = silc_channel_payload_encode(data_len, data, iv_len, 
-                                       channel->iv, cipher, hmac,
-                                       client->rng);
+  payload = silc_channel_message_payload_encode(data_len, data, iv_len, 
+                                               channel->iv, cipher, hmac,
+                                               client->rng);
 
   /* Get data used in packet header encryption, keys and stuff. */
   cipher = conn->send_key;
@@ -165,7 +165,7 @@ void silc_client_channel_message(SilcClient client,
 {
   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
   SilcBuffer buffer = packet->buffer;
-  SilcChannelPayload payload = NULL;
+  SilcChannelMessagePayload payload = NULL;
   SilcChannelID *id = NULL;
   SilcChannelEntry channel;
   SilcChannelUser chu;
@@ -200,8 +200,8 @@ void silc_client_channel_message(SilcClient client,
      all private keys and check what decrypts correctly. */
   if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
     /* Parse the channel message payload. This also decrypts the payload */
-    payload = silc_channel_payload_parse(buffer, channel->channel_key,
-                                        channel->hmac);
+    payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
+                                                channel->hmac);
     if (!payload)
       goto out;
   } else if (channel->private_keys) {
@@ -210,8 +210,8 @@ void silc_client_channel_message(SilcClient client,
     silc_dlist_start(channel->private_keys);
     while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
       /* Parse the channel message payload. This also decrypts the payload */
-      payload = silc_channel_payload_parse(buffer, entry->cipher,
-                                          entry->hmac);
+      payload = silc_channel_message_payload_parse(buffer, entry->cipher,
+                                                  entry->hmac);
       if (payload)
        break;
     }
@@ -221,7 +221,7 @@ void silc_client_channel_message(SilcClient client,
     goto out;
   }
 
-  message = silc_channel_get_data(payload, NULL);
+  message = silc_channel_message_get_data(payload, NULL);
 
   /* Find client entry */
   silc_list_start(channel->clients);
@@ -242,7 +242,7 @@ void silc_client_channel_message(SilcClient client,
   if (client_id)
     silc_free(client_id);
   if (payload)
-    silc_channel_payload_free(payload);
+    silc_channel_message_payload_free(payload);
 }
 
 /* Saves channel key from encoded `key_payload'. This is used when we
index 559b5cf9022519941acd6aa2103c355cd9313555..ec64040bd95ac268a35c96aca57cf4f08439a2c9 100644 (file)
@@ -209,6 +209,7 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
   char *nickname = NULL, *username = NULL;
   char *realname = NULL;
   unsigned int idle = 0, mode = 0;
+  SilcBuffer channels = NULL;
   
   argc = silc_argument_get_arg_num(cmd->args);
 
@@ -232,15 +233,20 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
     return;
   }
 
-  tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
+  tmp = silc_argument_get_arg_type(cmd->args, 6, &len);
   if (tmp) {
-    SILC_GET32_MSB(mode, tmp);
+    channels = silc_buffer_alloc(len);
+    silc_buffer_pull_tail(channels, SILC_BUFFER_END(channels));
+    silc_buffer_put(channels, tmp, len);
   }
 
+  tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
+  if (tmp)
+    SILC_GET32_MSB(mode, tmp);
+
   tmp = silc_argument_get_arg_type(cmd->args, 8, &len);
-  if (tmp) {
+  if (tmp)
     SILC_GET32_MSB(idle, tmp);
-  }
 
   /* Check if we have this client cached already. */
   if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
@@ -289,7 +295,10 @@ silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
   /* Notify application */
   if (!cmd->callback)
     COMMAND_REPLY((ARGS, client_entry, nickname, username, realname, 
-                  NULL, mode, idle));
+                  channels, mode, idle));
+
+  if (channels)
+    silc_buffer_free(channels);
 }
 
 /* Received reply for WHOIS command. This maybe called several times
@@ -877,11 +886,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(join)
 
   /* Get channel mode */
   tmp = silc_argument_get_arg_type(cmd->args, 5, NULL);
-  if (tmp) {
+  if (tmp)
     SILC_GET32_MSB(mode, tmp);
-  } else {
+  else
     mode = 0;
-  }
 
   /* Get channel key */
   tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
index 433236eb4be27dacb695362e8938fb0da334039c..26f7f4dc2fccabb9b6222d71f29dce83b586d13f 100644 (file)
@@ -17,7 +17,8 @@
   GNU General Public License for more details.
 
 */
-/* Channel Payload and Channel Key Payload implementations. */
+/* Channel Payload, Channel Message Payload and Channel Key Payload 
+   implementations. */
 /* $Id$ */
 
 #include "silcincludes.h"
 
 /******************************************************************************
 
-                          Channel Message Payload
+                              Channel Payload
 
 ******************************************************************************/
 
 /* Channel Message Payload structure. Contents of this structure is parsed
    from SILC packets. */
 struct SilcChannelPayloadStruct {
+  unsigned short name_len;
+  unsigned char *channel_name;
+  unsigned short id_len;
+  unsigned char *channel_id;
+  unsigned int mode;
+};
+
+/* Parses channel payload returning new channel payload structure. */
+
+SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer)
+{
+  SilcChannelPayload new;
+  int ret;
+
+  SILC_LOG_DEBUG(("Parsing channel payload"));
+
+  new = silc_calloc(1, sizeof(*new));
+
+  /* Parse the Channel Payload. Ignore the padding. */
+  ret = silc_buffer_unformat(buffer,
+                            SILC_STR_UI16_NSTRING_ALLOC(&new->channel_name, 
+                                                        &new->name_len),
+                            SILC_STR_UI16_NSTRING_ALLOC(&new->channel_id, 
+                                                        &new->id_len),
+                            SILC_STR_UI_INT(&new->mode),
+                            SILC_STR_END);
+  if (ret == -1)
+    goto err;
+
+  if ((new->name_len < 1 || new->name_len > buffer->len) ||
+      (new->id_len < 1 || new->id_len > buffer->len)) {
+    SILC_LOG_ERROR(("Incorrect channel payload in packet, packet dropped"));
+    goto err;
+  }
+
+  return new;
+
+ err:
+  silc_channel_payload_free(new);
+  return NULL;
+}
+
+/* Parses list of channel payloads returning list of payloads. */
+
+SilcDList silc_channel_payload_parse_list(SilcBuffer buffer)
+{
+  SilcDList list;
+  SilcChannelPayload new;
+  int len, ret;
+
+  SILC_LOG_DEBUG(("Parsing channel payload list"));
+
+  list = silc_dlist_init();
+
+  while (buffer->len) {
+    new = silc_calloc(1, sizeof(*new));
+    ret = silc_buffer_unformat(buffer,
+                              SILC_STR_UI16_NSTRING_ALLOC(&new->channel_name, 
+                                                          &new->name_len),
+                              SILC_STR_UI16_NSTRING_ALLOC(&new->channel_id, 
+                                                          &new->id_len),
+                              SILC_STR_UI_INT(&new->mode),
+                              SILC_STR_END);
+    if (ret == -1)
+      goto err;
+
+    if ((new->name_len < 1 || new->name_len > buffer->len) ||
+       (new->id_len < 1 || new->id_len > buffer->len)) {
+      SILC_LOG_ERROR(("Incorrect channel payload in packet, packet dropped"));
+      goto err;
+    }
+
+    len = 2 + new->name_len + 2 + new->id_len + 4;
+    if (buffer->len < len)
+      break;
+    silc_buffer_pull(buffer, len);
+
+    silc_dlist_add(list, new);
+  }
+  
+  return list;
+
+ err:
+  silc_channel_payload_list_free(list);
+  return NULL;
+}
+
+/* Encode new channel payload and returns it as buffer. */
+
+SilcBuffer silc_channel_payload_encode(unsigned char *channel_name,
+                                      unsigned short channel_name_len,
+                                      unsigned char *channel_id,
+                                      unsigned int channel_id_len,
+                                      unsigned int mode)
+{
+  SilcBuffer buffer;
+
+  SILC_LOG_DEBUG(("Encoding message payload"));
+
+  buffer = silc_buffer_alloc(2 + channel_name_len + 2 + channel_id_len + 4);
+  silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
+
+  /* Encode the Channel Payload */
+  silc_buffer_format(buffer, 
+                    SILC_STR_UI_SHORT(channel_name_len),
+                    SILC_STR_UI_XNSTRING(channel_name, channel_name_len),
+                    SILC_STR_UI_SHORT(channel_id_len),
+                    SILC_STR_UI_XNSTRING(channel_id, channel_id_len),
+                    SILC_STR_UI_INT(mode),
+                    SILC_STR_END);
+
+  return buffer;
+}
+
+/* Free's Channel Payload */
+
+void silc_channel_payload_free(SilcChannelPayload payload)
+{
+  silc_free(payload->channel_name);
+  silc_free(payload->channel_id);
+  silc_free(payload);
+}
+
+/* Free's list of Channel Payloads */
+
+void silc_channel_payload_list_free(SilcDList list)
+{
+  SilcChannelPayload entry;
+
+  silc_dlist_start(list);
+  while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
+    silc_free(entry->channel_name);
+    silc_free(entry->channel_id);
+    silc_free(entry);
+    silc_dlist_del(list, entry);
+  }
+
+  silc_dlist_uninit(list);
+}
+
+/* Return the channel name */
+
+unsigned char *silc_channel_get_name(SilcChannelPayload payload,
+                                    unsigned int *channel_name_len)
+{
+  if (channel_name_len)
+    *channel_name_len = payload->name_len;
+
+  return payload->channel_name;
+}
+
+/* Return the channel ID */
+
+unsigned char *silc_channel_get_id(SilcChannelPayload payload,
+                                  unsigned int *channel_id_len)
+{
+  if (channel_id_len)
+    *channel_id_len = payload->id_len;
+
+  return payload->channel_id;
+}
+
+/* Return the channel ID as parsed ID. */
+
+SilcChannelID *silc_channel_get_id_parse(SilcChannelPayload payload)
+{
+  return silc_id_str2id(payload->channel_id, payload->id_len,
+                       SILC_ID_CHANNEL);
+}
+
+/* Return the mode. The mode is arbitrary. It can be the mode of the
+   channel or perhaps the mode of the client on the channel.  The protocol
+   dictates what the usage of the mode is in different circumstances. */
+
+unsigned int silc_channel_get_mode(SilcChannelPayload payload)
+{
+  return payload->mode;
+}
+
+/******************************************************************************
+
+                          Channel Message Payload
+
+******************************************************************************/
+
+/* Channel Message Payload structure. Contents of this structure is parsed
+   from SILC packets. */
+struct SilcChannelMessagePayloadStruct {
   unsigned short data_len;
   unsigned char *data;
   unsigned char *mac;
@@ -40,10 +229,10 @@ struct SilcChannelPayloadStruct {
 
 /* Decrypts the channel message payload. */
 
-int silc_channel_payload_decrypt(unsigned char *data,
-                                size_t data_len,
-                                SilcCipher cipher,
-                                SilcHmac hmac)
+int silc_channel_message_payload_decrypt(unsigned char *data,
+                                        size_t data_len,
+                                        SilcCipher cipher,
+                                        SilcHmac hmac)
 {
   unsigned int iv_len, mac_len;
   unsigned char *end, *mac, mac2[32];
@@ -79,21 +268,22 @@ int silc_channel_payload_decrypt(unsigned char *data,
   return TRUE;
 }
 
-/* Parses channel payload returning new channel payload structure. This
-   also decrypts it and checks the MAC. */
+/* Parses channel message payload returning new channel payload structure.
+   This also decrypts it and checks the MAC. */
 
-SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer,
-                                             SilcCipher cipher,
-                                             SilcHmac hmac)
+SilcChannelMessagePayload 
+silc_channel_message_payload_parse(SilcBuffer buffer,
+                                  SilcCipher cipher,
+                                  SilcHmac hmac)
 {
-  SilcChannelPayload new;
+  SilcChannelMessagePayload new;
   int ret;
   unsigned int iv_len, mac_len;
 
-  SILC_LOG_DEBUG(("Parsing channel payload"));
+  SILC_LOG_DEBUG(("Parsing channel message payload"));
 
   /* Decrypt the payload */
-  ret = silc_channel_payload_decrypt(buffer->data, buffer->len,
+  ret = silc_channel_message_payload_decrypt(buffer->data, buffer->len,
                                     cipher, hmac);
   if (ret == FALSE)
     return NULL;
@@ -103,7 +293,7 @@ SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer,
 
   new = silc_calloc(1, sizeof(*new));
 
-  /* Parse the Channel Payload. Ignore the padding. */
+  /* Parse the Channel Message Payload. Ignore the padding. */
   ret = silc_buffer_unformat(buffer,
                             SILC_STR_UI16_NSTRING_ALLOC(&new->data, 
                                                         &new->data_len),
@@ -115,29 +305,30 @@ SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer,
     goto err;
 
   if (new->data_len < 1 || new->data_len > buffer->len) {
-    SILC_LOG_ERROR(("Incorrect channel payload in packet, packet dropped"));
+    SILC_LOG_ERROR(("Incorrect channel messaeg payload in packet, "
+                   "packet dropped"));
     goto err;
   }
 
   return new;
 
  err:
-  silc_channel_payload_free(new);
+  silc_channel_message_payload_free(new);
   return NULL;
 }
 
-/* Encodes channel payload into a buffer and returns it. This is used 
-   to add channel payload into a packet. As the channel payload is
+/* Encodes channel message payload into a buffer and returns it. This is used 
+   to add channel message payload into a packet. As the channel payload is
    encrypted separately from other parts of the packet padding must
    be applied to the payload. */
 
-SilcBuffer silc_channel_payload_encode(unsigned short data_len,
-                                      unsigned char *data,
-                                      unsigned short iv_len,
-                                      unsigned char *iv,
-                                      SilcCipher cipher,
-                                      SilcHmac hmac,
-                                      SilcRng rng)
+SilcBuffer silc_channel_message_payload_encode(unsigned short data_len,
+                                              unsigned char *data,
+                                              unsigned short iv_len,
+                                              unsigned char *iv,
+                                              SilcCipher cipher,
+                                              SilcHmac hmac,
+                                              SilcRng rng)
 {
   int i;
   SilcBuffer buffer;
@@ -145,7 +336,7 @@ SilcBuffer silc_channel_payload_encode(unsigned short data_len,
   unsigned char pad[SILC_PACKET_MAX_PADLEN];
   unsigned char mac[32];
 
-  SILC_LOG_DEBUG(("Encoding channel payload"));
+  SILC_LOG_DEBUG(("Encoding channel message payload"));
 
   /* Calculate length of padding. IV is not included into the calculation
      since it is not encrypted. */
@@ -160,7 +351,7 @@ SilcBuffer silc_channel_payload_encode(unsigned short data_len,
   /* Generate padding */
   for (i = 0; i < pad_len; i++) pad[i] = silc_rng_get_byte(rng);
 
-  /* Encode the Channel Payload */
+  /* Encode the Channel Message Payload */
   silc_buffer_pull_tail(buffer, 4 + data_len + pad_len);
   silc_buffer_format(buffer, 
                     SILC_STR_UI_SHORT(data_len),
@@ -191,23 +382,21 @@ SilcBuffer silc_channel_payload_encode(unsigned short data_len,
   return buffer;
 }
 
-/* Free's Channel Payload */
+/* Free's Channel Message Payload */
 
-void silc_channel_payload_free(SilcChannelPayload payload)
+void silc_channel_message_payload_free(SilcChannelMessagePayload payload)
 {
-  if (payload) {
-    if (payload->data) {
-      memset(payload->data, 0, payload->data_len);
-      silc_free(payload->data);
-    }
-    silc_free(payload);
+  if (payload->data) {
+    memset(payload->data, 0, payload->data_len);
+    silc_free(payload->data);
   }
+  silc_free(payload);
 }
 
 /* Return data */
 
-unsigned char *silc_channel_get_data(SilcChannelPayload payload,
-                                    unsigned int *data_len)
+unsigned char *silc_channel_message_get_data(SilcChannelMessagePayload payload,
+                                            unsigned int *data_len)
 {
   if (data_len)
     *data_len = payload->data_len;
@@ -217,14 +406,14 @@ unsigned char *silc_channel_get_data(SilcChannelPayload payload,
 
 /* Return MAC. The caller knows the length of the MAC */
 
-unsigned char *silc_channel_get_mac(SilcChannelPayload payload)
+unsigned char *silc_channel_mesage_get_mac(SilcChannelMessagePayload payload)
 {
   return payload->mac;
 }
 
 /* Return IV. The caller knows the length of the IV */
 
-unsigned char *silc_channel_get_iv(SilcChannelPayload payload)
+unsigned char *silc_channel_message_get_iv(SilcChannelMessagePayload payload)
 {
   return payload->iv;
 }
index 0c6a41e525e040b453b3a73e4443e1a94a4c079f..1059b156c4a3e697418631d8be1ccd84b221d617 100644 (file)
 #ifndef SILCCHANNEL_H
 #define SILCCHANNEL_H
 
-/* Forward declaration for Channel Message Payload parsed from packet. The
+#include "silcdlist.h"
+
+/* Forward declaration for Channel Payload parsed from packet. The
    actual structure is defined in source file and is private data. */
 typedef struct SilcChannelPayloadStruct *SilcChannelPayload;
 
+/* Forward declaration for Channel Message Payload parsed from packet. The
+   actual structure is defined in source file and is private data. */
+typedef struct SilcChannelMessagePayloadStruct *SilcChannelMessagePayload;
+
 /* Forward declaration for Channel Key Payload parsed from packet. The
    actual structure is defined in source file and is private data. */
 typedef struct SilcChannelKeyPayloadStruct *SilcChannelKeyPayload;
 
 /* Prototypes */
-int silc_channel_payload_decrypt(unsigned char *data,
-                                size_t data_len,
-                                SilcCipher cipher,
-                                SilcHmac hmac);
-SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer,
-                                             SilcCipher cipher,
-                                             SilcHmac hmac);
-SilcBuffer silc_channel_payload_encode(unsigned short data_len,
-                                      unsigned char *data,
-                                      unsigned short iv_len,
-                                      unsigned char *iv,
-                                      SilcCipher cipher,
-                                      SilcHmac hmac,
-                                      SilcRng rng);
+SilcChannelPayload silc_channel_payload_parse(SilcBuffer buffer);
+SilcDList silc_channel_payload_parse_list(SilcBuffer buffer);
+SilcBuffer silc_channel_payload_encode(unsigned char *channel_name,
+                                      unsigned short channel_name_len,
+                                      unsigned char *channel_id,
+                                      unsigned int channel_id_len,
+                                      unsigned int mode);
 void silc_channel_payload_free(SilcChannelPayload payload);
-unsigned char *silc_channel_get_data(SilcChannelPayload payload,
+void silc_channel_payload_list_free(SilcDList list);
+unsigned char *silc_channel_get_name(SilcChannelPayload payload,
+                                    unsigned int *channel_name_len);
+unsigned char *silc_channel_get_id(SilcChannelPayload payload,
+                                  unsigned int *channel_id_len);
+SilcChannelID *silc_channel_get_id_parse(SilcChannelPayload payload);
+unsigned int silc_channel_get_mode(SilcChannelPayload payload);
+int silc_channel_message_payload_decrypt(unsigned char *data,
+                                        size_t data_len,
+                                        SilcCipher cipher,
+                                        SilcHmac hmac);
+SilcChannelMessagePayload 
+silc_channel_message_payload_parse(SilcBuffer buffer,
+                                  SilcCipher cipher,
+                                  SilcHmac hmac);
+SilcBuffer silc_channel_message_payload_encode(unsigned short data_len,
+                                              unsigned char *data,
+                                              unsigned short iv_len,
+                                              unsigned char *iv,
+                                              SilcCipher cipher,
+                                              SilcHmac hmac,
+                                              SilcRng rng);
+void silc_channel_message_payload_free(SilcChannelMessagePayload payload);
+unsigned char *silc_channel_message_get_data(SilcChannelMessagePayload payload,
                                     unsigned int *data_len);
-unsigned char *silc_channel_get_mac(SilcChannelPayload payload);
-unsigned char *silc_channel_get_iv(SilcChannelPayload payload);
+unsigned char *silc_channel_message_get_mac(SilcChannelMessagePayload payload);
+unsigned char *silc_channel_message_get_iv(SilcChannelMessagePayload payload);
 SilcChannelKeyPayload silc_channel_key_payload_parse(SilcBuffer buffer);
 SilcBuffer silc_channel_key_payload_encode(unsigned short id_len,
                                           unsigned char *id,
index 9f25ededf3cec7f2f64bc4f37dfe30f72a95c72a..68faeed35dad44fddebea008c03d04b7d2e89a9c 100644 (file)
@@ -44,6 +44,7 @@ typedef unsigned short SilcNotifyType;
 #define SILC_NOTIFY_TYPE_SERVER_SIGNOFF  11 /* Server quitting SILC */
 #define SILC_NOTIFY_TYPE_KICKED          12 /* Kicked from channel */
 #define SILC_NOTIFY_TYPE_KILLED          13 /* Killed from the network */
+#define SILC_NOTIFY_TYPE_UMODE_CHANGE    14 /* user mode was changed */
 
 /* Prototypes */
 SilcNotifyPayload silc_notify_payload_parse(SilcBuffer buffer);