From: Pekka Riikonen Date: Thu, 29 Mar 2001 09:50:35 +0000 (+0000) Subject: updates. X-Git-Tag: SILC.0.1~80 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=f9a39597892c325e87a15255f346bf126760c486 updates. --- diff --git a/CHANGES b/CHANGES index d376b6a1..e030b803 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,9 @@ Thu Mar 29 15:26:25 EEST 2001 Pekka Riikonen other cells as well. Added this support for the router in the silcd/packet_receive.c. + * Added new local command NOTICE to send notice message on + channel. Affected file silc/local_command.[ch]. + Wed Mar 28 23:55:54 EEST 2001 Pekka Riikonen * Added new local command ME to the client. It is used to send diff --git a/TODO b/TODO index ea32c294..cc211d02 100644 --- a/TODO +++ b/TODO @@ -25,11 +25,6 @@ TODO General TODO In SILC Client Library =========================== - o TODO in commands (lib/silcclient/command.c and - silc/silclient/command_reply.c): - - o RESTART command is not implemented - o Client library crashes if for example server timeouts protocol execution and disconnects the client. The client, on the other hand may still assume that the connection is active, even after receiving @@ -82,6 +77,8 @@ TODO In SILC Server clients before setting the status. Good fix for this would be to make sure that the clients table does not include any unregistered clients in the first place. + o Cleanup LEAVE command's channel key sending, it can be done + simpler by one function: silc_server_send_channel_key. o TODO in notify types (packet_receive.c): diff --git a/apps/silc/client_ops.c b/apps/silc/client_ops.c index 1a094760..dce61eb8 100644 --- a/apps/silc/client_ops.c +++ b/apps/silc/client_ops.c @@ -56,7 +56,7 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn, silc_print(client, "* %s %s", sender ? sender->nickname : "[]", msg); else if (flags & SILC_MESSAGE_FLAG_NOTICE) - silc_print(client, "-%s- %s", sender ? sender->nickname : "[]", + silc_print(client, "- %s %s", sender ? sender->nickname : "[]", msg); else silc_print(client, "<%s> %s", sender ? sender->nickname : "[]", @@ -67,7 +67,7 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn, "[]", channel->channel_name, msg); else if (flags & SILC_MESSAGE_FLAG_NOTICE) - silc_print(client, "-%s:%s- %s", sender ? sender->nickname : + silc_print(client, "- %s:%s %s", sender ? sender->nickname : "[]", channel->channel_name, msg); else diff --git a/apps/silc/local_command.c b/apps/silc/local_command.c index b32f07f4..2f18ae03 100644 --- a/apps/silc/local_command.c +++ b/apps/silc/local_command.c @@ -33,6 +33,7 @@ SilcClientCommand silc_local_command_list[] = SILC_CLIENT_LCMD(away, AWAY, "AWAY", 0, 2), SILC_CLIENT_LCMD(key, KEY, "KEY", 0, 7), SILC_CLIENT_LCMD(me, ME, "ME", 0, 3), + SILC_CLIENT_LCMD(notice, NOTICE, "NOTICE", 0, 3), { NULL, 0, NULL, 0, 0 }, }; @@ -741,3 +742,51 @@ SILC_CLIENT_LCMD_FUNC(me) out: silc_client_command_free(cmd); } + +/* Sends an notice to the channel. */ + +SILC_CLIENT_LCMD_FUNC(notice) +{ + SilcClientCommandContext cmd = (SilcClientCommandContext)context; + SilcClientConnection conn = cmd->conn; + SilcClient client = cmd->client; + SilcChannelEntry channel_entry; + char *name; + + if (!cmd->conn) { + silc_say(client, conn, + "You are not connected to a server, use /SERVER to connect"); + goto out; + } + + if (cmd->argc < 3) { + silc_say(client, conn, "Usage: /ME "); + goto out; + } + + if (cmd->argv[1][0] == '*') { + if (!conn->current_channel) { + cmd->client->ops->say(cmd->client, conn, "You are not on any channel"); + goto out; + } + name = conn->current_channel->channel_name; + } else { + name = cmd->argv[1]; + } + + channel_entry = silc_client_get_channel(client, conn, name); + if (!channel_entry) { + silc_say(client, conn, "You are not on that channel"); + goto out; + } + + /* Send the action message */ + silc_client_send_channel_message(client, conn, channel_entry, NULL, + SILC_MESSAGE_FLAG_NOTICE, + cmd->argv[2], cmd->argv_lens[2], TRUE); + + silc_print(client, "- %s %s", conn->nickname, cmd->argv[2]); + + out: + silc_client_command_free(cmd); +} diff --git a/apps/silc/local_command.h b/apps/silc/local_command.h index 0e4fc3e9..134e0fdf 100644 --- a/apps/silc/local_command.h +++ b/apps/silc/local_command.h @@ -33,6 +33,7 @@ extern SilcClientCommand silc_local_command_list[]; #define SILC_LOCAL_COMMAND_AWAY 6 #define SILC_LOCAL_COMMAND_KEY 7 #define SILC_LOCAL_COMMAND_ME 8 +#define SILC_LOCAL_COMMAND_NOTICE 9 /* Macros */ @@ -55,5 +56,6 @@ SILC_CLIENT_LCMD_FUNC(server); SILC_CLIENT_LCMD_FUNC(away); SILC_CLIENT_LCMD_FUNC(key); SILC_CLIENT_LCMD_FUNC(me); +SILC_CLIENT_LCMD_FUNC(notice); #endif diff --git a/apps/silcd/command.c b/apps/silcd/command.c index ed29b05e..0f712ea0 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -2665,7 +2665,7 @@ static void silc_server_command_join_channel(SilcServer server, unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4]; SilcClientEntry client; SilcChannelClientEntry chl; - SilcBuffer reply, chidp, clidp, keyp, user_list, mode_list; + SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list; unsigned short ident = silc_command_get_ident(cmd->payload); char check[512]; @@ -2774,9 +2774,10 @@ static void silc_server_command_join_channel(SilcServer server, /* Send the channel key. This is broadcasted to the channel but is not sent to the client who is joining to the channel. */ - silc_server_send_channel_key(server, NULL, channel, - server->server_type == SILC_ROUTER ? - FALSE : !server->standalone); + if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) + silc_server_send_channel_key(server, NULL, channel, + server->server_type == SILC_ROUTER ? + FALSE : !server->standalone); /* Join the client to the channel by adding it to channel's user list. Add also the channel to client entry's channels list for fast cross- @@ -2800,13 +2801,17 @@ static void silc_server_command_join_channel(SilcServer server, SILC_PUT32_MSB(channel->mode, mode); SILC_PUT32_MSB(created, tmp2); SILC_PUT32_MSB(user_count, tmp3); - tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL); - keyp = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, tmp, - strlen(channel->channel_key-> - cipher->name), - channel->channel_key->cipher->name, - channel->key_len / 8, channel->key); - silc_free(tmp); + + if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { + tmp = silc_id_id2str(channel->id, SILC_ID_CHANNEL); + keyp = silc_channel_key_payload_encode(SILC_ID_CHANNEL_LEN, tmp, + strlen(channel->channel_key-> + cipher->name), + channel->channel_key->cipher->name, + channel->key_len / 8, channel->key); + silc_free(tmp); + } + reply = silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN, SILC_STATUS_OK, ident, 13, @@ -2816,7 +2821,8 @@ static void silc_server_command_join_channel(SilcServer server, 4, clidp->data, clidp->len, 5, mode, 4, 6, tmp2, 4, - 7, keyp->data, keyp->len, + 7, keyp ? keyp->data : NULL, + keyp ? keyp->len : 0, 8, channel->ban_list, channel->ban_list ? strlen(channel->ban_list) : 0, @@ -3945,14 +3951,16 @@ SILC_SERVER_CMD_FUNC(kick) target_client->id, SILC_ID_CLIENT_LEN, comment); - /* Re-generate channel key */ - silc_server_create_channel_key(server, channel, 0); - - /* Send the channel key to the channel. The key of course is not sent - to the client who was kicked off the channel. */ - silc_server_send_channel_key(server, target_client->connection, channel, - server->server_type == SILC_ROUTER ? - FALSE : !server->standalone); + if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { + /* Re-generate channel key */ + silc_server_create_channel_key(server, channel, 0); + + /* Send the channel key to the channel. The key of course is not sent + to the client who was kicked off the channel. */ + silc_server_send_channel_key(server, target_client->connection, channel, + server->server_type == SILC_ROUTER ? + FALSE : !server->standalone); + } out: silc_server_command_free(cmd); @@ -4322,35 +4330,39 @@ SILC_SERVER_CMD_FUNC(leave) if (!i) goto out; - /* Re-generate channel key */ - silc_server_create_channel_key(server, channel, 0); + if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { + /* Re-generate channel key */ + silc_server_create_channel_key(server, channel, 0); - /* Encode channel key payload to be distributed on the channel */ - packet = - silc_channel_key_payload_encode(len, tmp, - strlen(channel->channel_key->cipher->name), - channel->channel_key->cipher->name, - channel->key_len / 8, channel->key); + /* Encode channel key payload to be distributed on the channel */ + packet = + silc_channel_key_payload_encode(len, tmp, + strlen(channel->channel_key-> + cipher->name), + channel->channel_key->cipher->name, + channel->key_len / 8, channel->key); + + /* If we are normal server then we will send it to our router. If we + are router we will send it to all local servers that has clients on + the channel */ + if (server->server_type == SILC_SERVER) { + if (!server->standalone) + silc_server_packet_send(server, + cmd->server->router->connection, + SILC_PACKET_CHANNEL_KEY, 0, packet->data, + packet->len, FALSE); + } else { + + } - /* If we are normal server then we will send it to our router. If we - are router we will send it to all local servers that has clients on - the channel */ - if (server->server_type == SILC_SERVER) { - if (!server->standalone) - silc_server_packet_send(server, - cmd->server->router->connection, - SILC_PACKET_CHANNEL_KEY, 0, packet->data, - packet->len, FALSE); - } else { + /* Send to locally connected clients on the channel */ + silc_server_packet_send_local_channel(server, channel, + SILC_PACKET_CHANNEL_KEY, 0, + packet->data, packet->len, FALSE); + silc_buffer_free(packet); } - /* Send to locally connected clients on the channel */ - silc_server_packet_send_local_channel(server, channel, - SILC_PACKET_CHANNEL_KEY, 0, - packet->data, packet->len, FALSE); - - silc_buffer_free(packet); silc_free(id); out: diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index fe25519c..53124d40 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -622,7 +622,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) unsigned char *id_string; char *channel_name, *tmp; unsigned int mode, created; - SilcBuffer keyp, client_id_list, client_mode_list; + SilcBuffer keyp = NULL, client_id_list, client_mode_list; COMMAND_CHECK_STATUS; @@ -660,11 +660,11 @@ SILC_SERVER_CMD_REPLY_FUNC(join) /* Get channel key */ tmp = silc_argument_get_arg_type(cmd->args, 7, &len); - if (!tmp) - goto out; - keyp = silc_buffer_alloc(len); - silc_buffer_pull_tail(keyp, SILC_BUFFER_END(keyp)); - silc_buffer_put(keyp, tmp, len); + if (tmp) { + keyp = silc_buffer_alloc(len); + silc_buffer_pull_tail(keyp, SILC_BUFFER_END(keyp)); + silc_buffer_put(keyp, tmp, len); + } id = silc_id_payload_parse_id(id_string, id_len); if (!id) @@ -768,8 +768,11 @@ SILC_SERVER_CMD_REPLY_FUNC(join) entry->mode = mode; /* Save channel key */ - silc_server_save_channel_key(server, keyp, entry); - silc_buffer_free(keyp); + if (!(entry->mode & SILC_CHANNEL_MODE_PRIVKEY)) { + silc_server_save_channel_key(server, keyp, entry); + } + if (keyp) + silc_buffer_free(keyp); /* Save the users to the channel */ silc_server_save_users_on_channel(server, cmd->sock, entry, diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 4cdb7e07..38b2a86a 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -422,6 +422,20 @@ void silc_server_notify(SilcServer server, SILC_GET32_MSB(mode, tmp); + /* If the channel had private keys set and the mode was removed then + we must re-generate and re-distribute a new channel key */ + if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY && + !(mode & SILC_CHANNEL_MODE_PRIVKEY)) { + /* Re-generate channel key */ + silc_server_create_channel_key(server, channel, 0); + + /* Send the channel key. This sends it to our local clients and if + we are normal server to our router as well. */ + silc_server_send_channel_key(server, NULL, channel, + server->server_type == SILC_ROUTER ? + FALSE : !server->standalone); + } + /* Change mode */ channel->mode = mode; silc_free(channel_id); @@ -1176,7 +1190,9 @@ void silc_server_channel_key(SilcServer server, SilcBuffer buffer = packet->buffer; SilcChannelEntry channel; - if (packet->src_id_type != SILC_ID_SERVER) + if (packet->src_id_type != SILC_ID_SERVER || + (server->server_type == SILC_ROUTER && + sock->type == SILC_SOCKET_TYPE_ROUTER)) return; /* Save the channel key */ @@ -1736,21 +1752,25 @@ void silc_server_new_channel(SilcServer server, /* Create new key for the channel and send it to the server and everybody else possibly on the channel. */ - silc_server_create_channel_key(server, channel, 0); - - /* Send to the channel */ - silc_server_send_channel_key(server, sock, channel, FALSE); + if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { + silc_server_create_channel_key(server, channel, 0); + + /* Send to the channel */ + silc_server_send_channel_key(server, sock, channel, FALSE); + + /* Send to the server */ + chk = silc_channel_key_payload_encode(id_len, id, + strlen(channel->channel_key-> + cipher->name), + channel->channel_key-> + cipher->name, + channel->key_len / 8, + channel->key); + silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, + chk->data, chk->len, FALSE); + silc_buffer_free(chk); + } - /* Send to the server */ - chk = silc_channel_key_payload_encode(id_len, id, - strlen(channel->channel_key-> - cipher->name), - channel->channel_key->cipher->name, - channel->key_len / 8, - channel->key); - 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 diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index f88b63e8..e2f5d0e6 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -676,10 +676,11 @@ void silc_server_packet_relay_to_channel(SilcServer server, } else { /* Private key mode is set, we don't have the channel key, so just re-encrypt the entire packet and send it to the router. */ - silc_server_packet_send_dest(server, sock, - SILC_PACKET_CHANNEL_MESSAGE, 0, - channel->id, SILC_ID_CHANNEL, - data, data_len, force_send); + silc_server_packet_send_srcdest(server, sock, + SILC_PACKET_CHANNEL_MESSAGE, 0, + sender, sender_type, + channel->id, SILC_ID_CHANNEL, + data, data_len, force_send); } continue; } diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 54dc325a..0bb81178 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -2300,7 +2300,7 @@ void silc_server_remove_from_channels(SilcServer server, signoff_message, signoff_message ? strlen(signoff_message) : 0); - if (keygen) { + if (keygen && !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { /* Re-generate channel key */ silc_server_create_channel_key(server, channel, 0); @@ -2575,6 +2575,11 @@ void silc_server_create_channel_key(SilcServer server, SILC_LOG_DEBUG(("Generating channel key")); + if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) { + SILC_LOG_DEBUG(("Channel has private keys, will not generate new key")); + return; + } + if (!channel->channel_key) if (!silc_cipher_alloc("aes-256-cbc", &channel->channel_key)) return; diff --git a/apps/silcd/testi2.conf b/apps/silcd/testi2.conf index 90595798..62805382 100644 --- a/apps/silcd/testi2.conf +++ b/apps/silcd/testi2.conf @@ -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,12 +47,15 @@ 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:1336:1:1 [RouterConnection] -212.146.42.253:passwd:priikone:1335:1:1:0 +10.2.1.7:passwd:priikone:1333:1:1:0 [DenyConnection] + +[motd] +./motd diff --git a/doc/draft-riikonen-silc-pp-01.nroff b/doc/draft-riikonen-silc-pp-01.nroff index 67b5fb79..b289427d 100644 --- a/doc/draft-riikonen-silc-pp-01.nroff +++ b/doc/draft-riikonen-silc-pp-01.nroff @@ -1488,7 +1488,12 @@ o Flags (2 bytes) - Includes the flags of the channel The sender is performing an action and the message is the indication of the action. - 0x0008 - 0x0200 RESERVED + 0x0008 SILC_MESSAGE_FLAG_NOTICE + + The message is for example and informational notice + type message. + + 0x0010 - 0x0200 RESERVED Reserved for future flags diff --git a/doc/draft-riikonen-silc-spec-01.nroff b/doc/draft-riikonen-silc-spec-01.nroff index 4bf88c49..c74e7cbb 100644 --- a/doc/draft-riikonen-silc-spec-01.nroff +++ b/doc/draft-riikonen-silc-spec-01.nroff @@ -2550,13 +2550,13 @@ List of all defined commands in SILC follows. Reply messages to the command: Max Arguments: 14 - Arguments: (1) (2) - (3) (4) - (5) (6) - (7) (8) [] - (9) [] (10) [] - (11) [] (12) - (13) (14) + Arguments: (1) (2) + (3) (4) + (5) (6) + (7) [] (8) [] + (9) [] (10) [] + (11) [] (12) + (13) (14) This command replies with the channel name requested by the client, channel ID of the channel and topic of the channel @@ -2988,9 +2988,6 @@ List of all defined commands in SILC follows. SILC_STATUS_ERR_NO_SERVER_PRIV - - - 21 SILC_COMMAND_CLOSE Max Arguments: 2 diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 26ee63f9..186b1e45 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -52,13 +52,6 @@ void silc_client_send_channel_message(SilcClient client, SILC_LOG_DEBUG(("Sending packet to channel")); - if (!channel || !channel->hmac || - (!channel->channel_key && !key && !channel->private_keys)) { - client->ops->say(client, conn, - "Cannot talk to channel: key does not exist"); - return; - } - /* Take the key to be used */ if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) { if (key) { @@ -90,6 +83,9 @@ void silc_client_send_channel_message(SilcClient client, hmac = channel->hmac; } + if (!cipher || !hmac) + return; + /* Generate IV */ iv_len = silc_cipher_get_block_len(cipher); if (channel->iv[0] == '\0') @@ -310,9 +306,6 @@ void silc_client_save_channel_key(SilcClientConnection conn, silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash)); memset(hash, 0, sizeof(hash)); - /* Client is now joined to the channel */ - channel->on_channel = TRUE; - out: silc_free(id); silc_channel_key_payload_free(payload); @@ -342,7 +335,7 @@ void silc_client_receive_channel_key(SilcClient client, 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. - if `cipher' and/or `hmac' is NULL then default values will be used + If `cipher' and/or `hmac' is NULL then default values will be used (aes-256-cbc for cipher and hmac-sha1-96 for hmac). The private key for channel is optional. If it is not set then the @@ -373,6 +366,7 @@ int silc_client_add_channel_private_key(SilcClient client, { SilcChannelPrivateKey entry; unsigned char hash[32]; + SilcSKEKeyMaterial *keymat; if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) return FALSE; @@ -388,6 +382,13 @@ int silc_client_add_channel_private_key(SilcClient client, if (!silc_hmac_is_supported(hmac)) return FALSE; + /* Produce the key material */ + keymat = silc_calloc(1, sizeof(*keymat)); + if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, + client->md5hash, keymat) + != SILC_SKE_STATUS_OK) + return FALSE; + /* Remove the current key, if it exists. */ if (channel->channel_key) { silc_cipher_free(channel->channel_key); @@ -397,25 +398,27 @@ int silc_client_add_channel_private_key(SilcClient client, channel->key = NULL; channel->key_len = 0; } - if (channel->hmac) + if (channel->hmac) { silc_hmac_free(channel->hmac); + channel->hmac = NULL; + } if (!channel->private_keys) channel->private_keys = silc_dlist_init(); /* Save the key */ entry = silc_calloc(1, sizeof(*entry)); - entry->key = silc_calloc(key_len, sizeof(*entry->key)); - memcpy(entry->key, key, key_len); - entry->key_len = key_len; + entry->key = silc_calloc(keymat->enc_key_len / 8, sizeof(*entry->key)); + memcpy(entry->key, keymat->send_enc_key, keymat->enc_key_len / 8); + entry->key_len = keymat->enc_key_len / 8; /* Allocate the cipher and set the key*/ silc_cipher_alloc(cipher, &entry->cipher); - silc_cipher_set_key(entry->cipher, key, key_len * 8); + silc_cipher_set_key(entry->cipher, entry->key, keymat->enc_key_len); /* Generate HMAC key from the channel key data and set it */ silc_hmac_alloc(hmac, NULL, &entry->hmac); - silc_hash_make(entry->hmac->hash, key, key_len, hash); + silc_hash_make(entry->hmac->hash, entry->key, entry->key_len, hash); silc_hmac_set_key(entry->hmac, hash, silc_hash_len(entry->hmac->hash)); memset(hash, 0, sizeof(hash)); @@ -425,6 +428,9 @@ int silc_client_add_channel_private_key(SilcClient client, if (!channel->curr_key) channel->curr_key = entry; + /* Free the key material */ + silc_ske_free_key_material(keymat); + return TRUE; } diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index f5f2c875..f2296006 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -1700,7 +1700,6 @@ SILC_CLIENT_CMD_FUNC(connect) SILC_CLIENT_CMD_FUNC(restart) { SilcClientCommandContext cmd = (SilcClientCommandContext)context; - SilcClientConnection conn = cmd->conn; SilcBuffer buffer; if (!cmd->conn) { diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index f091e8cf..be33b9ca 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -913,7 +913,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) SilcChannelUser chu; unsigned int argc, mode, len, list_count; char *topic, *tmp, *channel_name = NULL, *hmac; - SilcBuffer keyp, client_id_list, client_mode_list; + SilcBuffer keyp = NULL, client_id_list, client_mode_list; int i; SILC_LOG_DEBUG(("Start")); @@ -969,14 +969,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) /* Get channel key */ tmp = silc_argument_get_arg_type(cmd->args, 7, &len); - if (!tmp) { - silc_id_payload_free(idp); - silc_free(channel_name); - goto out; + if (tmp) { + keyp = silc_buffer_alloc(len); + silc_buffer_pull_tail(keyp, SILC_BUFFER_END(keyp)); + silc_buffer_put(keyp, tmp, len); } - keyp = silc_buffer_alloc(len); - silc_buffer_pull_tail(keyp, SILC_BUFFER_END(keyp)); - silc_buffer_put(keyp, tmp, len); /* Get topic */ topic = silc_argument_get_arg_type(cmd->args, 10, NULL); @@ -1069,17 +1066,23 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) client_mode_list->head); /* Save channel key */ - silc_client_save_channel_key(conn, keyp, channel); + if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) + silc_client_save_channel_key(conn, keyp, channel); + + /* Client is now joined to the channel */ + channel->on_channel = TRUE; /* Notify application */ - COMMAND_REPLY((ARGS, channel_name, channel, mode, 0, keyp->head, NULL, + COMMAND_REPLY((ARGS, channel_name, channel, mode, 0, + keyp ? keyp->head : NULL, NULL, NULL, topic, hmac, list_count, client_id_list, client_mode_list)); /* Execute any pending command callbacks */ SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_JOIN); - silc_buffer_free(keyp); + if (keyp) + silc_buffer_free(keyp); silc_buffer_free(client_id_list); silc_buffer_free(client_mode_list); diff --git a/lib/silccore/silcchannel.h b/lib/silccore/silcchannel.h index 33422f82..53b24990 100644 --- a/lib/silccore/silcchannel.h +++ b/lib/silccore/silcchannel.h @@ -43,7 +43,8 @@ typedef unsigned short SilcMessageFlags; #define SILC_MESSAGE_FLAG_AUTOREPLY 0x0001 #define SILC_MESSAGE_FLAG_NOREPLY 0x0002 #define SILC_MESSAGE_FLAG_ACTION 0x0004 -#define SILC_MESSAGE_FLAG_RESERVED 0x0008 /* to 0x0200 */ +#define SILC_MESSAGE_FLAG_NOTICE 0x0008 +#define SILC_MESSAGE_FLAG_RESERVED 0x0010 /* to 0x0200 */ #define SILC_MESSAGE_FLAG_PRIVATE 0x0400 /* to 0x8000 */ /* Prototypes */