SilcClient client = conn->client;
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
char *topic;
SilcUInt32 len;
SilcID id;
silc_client_command_callback(cmd, channel, channel->topic);
out:
+ silc_client_unref_channel(client, conn, channel);
silc_fsm_next(fsm, silc_client_command_reply_processed);
return SILC_FSM_CONTINUE;
}
SilcClient client = conn->client;
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
unsigned char *tmp;
SilcUInt32 len;
SilcArgumentPayload invite_args = NULL;
silc_argument_payload_free(invite_args);
out:
+ silc_client_unref_channel(client, conn, channel);
silc_fsm_next(fsm, silc_client_command_reply_processed);
return SILC_FSM_CONTINUE;
}
{
SilcClientCommandContext cmd = context;
SilcChannelEntry channel = cmd->context;
+ SilcCommandPayload payload = silc_fsm_get_state_context(&cmd->thread);
+ SilcArgumentPayload args = silc_command_get_args(payload);
+ SilcUInt32 list_count;
+ unsigned char *tmp;
+ char msg[512];
+
+ if (!clients) {
+ silc_snprintf(msg, sizeof(msg), "Error resolving channel %s user list",
+ channel->channel_name);
+ SAY(client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, msg);
+ } else {
+ tmp = silc_argument_get_arg_type(args, 12, NULL);
+ if (tmp) {
+ SILC_GET32_MSB(list_count, tmp);
+ if (list_count - silc_dlist_count(clients) > 5) {
+ silc_snprintf(msg, sizeof(msg),
+ "Channel %s user list was not fully resolved. "
+ "The channel may not be fully synced.",
+ channel->channel_name);
+ SAY(client, conn, SILC_CLIENT_MESSAGE_WARNING, msg);
+ }
+ }
+ }
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);
}
/* Get the list count */
tmp = silc_argument_get_arg_type(args, 12, &len);
- if (!tmp) {
+ if (!tmp || len != 4) {
ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
/* Add clients we received in the reply to the channel */
for (i = 0; i < list_count; i++) {
SilcUInt16 idp_len;
- SilcUInt32 mode;
SilcID id;
SilcClientEntry client_entry;
/* 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 */
SilcArgumentPayload args = silc_command_get_args(payload);
unsigned char *tmp;
SilcUInt32 mode;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcUInt32 len;
SilcPublicKey public_key = NULL;
SilcID id;
silc_client_command_callback(cmd, channel, mode, public_key,
channel->channel_pubkeys, channel->user_limit);
+ silc_rwlock_wrlock(channel->internal.lock);
+
+ /* If founder key changed, update it */
+ if (public_key &&
+ (!channel->founder_key ||
+ !silc_pkcs_public_key_compare(public_key, channel->founder_key))) {
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ channel->founder_key = public_key;
+ public_key = NULL;
+ }
+
+ silc_rwlock_unlock(channel->internal.lock);
+
out:
+ silc_client_unref_channel(client, conn, channel);
if (public_key)
silc_pkcs_public_key_free(public_key);
silc_fsm_next(fsm, silc_client_command_reply_processed);
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
SilcClientEntry client_entry;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcChannelUser chu;
unsigned char *modev;
SilcUInt32 len, mode;
silc_client_unref_client(client, conn, client_entry);
out:
+ silc_client_unref_channel(client, conn, channel);
silc_fsm_next(fsm, silc_client_command_reply_processed);
return SILC_FSM_CONTINUE;
}
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
SilcClientEntry client_entry;
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
SilcID id;
/* Sanity checks */
silc_client_unref_client(client, conn, client_entry);
out:
+ silc_client_unref_channel(client, conn, channel);
silc_fsm_next(fsm, silc_client_command_reply_processed);
return SILC_FSM_CONTINUE;
}
SilcClient client = conn->client;
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
- SilcChannelEntry channel;
+ SilcChannelEntry channel = NULL;
unsigned char *tmp;
SilcUInt32 len;
SilcArgumentPayload invite_args = NULL;
silc_argument_payload_free(invite_args);
out:
+ silc_client_unref_channel(client, conn, channel);
silc_fsm_next(fsm, silc_client_command_reply_processed);
return SILC_FSM_CONTINUE;
}
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
SilcChannelEntry channel;
+ SilcCipher key;
+ SilcHmac hmac;
SilcID id;
/* Sanity checks */
/* 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);
SilcCommandPayload payload = state_context;
SilcArgumentPayload args = silc_command_get_args(payload);
unsigned char *tmp;
- SilcUInt32 tmp_len, list_count;
- SilcUInt16 idp_len, mode;
+ SilcUInt32 tmp_len, list_count, mode;
+ SilcUInt16 idp_len;
SilcHashTableList htl;
SilcBufferStruct client_id_list, client_mode_list;
SilcChannelEntry channel = NULL;
goto out;
}
if (!silc_public_key_payload_decode(tmp, len, &public_key)) {
+ SAY(client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR,
+ "Cannot decode public key: malformed/unsupported public key");
ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}