+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
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.
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:
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.
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.
+ 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
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
{ name = "#silc"; chatnet = silcnet; autojoin = No; }
);
+#
+# Keyboard bindings (BIND command)
+#
+keyboard = (
+ { key = "meta-K"; id = "command"; data = "key channel * change"; }
+);
+
#
# Your favorite aliases
#
{ "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 } },
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,
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;
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);
- cmd_return_error(CMDERR_NOT_JOINED);
+ cmd_return_error(CMDERR_CHAN_NOT_FOUND);
}
+ channel_entry = chanrec->entry;
}
/* Set command */
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])) {
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;
- }
- else {
+ } else {
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;
- }
- port = settings_get_int("auto_bind_port");
+ port = settings_get_int("auto_bind_port");
}
} /* if use_auto_addr */
}
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> "
GSList *banlist; /* list of bans */
GSList *ebanlist; /* list of ban exceptions */
GSList *invitelist; /* invite list */
+ SilcUInt32 cur_key;
SilcChannelEntry entry;
} SILC_CHANNEL_REC;
/* 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] */
int silc_client_add_channel_private_key(SilcClient client,
SilcClientConnection conn,
SilcChannelEntry channel,
+ const char *name,
char *cipher,
char *hmac,
unsigned char *key,
/* 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;
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_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_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. */
/* 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);
}
/* 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 +
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 {
typedef struct SilcClientCommandContextStruct *SilcClientCommandContext;
typedef struct SilcClientCommandReplyContextStruct
*SilcClientCommandReplyContext;
-typedef struct SilcChannelPrivateKeyStruct *SilcChannelPrivateKey;
typedef struct SilcChannelUserStruct *SilcChannelUser;
/* General definitions */
} *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
*
* int silc_client_add_channel_private_key(SilcClient client,
* SilcClientConnection conn,
* SilcChannelEntry channel,
+ * const char *name,
* char *cipher,
* char *hmac,
* unsigned char *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
int silc_client_add_channel_private_key(SilcClient client,
SilcClientConnection conn,
SilcChannelEntry channel,
+ const char *name,
char *cipher,
char *hmac,
unsigned char *key,
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) */
# 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
#############################################################################