Addec multiple channel private key support to Irssi SILC client.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 19 Mar 2002 18:41:30 +0000 (18:41 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 19 Mar 2002 18:41:30 +0000 (18:41 +0000)
14 files changed:
CHANGES
TODO
apps/irssi/docs/help/in/key.in
apps/irssi/silc.conf
apps/irssi/src/fe-common/silc/module-formats.c
apps/irssi/src/fe-common/silc/module-formats.h
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-channels.h
apps/irssi/src/silc/core/silc-servers.c
lib/silcclient/client_channel.c
lib/silcclient/client_prvmsg.c
lib/silcclient/idlist.h
lib/silcclient/silcclient.h
prepare

diff --git a/CHANGES b/CHANGES
index 888671f12ea5f8c8669de2ae0b9f0e1fcc80a3ed..6e419f7f7ca0b63532d288c5ab4866b8d9072fdc 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,21 @@
+Tue Mar 19 20:42:41 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added `name' field to SilcChannelPrivateKey to represent
+         application given name for the key.  Moved also the context from
+         lib/silcclient/idlist.h into lib/silcclient/silcclient.h.
+         Added the `name' argument also to the function
+         silc_client_add_channel_private_key.
+
+         Added function silc_client_current_channel_private_key to set the
+         current channel private key in use.
+
+         Added "change" command to KEY command which can be used to change
+         the current channel private key.  Bound the command also to
+         alt+K (Alt+Shift+k).
+
+         Also affected files lib/silcclient/client_channel.c,
+         irssi/src/docs/help/in/key.in, irssi/src/silc/core/silc-channel.c.
+
 Tue Mar 19 16:32:43 CET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added silc_rng_get_byte_fast function in to the
 Tue Mar 19 16:32:43 CET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added silc_rng_get_byte_fast function in to the
diff --git a/TODO b/TODO
index 7ec1bc17ba0786b203e6c3820848c03c7b5a384a..980ff9d4417ccdca139ebe682efd13a074da4c84 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,16 +1,6 @@
 TODO/bugs in Irssi SILC client
 ==============================
 
 TODO/bugs in Irssi SILC client
 ==============================
 
- o Fix the silc_channels_join to parse the command like, with fe.
-   silc_parse_command_line, because currently it ignores all options,
-   including passphrase which makes autojoin impossible to +a channels.
-   Other important options are ignored too.
-
- o Add local command to switch the channel's private key when channel has
-   several private keys.  Currently sending channel messages with many
-   keys is not possible because changing the key is not possible by the
-   user.
-
  o /cumode for unknown nick does not give any error message.
 
 
  o /cumode for unknown nick does not give any error message.
 
 
index 9e54b7bd7daeae44477b100b5d977aeffae591f4..3d3a716252150d419cf410351e34f1fdb7803df6 100644 (file)
@@ -15,8 +15,8 @@ Types:
   MSG        The command is performed for private messages
              affecting the <nickname>.
 
   MSG        The command is performed for private messages
              affecting the <nickname>.
 
-  CHANNEL    The command is performed for channel affecting
-             the <channel>.
+  CHANNEL    The command is performed for the channel indicated
+             by <channel> (* matches current channel).
 
 Commands:
 
 
 Commands:
 
@@ -27,7 +27,7 @@ Commands:
     negotiated key material is used.  If the negotiation has not
     been performed this command has no effect.
 
     negotiated key material is used.  If the negotiation has not
     been performed this command has no effect.
 
-    If the type is `msg' and the <key> is `*' then random key
+    If the type is MSG and the <key> is `*' then random key
     will be generated automatically.  The <cipher> may be set
     for both private message and channel private keys and the
     <hmac> may be set only to the channel private keys.
     will be generated automatically.  The <cipher> may be set
     for both private message and channel private keys and the
     <hmac> may be set only to the channel private keys.
@@ -44,9 +44,17 @@ Commands:
   list
 
     List all private keys that has been set.  If the type is
   list
 
     List all private keys that has been set.  If the type is
-    `msg' and the <nickname> is ´*' then all private message
+    MSG and the <nickname> is ´*' then all private message
     keys that you've set will be listed.
 
     keys that you've set will be listed.
 
+  change     [<number>]
+
+    This command can be used only when type is CHANNEL.  This is
+    used to change the current channel private key.  The <number>
+    may indicate what key is changed.  If it is not provided then
+    next key is changed to current channel private key.  By default
+    this command is also bound to Meta-K (Alt+Shift+k) key.
+
   agreement  [<hostname> [<port>]]
 
     Send key agreement request to remote client.  If the
   agreement  [<hostname> [<port>]]
 
     Send key agreement request to remote client.  If the
@@ -82,3 +90,10 @@ Commands:
     your key agreement request.  You will see a notify on the
     screen when the reply arrives.  The <hostname> and <port> is the
     hostname and port of the remote client's key agreement server.
     your key agreement request.  You will see a notify on the
     screen when the reply arrives.  The <hostname> and <port> is the
     hostname and port of the remote client's key agreement server.
+
+Examples:
+
+  Set channel private key to current channel, and list all keys:
+
+    /KEY CHANNEL set very_secret_key_this_is
+    /KEY CHANNEL list
index 3ff0538f16eeb13e9e1455b8b39c79222302d999..e8741573fa62039c5001892072a57bde07e8b8bb 100644 (file)
@@ -21,6 +21,13 @@ channels = (
   { name = "#silc"; chatnet = silcnet; autojoin = No; }
 );
 
   { name = "#silc"; chatnet = silcnet; autojoin = No; }
 );
 
+#
+# Keyboard bindings (BIND command)
+#
+keyboard = (
+  { key = "meta-K"; id = "command"; data = "key channel * change"; }
+); 
+
 #
 # Your favorite aliases
 #
 #
 # Your favorite aliases
 #
index 5ee13d6d2cd8c0bdfdc23144d11f710365991eca..6ac3306f20b9d3efe41801fcaab49fa664a86fc2 100644 (file)
@@ -68,6 +68,7 @@ FORMAT_REC fecommon_silc_formats[] = {
        { "channel_private_key_nomode", "Private key mode is not set on channel {channel $0}", 1, { 0 } },
        { "channel_private_key_error", "Could not add private key to channel {channel $0}", 1, { 0 } },
        { "channel_private_key_list", "Channel {channel $0} private keys%:  Cipher           Hmac             Key", 1, { 0 } },
        { "channel_private_key_nomode", "Private key mode is not set on channel {channel $0}", 1, { 0 } },
        { "channel_private_key_error", "Could not add private key to channel {channel $0}", 1, { 0 } },
        { "channel_private_key_list", "Channel {channel $0} private keys%:  Cipher           Hmac             Key", 1, { 0 } },
+       { "channel_private_change", "You are using private key n:o $0 on {channel $1}", 2, { 1, 0 } },
        { "private_key_list", "Private message keys%:  Client                         Cipher         Key", 0 },
        { "private_key_list_nick", "Private message keys with {nick $0}%:  Client                         Cipher         Key", 1, { 0 } },
        { "key_agreement", "Requesting key agreement with {nick $0}", 1, { 0 } },
        { "private_key_list", "Private message keys%:  Client                         Cipher         Key", 0 },
        { "private_key_list_nick", "Private message keys with {nick $0}%:  Client                         Cipher         Key", 1, { 0 } },
        { "key_agreement", "Requesting key agreement with {nick $0}", 1, { 0 } },
index 62b2db5a2c50f4fc5ac4f8f3e3e8a822cd091fd5..42422e4bd4616d1b206bb06e22c86ed23e45d3b5 100644 (file)
@@ -63,6 +63,7 @@ enum {
   SILCTXT_CH_PRIVATE_KEY_NOMODE,
   SILCTXT_CH_PRIVATE_KEY_ERROR,
   SILCTXT_CH_PRIVATE_KEY_LIST,
   SILCTXT_CH_PRIVATE_KEY_NOMODE,
   SILCTXT_CH_PRIVATE_KEY_ERROR,
   SILCTXT_CH_PRIVATE_KEY_LIST,
+  SILCTXT_CH_PRIVATE_KEY_CHANGE,
   SILCTXT_PRIVATE_KEY_LIST,
   SILCTXT_PRIVATE_KEY_LIST_NICK,
   SILCTXT_KEY_AGREEMENT,
   SILCTXT_PRIVATE_KEY_LIST,
   SILCTXT_PRIVATE_KEY_LIST_NICK,
   SILCTXT_KEY_AGREEMENT,
index 1952eb90acbcc9bd4bed1b888c62654d75fa45bc..a0c98fffe1c92f4c2f46345ef147b9168b53dae9 100644 (file)
@@ -450,6 +450,7 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
   SilcClientConnection conn;
   SilcClientEntry *entrys, client_entry = NULL;
   SilcUInt32 entry_count;
   SilcClientConnection conn;
   SilcClientEntry *entrys, client_entry = NULL;
   SilcUInt32 entry_count;
+  SILC_CHANNEL_REC *chanrec = NULL;
   SilcChannelEntry channel_entry = NULL;
   char *nickname = NULL, *tmp;
   int command = 0, port = 0, type = 0;
   SilcChannelEntry channel_entry = NULL;
   char *nickname = NULL, *tmp;
   int command = 0, port = 0, type = 0;
@@ -525,11 +526,12 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
       name = argv[2];
     }
 
       name = argv[2];
     }
 
-    channel_entry = silc_client_get_channel(silc_client, conn, name);
-    if (!channel_entry) {
+    chanrec = silc_channel_find(server, name);
+    if (chanrec == NULL) {
       silc_free(nickname);
       silc_free(nickname);
-      cmd_return_error(CMDERR_NOT_JOINED);
+      cmd_return_error(CMDERR_CHAN_NOT_FOUND);
     }
     }
+    channel_entry = chanrec->entry;
   }
 
   /* Set command */
   }
 
   /* Set command */
@@ -576,7 +578,7 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
          hmac = argv[6];
 
        if (!silc_client_add_channel_private_key(silc_client, conn, 
          hmac = argv[6];
 
        if (!silc_client_add_channel_private_key(silc_client, conn, 
-                                                channel_entry,
+                                                channel_entry, NULL,
                                                 cipher, hmac,
                                                 argv[4],
                                                 argv_lens[4])) {
                                                 cipher, hmac,
                                                 argv[4],
                                                 argv_lens[4])) {
@@ -776,22 +778,18 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
        
         hostname = (char *)settings_get_str("auto_public_ip");
 
        
         hostname = (char *)settings_get_str("auto_public_ip");
 
-/* If the hostname isn't set, treat this case as if auto_public_ip wasn't
- * set.
- */
+       /* If the hostname isn't set, treat this case as if auto_public_ip 
+          wasn't set. */
         if ((hostname) && (*hostname == '\0')) {
            hostname = NULL;
         if ((hostname) && (*hostname == '\0')) {
            hostname = NULL;
-        }
-        else {
+        } else {
           bindhost = (char *)settings_get_str("auto_bind_ip");
             
           bindhost = (char *)settings_get_str("auto_bind_ip");
             
-/* if the bind_ip isn't set, but the public_ip IS, then assume then
- * public_ip is the same value as the bind_ip.
- */
-          if ((bindhost) && (*bindhost == '\0')) {
+         /* if the bind_ip isn't set, but the public_ip IS, then assume then
+            public_ip is the same value as the bind_ip. */
+          if ((bindhost) && (*bindhost == '\0'))
             bindhost = hostname;
             bindhost = hostname;
-          }
-           port = settings_get_int("auto_bind_port");
+         port = settings_get_int("auto_bind_port");
         }
       }  /* if use_auto_addr */
     }
         }
       }  /* if use_auto_addr */
     }
@@ -812,6 +810,48 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
     internal->server = server;
   }
 
     internal->server = server;
   }
 
+  /* Change current channel private key */
+  if (!strcasecmp(argv[3], "change")) {
+    command = 6;
+    if (type == 2) {
+      /* Unset channel key(s) */
+      SilcChannelPrivateKey *keys;
+      SilcUInt32 keys_count;
+      int number;
+
+      keys = silc_client_list_channel_private_keys(silc_client, conn, 
+                                                  channel_entry,
+                                                  &keys_count);
+      if (!keys)
+       goto out;
+
+      if (argc == 4) {
+       chanrec->cur_key++;
+       if (chanrec->cur_key >= keys_count)
+         chanrec->cur_key = 0;
+      }
+
+      if (argc > 4) {
+       number = atoi(argv[4]);
+       if (!number || number > keys_count)
+         chanrec->cur_key = 0;
+       else
+         chanrec->cur_key = number - 1;
+      }
+
+      /* Set the current channel private key */
+      silc_client_current_channel_private_key(silc_client, conn, 
+                                             channel_entry, 
+                                             keys[chanrec->cur_key]);
+      printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+                        SILCTXT_CH_PRIVATE_KEY_CHANGE, chanrec->cur_key + 1,
+                        channel_entry->channel_name);
+
+      silc_client_free_channel_private_keys(keys, keys_count);
+      goto out;
+    }
+  }
+
   if (command == 0) {
     silc_say(silc_client, conn, SILC_CLIENT_MESSAGE_INFO,
             "Usage: /KEY msg|channel <nickname|channel> "
   if (command == 0) {
     silc_say(silc_client, conn, SILC_CLIENT_MESSAGE_INFO,
             "Usage: /KEY msg|channel <nickname|channel> "
index 8a286b733efe8c5575c07513bb47b9da07397d28..b572712c4b8c0cf30d5e8445262424ba544643bb 100644 (file)
@@ -19,6 +19,7 @@ typedef struct {
   GSList *banlist;             /* list of bans */
   GSList *ebanlist;            /* list of ban exceptions */
   GSList *invitelist;          /* invite list */
   GSList *banlist;             /* list of bans */
   GSList *ebanlist;            /* list of ban exceptions */
   GSList *invitelist;          /* invite list */
+  SilcUInt32 cur_key;
   SilcChannelEntry entry;
 } SILC_CHANNEL_REC;
 
   SilcChannelEntry entry;
 } SILC_CHANNEL_REC;
 
index 03ccd79f7426e2c27bc9a24706e65bac7b7556c1..dcd9bb34ff94856cd113f9cecf96ee1f1ef890ca 100644 (file)
@@ -295,7 +295,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server)
 /* SYNTAX: INVITE <channel> [<nickname>[@hostname>] */
 /* SYNTAX: INVITE <channel> [+|-[<nickname>[@<server>[!<username>[@hostname>]]]]] */
 /* SYNTAX: KEY MSG <nickname> set|unset|list|agreement|negotiate [<arguments>] */
 /* SYNTAX: INVITE <channel> [<nickname>[@hostname>] */
 /* SYNTAX: INVITE <channel> [+|-[<nickname>[@<server>[!<username>[@hostname>]]]]] */
 /* SYNTAX: KEY MSG <nickname> set|unset|list|agreement|negotiate [<arguments>] */
-/* SYNTAX: KEY CHANNEL <channel> set|unset|list [<arguments>] */
+/* SYNTAX: KEY CHANNEL <channel> set|unset|list|change [<arguments>] */
 /* SYNTAX: KICK <channel> <nickname>[@<hostname>] [<comment>] */
 /* SYNTAX: KILL <nickname>[@<hostname>] [<comment>] */
 /* SYNTAX: OPER <username> [-pubkey] */
 /* SYNTAX: KICK <channel> <nickname>[@<hostname>] [<comment>] */
 /* SYNTAX: KILL <nickname>[@<hostname>] [<comment>] */
 /* SYNTAX: OPER <username> [-pubkey] */
index 485decf0867e70e8fec29bfba533bcf6f4d2364e..ff2f6d026a92cf69472661ce93e7218a736ab30b 100644 (file)
@@ -471,6 +471,7 @@ void silc_client_receive_channel_key(SilcClient client,
 int silc_client_add_channel_private_key(SilcClient client,
                                        SilcClientConnection conn,
                                        SilcChannelEntry channel,
 int silc_client_add_channel_private_key(SilcClient client,
                                        SilcClientConnection conn,
                                        SilcChannelEntry channel,
+                                       const char *name,
                                        char *cipher,
                                        char *hmac,
                                        unsigned char *key,
                                        char *cipher,
                                        char *hmac,
                                        unsigned char *key,
@@ -520,6 +521,7 @@ int silc_client_add_channel_private_key(SilcClient client,
 
   /* Save the key */
   entry = silc_calloc(1, sizeof(*entry));
 
   /* Save the key */
   entry = silc_calloc(1, sizeof(*entry));
+  entry->name = name ? strdup(name) : NULL;
   entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
   entry->key_len = keymat->enc_key_len / 8;
 
   entry->key = silc_memdup(keymat->send_enc_key, keymat->enc_key_len / 8);
   entry->key_len = keymat->enc_key_len / 8;
 
@@ -565,6 +567,7 @@ int silc_client_del_channel_private_keys(SilcClient client,
     silc_dlist_del(channel->private_keys, entry);
     memset(entry->key, 0, entry->key_len);
     silc_free(entry->key);
     silc_dlist_del(channel->private_keys, entry);
     memset(entry->key, 0, entry->key_len);
     silc_free(entry->key);
+    silc_free(entry->name);
     silc_cipher_free(entry->cipher);
     silc_hmac_free(entry->hmac);
     silc_free(entry);
     silc_cipher_free(entry->cipher);
     silc_hmac_free(entry->hmac);
     silc_free(entry);
@@ -603,6 +606,7 @@ int silc_client_del_channel_private_key(SilcClient client,
       silc_dlist_del(channel->private_keys, entry);
       memset(entry->key, 0, entry->key_len);
       silc_free(entry->key);
       silc_dlist_del(channel->private_keys, entry);
       memset(entry->key, 0, entry->key_len);
       silc_free(entry->key);
+      silc_free(entry->name);
       silc_cipher_free(entry->cipher);
       silc_hmac_free(entry->hmac);
       silc_free(entry);
       silc_cipher_free(entry->cipher);
       silc_hmac_free(entry->hmac);
       silc_free(entry);
@@ -658,6 +662,18 @@ void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
   silc_free(keys);
 }
 
   silc_free(keys);
 }
 
+/* Sets the `key' to be used as current channel private key on the
+   `channel'.  Packet sent after calling this function will be secured
+   with `key'. */
+
+void silc_client_current_channel_private_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcChannelEntry channel,
+                                            SilcChannelPrivateKey key)
+{
+  channel->curr_key = key;
+}
+
 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the 
    channel indicated by the `channel'. NULL if client is not joined on
    the channel. */
 /* Returns the SilcChannelUser entry if the `client_entry' is joined on the 
    channel indicated by the `channel'. NULL if client is not joined on
    the channel. */
index 2ef43aec9245307d993752a0ae37fff1a546ec80..c229b4509655c111fe43e21c6f0fc45d8922a6d7 100644 (file)
@@ -71,7 +71,7 @@ void silc_client_send_private_message(SilcClient client,
   /* We have private message specific key */
 
   /* Get data used in the encryption */
   /* We have private message specific key */
 
   /* Get data used in the encryption */
-  cipher = client_entry->send_key;
+  cipher = conn->send_key;
   hmac = conn->hmac_send;
   block_len = silc_cipher_get_block_len(cipher);
 
   hmac = conn->hmac_send;
   block_len = silc_cipher_get_block_len(cipher);
 
@@ -103,7 +103,6 @@ void silc_client_send_private_message(SilcClient client,
   }
 
   /* Encrypt the header and padding of the packet. */
   }
 
   /* Encrypt the header and padding of the packet. */
-  cipher = conn->send_key;
   silc_packet_encrypt(cipher, hmac, conn->psn_send++,
                      (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + 
                      packetdata.src_id_len + packetdata.dst_id_len +
   silc_packet_encrypt(cipher, hmac, conn->psn_send++,
                      (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + 
                      packetdata.src_id_len + packetdata.dst_id_len +
index ef48ed54fbdbacf53af102c48af8a412c6b83c5a..7d680741f73c2f9b554784423e72c0d1a2afea2b 100644 (file)
@@ -61,14 +61,6 @@ struct SilcChannelUserStruct {
   SilcChannelEntry channel;
 };
 
   SilcChannelEntry channel;
 };
 
-/* Structure to hold one channel private key. */
-struct SilcChannelPrivateKeyStruct {
-  SilcCipher cipher;                 /* The cipher and key */
-  SilcHmac hmac;                     /* The HMAC and hmac key */
-  unsigned char *key;                /* The key data */
-  SilcUInt32 key_len;                /* The key length */
-};
-
 /* Channel entry context. This is allocate for every channel client has
    joined to. This includes for example the channel specific keys */
 struct SilcChannelEntryStruct {
 /* Channel entry context. This is allocate for every channel client has
    joined to. This includes for example the channel specific keys */
 struct SilcChannelEntryStruct {
index 2dcb7a58a8aaf9bf9c05b1d984a5f303d1afe741..1e069138a4b53a51c70a7eed51f7c75c4af4082d 100644 (file)
@@ -68,7 +68,6 @@ typedef struct SilcClientCommandStruct *SilcClientCommand;
 typedef struct SilcClientCommandContextStruct *SilcClientCommandContext;
 typedef struct SilcClientCommandReplyContextStruct 
                                            *SilcClientCommandReplyContext;
 typedef struct SilcClientCommandContextStruct *SilcClientCommandContext;
 typedef struct SilcClientCommandReplyContextStruct 
                                            *SilcClientCommandReplyContext;
-typedef struct SilcChannelPrivateKeyStruct *SilcChannelPrivateKey;
 typedef struct SilcChannelUserStruct *SilcChannelUser;
 
 /* General definitions */
 typedef struct SilcChannelUserStruct *SilcChannelUser;
 
 /* General definitions */
@@ -150,6 +149,27 @@ typedef struct {
 } *SilcPrivateMessageKeys;
 /***/
 
 } *SilcPrivateMessageKeys;
 /***/
 
+/****s* silcclient/SilcClientAPI/SilcChannelPrivateKey
+ *
+ * NAME
+ *
+ *    typedef struct { ... } SilcChannelPrivateKey;
+ *
+ * DESCRIPTION
+ *
+ *    Structure to hold one channel private key. The array of this structure
+ *    is returned by silc_client_list_channel_private_keys function.
+ *
+ * SOURCE
+ */
+typedef struct SilcChannelPrivateKeyStruct {
+  char *name;                        /* Application given name */
+  SilcCipher cipher;                 /* The cipher and key */
+  SilcHmac hmac;                     /* The HMAC and hmac key */
+  unsigned char *key;                /* The key data */
+  SilcUInt32 key_len;                /* The key length */
+} *SilcChannelPrivateKey;
+/***/
 
 /****f* silcclient/SilcClientAPI/SilcAskPassphrase
  *
 
 /****f* silcclient/SilcClientAPI/SilcAskPassphrase
  *
@@ -1471,6 +1491,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *    int silc_client_add_channel_private_key(SilcClient client,
  *                                            SilcClientConnection conn,
  *                                            SilcChannelEntry channel,
  *    int silc_client_add_channel_private_key(SilcClient client,
  *                                            SilcClientConnection conn,
  *                                            SilcChannelEntry channel,
+ *                                            const char *name,
  *                                            char *cipher,
  *                                            char *hmac,
  *                                            unsigned char *key,
  *                                            char *cipher,
  *                                            char *hmac,
  *                                            unsigned char *key,
@@ -1485,6 +1506,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
  *    key in order to decrypt the messages. However, it is possible to have
  *    several private keys per one channel. In this case only some of the
  *    clients on the channel may know the one key and only some the other key.
  *    key in order to decrypt the messages. However, it is possible to have
  *    several private keys per one channel. In this case only some of the
  *    clients on the channel may know the one key and only some the other key.
+ *    The `name' can be application given name for the key.
  *
  *    The private key for channel is optional. If it is not set then the
  *    channel messages are encrypted using the channel key generated by the
  *
  *    The private key for channel is optional. If it is not set then the
  *    channel messages are encrypted using the channel key generated by the
@@ -1510,6 +1532,7 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
 int silc_client_add_channel_private_key(SilcClient client,
                                        SilcClientConnection conn,
                                        SilcChannelEntry channel,
 int silc_client_add_channel_private_key(SilcClient client,
                                        SilcClientConnection conn,
                                        SilcChannelEntry channel,
+                                       const char *name,
                                        char *cipher,
                                        char *hmac,
                                        unsigned char *key,
                                        char *cipher,
                                        char *hmac,
                                        unsigned char *key,
@@ -1598,6 +1621,27 @@ silc_client_list_channel_private_keys(SilcClient client,
 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
                                           SilcUInt32 key_count);
 
 void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
                                           SilcUInt32 key_count);
 
+/****f* silcclient/SilcClientAPI/silc_client_current_channel_private_key
+ *
+ * SYNOPSIS
+ *
+ *    void silc_client_current_channel_private_key(SilcClient client,
+ *                                                 SilcClientConnection conn,
+ *                                                 SilcChannelEntry channel,
+ *                                                 SilcChannelPrivateKey key);
+ *
+ * DESCRIPTION
+ *
+ *    Sets the `key' to be used as current channel private key on the
+ *    `channel'.  Packet sent after calling this function will be secured
+ *    with `key'.
+ *
+ ***/
+void silc_client_current_channel_private_key(SilcClient client,
+                                            SilcClientConnection conn,
+                                            SilcChannelEntry channel,
+                                            SilcChannelPrivateKey key);
+
 
 /* Key Agreement routines (client_keyagr.c) */
 
 
 /* Key Agreement routines (client_keyagr.c) */
 
diff --git a/prepare b/prepare
index e7e4ab8e875cef7b8509b04b197346d1c0cfd526..d3fc25bd10c83c936cae66a8ae9af30ab627ac2b 100755 (executable)
--- a/prepare
+++ b/prepare
@@ -37,7 +37,7 @@
 # SILC Distribution versions. Set here or give the version on the command
 # line as argument.
 #
 # SILC Distribution versions. Set here or give the version on the command
 # line as argument.
 #
-SILC_VERSION=0.8                       # Base version
+SILC_VERSION=0.8.1                     # Base version
 
 #############################################################################
 
 
 #############################################################################