From: Pekka Riikonen Date: Tue, 19 Mar 2002 18:41:30 +0000 (+0000) Subject: Addec multiple channel private key support to Irssi SILC client. X-Git-Tag: silc.toolkit.0.8.1~3 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=b595f4324d9f59209f3b3c8dba8ac49ac66e467b Addec multiple channel private key support to Irssi SILC client. --- diff --git a/CHANGES b/CHANGES index 888671f1..6e419f7f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +Tue Mar 19 20:42:41 EET 2002 Pekka Riikonen + + * 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 * Added silc_rng_get_byte_fast function in to the diff --git a/TODO b/TODO index 7ec1bc17..980ff9d4 100644 --- a/TODO +++ b/TODO @@ -1,16 +1,6 @@ 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. diff --git a/apps/irssi/docs/help/in/key.in b/apps/irssi/docs/help/in/key.in index 9e54b7bd..3d3a7162 100644 --- a/apps/irssi/docs/help/in/key.in +++ b/apps/irssi/docs/help/in/key.in @@ -15,8 +15,8 @@ Types: MSG The command is performed for private messages affecting the . - CHANNEL The command is performed for channel affecting - the . + CHANNEL The command is performed for the channel indicated + by (* matches current channel). Commands: @@ -27,7 +27,7 @@ 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 is `*' then random key + If the type is MSG and the is `*' then random key will be generated automatically. The may be set for both private message and channel private keys and the 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 - `msg' and the is ´*' then all private message + MSG and the is ´*' then all private message keys that you've set will be listed. + change [] + + This command can be used only when type is CHANNEL. This is + used to change the current channel private key. The + 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 [ []] 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 and 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 diff --git a/apps/irssi/silc.conf b/apps/irssi/silc.conf index 3ff0538f..e8741573 100644 --- a/apps/irssi/silc.conf +++ b/apps/irssi/silc.conf @@ -21,6 +21,13 @@ channels = ( { name = "#silc"; chatnet = silcnet; autojoin = No; } ); +# +# Keyboard bindings (BIND command) +# +keyboard = ( + { key = "meta-K"; id = "command"; data = "key channel * change"; } +); + # # Your favorite aliases # diff --git a/apps/irssi/src/fe-common/silc/module-formats.c b/apps/irssi/src/fe-common/silc/module-formats.c index 5ee13d6d..6ac3306f 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.c +++ b/apps/irssi/src/fe-common/silc/module-formats.c @@ -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_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 } }, diff --git a/apps/irssi/src/fe-common/silc/module-formats.h b/apps/irssi/src/fe-common/silc/module-formats.h index 62b2db5a..42422e4b 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.h +++ b/apps/irssi/src/fe-common/silc/module-formats.h @@ -63,6 +63,7 @@ enum { 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, diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index 1952eb90..a0c98fff 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -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; + SILC_CHANNEL_REC *chanrec = NULL; 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]; } - 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 */ @@ -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, - channel_entry, + channel_entry, NULL, 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"); -/* 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 */ } @@ -812,6 +810,48 @@ static void command_key(const char *data, SILC_SERVER_REC *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 " diff --git a/apps/irssi/src/silc/core/silc-channels.h b/apps/irssi/src/silc/core/silc-channels.h index 8a286b73..b572712c 100644 --- a/apps/irssi/src/silc/core/silc-channels.h +++ b/apps/irssi/src/silc/core/silc-channels.h @@ -19,6 +19,7 @@ typedef struct { GSList *banlist; /* list of bans */ GSList *ebanlist; /* list of ban exceptions */ GSList *invitelist; /* invite list */ + SilcUInt32 cur_key; SilcChannelEntry entry; } SILC_CHANNEL_REC; diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 03ccd79f..dcd9bb34 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -295,7 +295,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) /* SYNTAX: INVITE [[@hostname>] */ /* SYNTAX: INVITE [+|-[[@[![@hostname>]]]]] */ /* SYNTAX: KEY MSG set|unset|list|agreement|negotiate [] */ -/* SYNTAX: KEY CHANNEL set|unset|list [] */ +/* SYNTAX: KEY CHANNEL set|unset|list|change [] */ /* SYNTAX: KICK [@] [] */ /* SYNTAX: KILL [@] [] */ /* SYNTAX: OPER [-pubkey] */ diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 485decf0..ff2f6d02 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -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, + const char *name, 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)); + 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; @@ -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_free(entry->name); 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_free(entry->name); 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); } +/* 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. */ diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 2ef43aec..c229b450 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -71,7 +71,7 @@ void silc_client_send_private_message(SilcClient client, /* 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); @@ -103,7 +103,6 @@ void silc_client_send_private_message(SilcClient client, } /* 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 + diff --git a/lib/silcclient/idlist.h b/lib/silcclient/idlist.h index ef48ed54..7d680741 100644 --- a/lib/silcclient/idlist.h +++ b/lib/silcclient/idlist.h @@ -61,14 +61,6 @@ struct SilcChannelUserStruct { 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 { diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 2dcb7a58..1e069138 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -68,7 +68,6 @@ typedef struct SilcClientCommandStruct *SilcClientCommand; typedef struct SilcClientCommandContextStruct *SilcClientCommandContext; typedef struct SilcClientCommandReplyContextStruct *SilcClientCommandReplyContext; -typedef struct SilcChannelPrivateKeyStruct *SilcChannelPrivateKey; typedef struct SilcChannelUserStruct *SilcChannelUser; /* General definitions */ @@ -150,6 +149,27 @@ typedef struct { } *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 * @@ -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, + * const char *name, * 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. + * 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 @@ -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, + const char *name, 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); +/****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) */ diff --git a/prepare b/prepare index e7e4ab8e..d3fc25bd 100755 --- a/prepare +++ b/prepare @@ -37,7 +37,7 @@ # 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 #############################################################################