SilcChannelClientResolve res = (SilcChannelClientResolve)context;
if (clients_count == 1) {
- SilcIDCacheEntry id_cache = NULL;
SilcChannelEntry channel;
unsigned char *message;
- if (!silc_idcache_find_by_id_one(conn->channel_cache, res->channel_id,
- &id_cache))
+ channel = silc_client_get_channel_by_id(client, conn, res->channel_id);
+ if (!channel)
goto out;
- channel = (SilcChannelEntry)id_cache->context;
+ /* If this client is not on channel, add it there since it clearly
+ is there. */
+ if (!silc_client_on_channel(channel, clients[0])) {
+ SilcChannelUser chu = silc_calloc(1, sizeof(*chu));
+ chu->client = clients[0];
+ chu->channel = channel;
+ silc_hash_table_add(channel->user_list, clients[0], chu);
+ silc_hash_table_add(clients[0]->channels, channel, chu);
+ }
+
message = silc_channel_message_get_data(res->payload, NULL);
/* Pass the message to application */
SilcChannelMessagePayload payload = NULL;
SilcChannelID *id = NULL;
SilcChannelEntry channel;
- SilcChannelUser chu;
- SilcIDCacheEntry id_cache = NULL;
+ SilcClientEntry client_entry;
SilcClientID *client_id = NULL;
- bool found = FALSE;
unsigned char *message;
SILC_LOG_DEBUG(("Start"));
goto out;
/* Find the channel entry from channels on this connection */
- if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)id, &id_cache))
+ channel = silc_client_get_channel_by_id(client, conn, id);
+ if (!channel)
goto out;
- channel = (SilcChannelEntry)id_cache->context;
-
/* If there is no channel private key then just decrypt the message
with the channel key. If private keys are set then just go through
all private keys and check what decrypts correctly. */
we will use the old key in decryption. If that fails too then we
cannot do more and will drop the packet. */
if (!payload) {
- if (!channel->old_channel_key)
+ if (!channel->old_channel_key) {
goto out;
+ }
payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
channel->old_channel_key,
channel->old_hmac);
- if (!payload)
+ if (!payload) {
goto out;
+ }
}
} else if (channel->private_keys) {
SilcChannelPrivateKey entry;
}
/* Find client entry */
- silc_list_start(channel->clients);
- while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
- if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id) &&
- chu->client->nickname) {
- found = TRUE;
- break;
- }
- }
-
- if (!found) {
+ client_entry = silc_client_get_client_by_id(client, conn, client_id);
+ if (!client_entry || !client_entry->nickname) {
/* Resolve the client info */
SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
res->payload = payload;
goto out;
}
+ if (!silc_client_on_channel(channel, client_entry)) {
+ SILC_LOG_WARNING(("Received channel message from client not on channel"));
+ goto out;
+ }
+
message = silc_channel_message_get_data(payload, NULL);
/* Pass the message to application */
client->internal->ops->channel_message(
- client, conn, chu->client, channel,
+ client, conn, client_entry, channel,
silc_channel_message_get_flags(payload),
message);
out:
- if (id)
- silc_free(id);
- if (client_id)
- silc_free(client_id);
+ silc_free(id);
+ silc_free(client_id);
if (payload)
silc_channel_message_payload_free(payload);
}
receive Channel Key Payload and when we are processing JOIN command
reply. */
-void silc_client_save_channel_key(SilcClientConnection conn,
+void silc_client_save_channel_key(SilcClient client,
+ SilcClientConnection conn,
SilcBuffer key_payload,
SilcChannelEntry channel)
{
unsigned char *id_string, *key, *cipher, *hmac, hash[32];
uint32 tmp_len;
SilcChannelID *id;
- SilcIDCacheEntry id_cache = NULL;
SilcChannelKeyPayload payload;
payload = silc_channel_key_payload_parse(key_payload->data,
/* Find channel. */
if (!channel) {
- if (!silc_idcache_find_by_id_one(conn->channel_cache,
- (void *)id, &id_cache))
+ channel = silc_client_get_channel_by_id(client, conn, id);
+ if (!channel)
goto out;
-
- /* Get channel entry */
- channel = (SilcChannelEntry)id_cache->context;
}
hmac = (channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) :
if (channel->old_hmac)
silc_hmac_free(channel->old_hmac);
if (channel->rekey_task)
- silc_schedule_task_del(conn->client->schedule, channel->rekey_task);
+ silc_schedule_task_del(client->schedule, channel->rekey_task);
channel->old_channel_key = channel->channel_key;
channel->old_hmac = channel->hmac;
channel->rekey_task =
- silc_schedule_task_add(conn->client->schedule, 0,
+ silc_schedule_task_add(client->schedule, 0,
silc_client_save_channel_key_rekey, channel,
10, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
key = silc_channel_key_get_key(payload, &tmp_len);
cipher = silc_channel_key_get_cipher(payload, NULL);
channel->key_len = tmp_len * 8;
- channel->key = silc_calloc(tmp_len, sizeof(*channel->key));
- memcpy(channel->key, key, tmp_len);
+ channel->key = silc_memdup(key, tmp_len);
if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
- conn->client->internal->ops->say(
+ client->internal->ops->say(
conn->client, conn,
SILC_CLIENT_MESSAGE_AUDIT,
"Cannot talk to channel: unsupported cipher %s",
SILC_LOG_DEBUG(("Received key for channel"));
/* Save the key */
- silc_client_save_channel_key(sock->user_data, packet, NULL);
+ silc_client_save_channel_key(client, sock->user_data, packet, NULL);
}
/* Adds private key for channel. This may be set only if the channel's mode
/* Save the key */
entry = silc_calloc(1, sizeof(*entry));
- 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 = silc_memdup(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_free(keys);
}
+
+/* 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. */
+
+SilcChannelUser silc_client_on_channel(SilcChannelEntry channel,
+ SilcClientEntry client_entry)
+{
+ SilcChannelUser chu;
+
+ if (silc_hash_table_find(channel->user_list, client_entry, NULL,
+ (void *)&chu))
+ return chu;
+
+ return NULL;
+}