for (i = 0; i < iv_len; i++) channel->iv[i] =
silc_rng_get_byte(client->rng);
else
- silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv);
+ silc_hash_make(client->internal->md5hash, channel->iv, iv_len,
+ channel->iv);
/* Encode the channel payload. This also encrypts the message payload. */
payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len,
silc_free(id_string);
}
+typedef struct {
+ SilcChannelMessagePayload payload;
+ SilcChannelID *channel_id;
+} *SilcChannelClientResolve;
+
static void silc_client_channel_message_cb(SilcClient client,
SilcClientConnection conn,
SilcClientEntry *clients,
uint32 clients_count,
void *context)
{
- SilcPacketContext *packet = (SilcPacketContext *)context;
+ 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))
+ goto out;
- if (clients)
- silc_client_channel_message(client, conn->sock, packet);
- silc_packet_context_free(packet);
+ channel = (SilcChannelEntry)id_cache->context;
+ message = silc_channel_message_get_data(res->payload, NULL);
+
+ /* Pass the message to application */
+ client->internal->ops->channel_message(
+ client, conn, clients[0], channel,
+ silc_channel_message_get_flags(res->payload),
+ message);
+ }
+
+ out:
+ silc_channel_message_payload_free(res->payload);
+ silc_free(res->channel_id);
+ silc_free(res);
}
/* Process received message to a channel (or from a channel, really). This
all private keys and check what decrypts correctly. */
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Parse the channel message payload. This also decrypts the payload */
- payload = silc_channel_message_payload_parse(buffer, channel->channel_key,
+ payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
+ channel->channel_key,
channel->hmac);
/* If decryption failed and we have just performed channel key rekey
if (!channel->old_channel_key)
goto out;
- payload = silc_channel_message_payload_parse(buffer,
+ payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
channel->old_channel_key,
channel->old_hmac);
if (!payload)
silc_dlist_start(channel->private_keys);
while ((entry = silc_dlist_get(channel->private_keys)) != SILC_LIST_END) {
/* Parse the channel message payload. This also decrypts the payload */
- payload = silc_channel_message_payload_parse(buffer, entry->cipher,
+ payload = silc_channel_message_payload_parse(buffer->data, buffer->len,
+ entry->cipher,
entry->hmac);
if (payload)
break;
/* 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)) {
+ if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id) &&
+ chu->client->nickname) {
found = TRUE;
break;
}
if (!found) {
/* Resolve the client info */
+ SilcChannelClientResolve res = silc_calloc(1, sizeof(*res));
+ res->payload = payload;
+ res->channel_id = id;
silc_client_get_client_by_id_resolve(client, conn, client_id,
silc_client_channel_message_cb,
- silc_packet_context_dup(packet));
+ res);
+ payload = NULL;
+ id = NULL;
goto out;
}
message = silc_channel_message_get_data(payload, NULL);
/* Pass the message to application */
- client->ops->channel_message(client, conn, chu->client, channel,
- silc_channel_message_get_flags(payload),
- message);
+ client->internal->ops->channel_message(
+ client, conn, chu->client, channel,
+ silc_channel_message_get_flags(payload),
+ message);
out:
if (id)
SilcIDCacheEntry id_cache = NULL;
SilcChannelKeyPayload payload;
- payload = silc_channel_key_payload_parse(key_payload);
+ payload = silc_channel_key_payload_parse(key_payload->data,
+ key_payload->len);
if (!payload)
return;
memcpy(channel->key, key, tmp_len);
if (!silc_cipher_alloc(cipher, &channel->channel_key)) {
- conn->client->ops->say(conn->client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+ conn->client->internal->ops->say(
+ conn->client, conn,
+ SILC_CLIENT_MESSAGE_AUDIT,
"Cannot talk to channel: unsupported cipher %s",
cipher);
goto out;
/* 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)
+ client->internal->md5hash, keymat)
!= SILC_SKE_STATUS_OK)
return FALSE;