X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=lib%2Fsilcclient%2Fcommand_reply.c;h=ede887535fdcdc97b6219d0c8d73f11b45867021;hp=ee71a4264b0c6fa3d7f107fd98fc2a72661bfa02;hb=805fddcf6431e784f9f77114782a90c9d12f9cbe;hpb=4d3f87f2f076bd332fa73f878fe198b7a94671b5 diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index ee71a426..ede88753 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -118,6 +118,7 @@ static void silc_client_command_process_error(SilcClientCommandContext cmd, client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id); if (client_entry) { silc_client_remove_from_channels(client, conn, client_entry); + client_entry->internal.valid = FALSE; silc_client_del_client(client, conn, client_entry); silc_client_unref_client(client, conn, client_entry); } @@ -947,6 +948,7 @@ SILC_FSM_STATE(silc_client_command_reply_kill) /* Remove the client */ if (client_entry) { silc_client_remove_from_channels(client, conn, client_entry); + client_entry->internal.valid = FALSE; silc_client_del_client(client, conn, client_entry); silc_client_unref_client(client, conn, client_entry); } @@ -1138,7 +1140,7 @@ silc_client_command_reply_join_resolved(SilcClient client, channel->internal.resolve_cmd_ident = 0; silc_client_unref_channel(client, conn, channel); - SILC_FSM_CALL_CONTINUE(&cmd->thread); + SILC_FSM_CALL_CONTINUE_SYNC(&cmd->thread); } @@ -1287,8 +1289,13 @@ SILC_FSM_STATE(silc_client_command_reply_join) /* Get channel key and save it */ tmp = silc_argument_get_arg_type(args, 7, &len); if (tmp) { - silc_buffer_set(&keyp, tmp, len); - silc_client_save_channel_key(client, conn, &keyp, channel); + /* If channel key already exists on the channel then while resolving + the user list we have already received new key from server. Don't + replace it with this old key. */ + if (!channel->internal.send_key) { + silc_buffer_set(&keyp, tmp, len); + silc_client_save_channel_key(client, conn, &keyp, channel); + } } /* Get topic */ @@ -1809,6 +1816,8 @@ SILC_FSM_STATE(silc_client_command_reply_leave) SilcCommandPayload payload = state_context; SilcArgumentPayload args = silc_command_get_args(payload); SilcChannelEntry channel; + SilcCipher key; + SilcHmac hmac; SilcID id; /* Sanity checks */ @@ -1834,6 +1843,32 @@ SILC_FSM_STATE(silc_client_command_reply_leave) /* Notify application */ silc_client_command_callback(cmd, channel); + /* Remove old keys and stuff. The channel may remain even after leaving + but we want to remove these always. */ + if (channel->internal.send_key) + silc_cipher_free(channel->internal.send_key); + channel->internal.send_key = NULL; + if (channel->internal.receive_key) + silc_cipher_free(channel->internal.receive_key); + channel->internal.receive_key = NULL; + if (channel->internal.hmac) + silc_hmac_free(channel->internal.hmac); + channel->internal.hmac = NULL; + if (channel->internal.old_channel_keys) { + silc_dlist_start(channel->internal.old_channel_keys); + while ((key = silc_dlist_get(channel->internal.old_channel_keys))) + silc_cipher_free(key); + silc_dlist_uninit(channel->internal.old_channel_keys); + } + channel->internal.old_channel_keys = NULL; + if (channel->internal.old_hmacs) { + silc_dlist_start(channel->internal.old_hmacs); + while ((hmac = silc_dlist_get(channel->internal.old_hmacs))) + silc_hmac_free(hmac); + silc_dlist_uninit(channel->internal.old_hmacs); + } + channel->internal.old_hmacs = NULL; + /* Now delete the channel. */ silc_client_empty_channel(client, conn, channel); silc_client_del_channel(client, conn, channel);