updates.
[silc.git] / lib / silcclient / client_prvmsg.c
index 5acc8610abd2d3d4fa446ee3cca7980f319abd0a..439fe0e32d3853877fa8b3346b41dec2cf3598e8 100644 (file)
@@ -21,7 +21,8 @@
 /* This file includes the private message sending and receiving routines
    and private message key handling routines. */
 
-#include "clientlibincludes.h"
+#include "silcincludes.h"
+#include "silcclient.h"
 #include "client_internal.h"
 
 /* Sends private message to remote client. If private message key has
@@ -37,12 +38,13 @@ void silc_client_send_private_message(SilcClient client,
                                      SilcClientEntry client_entry,
                                      SilcMessageFlags flags,
                                      unsigned char *data, 
-                                     uint32 data_len, 
+                                     SilcUInt32 data_len, 
                                      int force_send)
 {
   SilcSocketConnection sock = conn->sock;
   SilcBuffer buffer;
   SilcPacketContext packetdata;
+  const SilcBufferStruct packet;
   SilcCipher cipher;
   SilcHmac hmac;
   int block_len;
@@ -52,7 +54,8 @@ void silc_client_send_private_message(SilcClient client,
   /* Encode private message payload */
   buffer = silc_private_message_payload_encode(flags,
                                               data_len, data,
-                                              client_entry->send_key);
+                                              client_entry->send_key,
+                                              client->rng);
 
   /* If we don't have private message specific key then private messages
      are just as any normal packet thus call normal packet sending.  If
@@ -68,11 +71,13 @@ void silc_client_send_private_message(SilcClient client,
   /* We have private message specific key */
 
   /* Get data used in the encryption */
-  cipher = client_entry->send_key;
+  cipher = conn->send_key;
   hmac = conn->hmac_send;
   block_len = silc_cipher_get_block_len(cipher);
 
   /* Set the packet context pointers. */
+  data = buffer->data;
+  data_len = buffer->len;
   packetdata.flags = SILC_PACKET_FLAG_PRIVMSG_KEY;
   packetdata.type = SILC_PACKET_PRIVATE_MESSAGE;
   packetdata.src_id = conn->local_id_data;
@@ -81,37 +86,30 @@ void silc_client_send_private_message(SilcClient client,
   packetdata.dst_id = silc_id_id2str(client_entry->id, SILC_ID_CLIENT);
   packetdata.dst_id_len = silc_id_get_len(client_entry->id, SILC_ID_CLIENT);
   packetdata.dst_id_type = SILC_ID_CLIENT;
-  packetdata.truelen = buffer->len + SILC_PACKET_HEADER_LEN + 
+  data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
+                                packetdata.src_id_len +
+                                packetdata.dst_id_len);
+  packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
     packetdata.src_id_len + packetdata.dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN((SILC_PACKET_HEADER_LEN +
                                          packetdata.src_id_len +
                                          packetdata.dst_id_len), block_len);
 
-  /* Prepare outgoing data buffer for packet sending */
-  silc_packet_send_prepare(sock, 
-                          SILC_PACKET_HEADER_LEN +
-                          packetdata.src_id_len + 
-                          packetdata.dst_id_len,
-                          packetdata.padlen,
-                          buffer->len);
-  
-  packetdata.buffer = sock->outbuf;
-
-  /* Put the actual encrypted message payload data into the buffer. */
-  silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
-
   /* Create the outgoing packet */
-  silc_packet_assemble(&packetdata, cipher);
+  if (!silc_packet_assemble(&packetdata, client->rng, cipher, hmac, sock, 
+                            data, data_len, (const SilcBuffer)&packet)) {
+    SILC_LOG_ERROR(("Error assembling packet"));
+    goto out;
+  }
 
   /* Encrypt the header and padding of the packet. */
-  cipher = conn->send_key;
   silc_packet_encrypt(cipher, hmac, conn->psn_send++,
-                     sock->outbuf, SILC_PACKET_HEADER_LEN + 
+                     (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + 
                      packetdata.src_id_len + packetdata.dst_id_len +
                      packetdata.padlen);
 
-  SILC_LOG_HEXDUMP(("Private message packet, len %d", sock->outbuf->len),
-                  sock->outbuf->data, sock->outbuf->len);
+  SILC_LOG_HEXDUMP(("Private message packet, len %d", packet.len),
+                  packet.data, packet.len);
 
   /* Now actually send the packet */
   silc_client_packet_send_real(client, sock, force_send);
@@ -124,7 +122,7 @@ void silc_client_send_private_message(SilcClient client,
 static void silc_client_private_message_cb(SilcClient client,
                                           SilcClientConnection conn,
                                           SilcClientEntry *clients,
-                                          uint32 clients_count,
+                                          SilcUInt32 clients_count,
                                           void *context)
 {
   SilcPacketContext *packet = (SilcPacketContext *)context;
@@ -147,10 +145,11 @@ void silc_client_private_message(SilcClient client,
 {
   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
   SilcPrivateMessagePayload payload = NULL;
-  SilcIDCacheEntry id_cache = NULL;
   SilcClientID *remote_id = NULL;
   SilcClientEntry remote_client;
   SilcMessageFlags flags;
+  unsigned char *message;
+  SilcUInt32 message_len;
 
   if (packet->src_id_type != SILC_ID_CLIENT)
     goto out;
@@ -161,19 +160,15 @@ void silc_client_private_message(SilcClient client,
     goto out;
 
   /* Check whether we know this client already */
-  if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)remote_id, 
-                                      NULL, NULL, 
-                                      silc_hash_client_id_compare, NULL,
-                                      &id_cache) || 
-      ((SilcClientEntry)id_cache->context)->nickname == NULL) {
-
-    if (id_cache && id_cache->context) {
-      remote_client = (SilcClientEntry)id_cache->context;
+  remote_client = silc_client_get_client_by_id(client, conn, remote_id);
+  if (!remote_client || !remote_client->nickname) {
+    if (remote_client) {
       if (remote_client->status & SILC_CLIENT_STATUS_RESOLVING) {
        remote_client->status &= ~SILC_CLIENT_STATUS_RESOLVING;
        goto out;
       }
       remote_client->status |= SILC_CLIENT_STATUS_RESOLVING;
+      remote_client->resolve_cmd_ident = conn->cmd_ident + 1;
     }
 
     /* Resolve the client info */
@@ -183,10 +178,9 @@ void silc_client_private_message(SilcClient client,
     return;
   }
 
-  remote_client = (SilcClientEntry)id_cache->context;
-
   /* Parse the payload and decrypt it also if private message key is set */
-  payload = silc_private_message_payload_parse(packet->buffer,
+  payload = silc_private_message_payload_parse(packet->buffer->data,
+                                              packet->buffer->len,
                                               remote_client->receive_key);
   if (!payload) {
     silc_free(remote_id);
@@ -196,9 +190,9 @@ void silc_client_private_message(SilcClient client,
   flags = silc_private_message_get_flags(payload);
 
   /* Pass the private message to application */
-  client->ops->private_message(client, conn, remote_client, flags,
-                              silc_private_message_get_message(payload, 
-                                                               NULL));
+  message = silc_private_message_get_message(payload, &message_len);
+  client->internal->ops->private_message(client, conn, remote_client, flags,
+                                        message, message_len);
 
   /* See if we are away (gone). If we are away we will reply to the
      sender with the set away message. */
@@ -226,12 +220,12 @@ void silc_client_private_message(SilcClient client,
 static void silc_client_private_message_key_cb(SilcClient client,
                                               SilcClientConnection conn,
                                               SilcClientEntry *clients,
-                                              uint32 clients_count,
+                                              SilcUInt32 clients_count,
                                               void *context)
 {
   SilcPacketContext *packet = (SilcPacketContext *)context;
   unsigned char *key;
-  uint16 key_len;
+  SilcUInt16 key_len;
   unsigned char *cipher;
   int ret;
 
@@ -255,14 +249,15 @@ static void silc_client_private_message_key_cb(SilcClient client,
     goto out;
 
   /* Print some info for application */
-  client->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
-                  "Received private message key from %s%s%s %s%s%s", 
-                  clients[0]->nickname,
-                  clients[0]->server ? "@" : "",
-                  clients[0]->server ? clients[0]->server : "",
-                  clients[0]->username ? "(" : "",
-                  clients[0]->username ? clients[0]->username : "",
-                  clients[0]->username ? ")" : "");
+  client->internal->ops->say(
+                    client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
+                    "Received private message key from %s%s%s %s%s%s", 
+                    clients[0]->nickname,
+                    clients[0]->server ? "@" : "",
+                    clients[0]->server ? clients[0]->server : "",
+                    clients[0]->username ? "(" : "",
+                    clients[0]->username ? clients[0]->username : "",
+                    clients[0]->username ? ")" : "");
 
  out:
   silc_packet_context_free(packet);
@@ -317,12 +312,12 @@ int silc_client_add_private_message_key(SilcClient client,
                                        SilcClientEntry client_entry,
                                        char *cipher,
                                        unsigned char *key,
-                                       uint32 key_len,
+                                       SilcUInt32 key_len,
                                        bool generate_key,
                                        bool responder)
 {
   unsigned char private_key[32];
-  uint32 len;
+  SilcUInt32 len;
   int i;
   SilcSKEKeyMaterial *keymat;
 
@@ -349,14 +344,13 @@ int silc_client_add_private_message_key(SilcClient client,
   }
 
   /* Save the key */
-  client_entry->key = silc_calloc(key_len, sizeof(*client_entry->key));
-  memcpy(client_entry->key, key, key_len);
+  client_entry->key = silc_memdup(key, key_len);
   client_entry->key_len = key_len;
 
   /* Produce the key material as the protocol defines */
   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;
 
@@ -523,10 +517,10 @@ int silc_client_del_private_message_key(SilcClient client,
 SilcPrivateMessageKeys
 silc_client_list_private_message_keys(SilcClient client,
                                      SilcClientConnection conn,
-                                     uint32 *key_count)
+                                     SilcUInt32 *key_count)
 {
   SilcPrivateMessageKeys keys;
-  uint32 count = 0;
+  SilcUInt32 count = 0;
   SilcIDCacheEntry id_cache;
   SilcIDCacheList list;
   SilcClientEntry entry;
@@ -567,7 +561,7 @@ silc_client_list_private_message_keys(SilcClient client,
    silc_client_list_private_message_keys. */
 
 void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
-                                          uint32 key_count)
+                                          SilcUInt32 key_count)
 {
   silc_free(keys);
 }