Added some asserts and error checks.
[silc.git] / lib / silcclient / client_prvmsg.c
index 2ef43aec9245307d993752a0ae37fff1a546ec80..dc7b14d467760966b4bdc2220005d4869970ec13 100644 (file)
@@ -41,7 +41,7 @@ void silc_client_send_private_message(SilcClient client,
                                      SilcUInt32 data_len, 
                                      int force_send)
 {
-  SilcSocketConnection sock = conn->sock;
+  SilcSocketConnection sock;
   SilcBuffer buffer;
   SilcPacketContext packetdata;
   const SilcBufferStruct packet;
@@ -49,6 +49,8 @@ void silc_client_send_private_message(SilcClient client,
   SilcHmac hmac;
   int block_len;
 
+  assert(client && conn && client_entry);
+  sock = conn->sock;
   SILC_LOG_DEBUG(("Sending private message"));
 
   /* Encode private message payload */
@@ -71,8 +73,8 @@ 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;
-  hmac = conn->hmac_send;
+  cipher = conn->internal->send_key;
+  hmac = conn->internal->hmac_send;
   block_len = silc_cipher_get_block_len(cipher);
 
   /* Set the packet context pointers. */
@@ -103,8 +105,7 @@ void silc_client_send_private_message(SilcClient client,
   }
 
   /* Encrypt the header and padding of the packet. */
-  cipher = conn->send_key;
-  silc_packet_encrypt(cipher, hmac, conn->psn_send++,
+  silc_packet_encrypt(cipher, hmac, conn->internal->psn_send++,
                      (SilcBuffer)&packet, SILC_PACKET_HEADER_LEN + 
                      packetdata.src_id_len + packetdata.dst_id_len +
                      packetdata.padlen);
@@ -149,6 +150,9 @@ void silc_client_private_message(SilcClient client,
   SilcClientID *remote_id = NULL;
   SilcClientEntry remote_client;
   SilcMessageFlags flags;
+  unsigned char *message;
+  SilcUInt32 message_len;
+  SilcCipher cipher = NULL;
 
   if (packet->src_id_type != SILC_ID_CLIENT)
     goto out;
@@ -167,19 +171,25 @@ void silc_client_private_message(SilcClient client,
        goto out;
       }
       remote_client->status |= SILC_CLIENT_STATUS_RESOLVING;
+      remote_client->resolve_cmd_ident = conn->cmd_ident + 1;
     }
 
     /* Resolve the client info */
-    silc_client_get_client_by_id_resolve(client, conn, remote_id,
+    silc_client_get_client_by_id_resolve(client, conn, remote_id, NULL,
                                         silc_client_private_message_cb,
                                         silc_packet_context_dup(packet));
     return;
   }
 
+  cipher = remote_client->receive_key;
+  if (packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY && !cipher) {
+    silc_free(remote_id);
+    return;
+  }
+
   /* Parse the payload and decrypt it also if private message key is set */
   payload = silc_private_message_payload_parse(packet->buffer->data,
-                                              packet->buffer->len,
-                                              remote_client->receive_key);
+                                              packet->buffer->len, cipher);
   if (!payload) {
     silc_free(remote_id);
     return;
@@ -188,14 +198,14 @@ void silc_client_private_message(SilcClient client,
   flags = silc_private_message_get_flags(payload);
 
   /* Pass the private message to application */
-  client->internal->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. */
-  if (conn->away && conn->away->away && !(flags & SILC_MESSAGE_FLAG_NOREPLY)) {
+  if (conn->internal->away && conn->internal->away->away &&
+      !(flags & SILC_MESSAGE_FLAG_NOREPLY)) {
     /* If it's me, ignore */
     if (SILC_ID_CLIENT_COMPARE(remote_id, conn->local_id))
       goto out;
@@ -204,8 +214,8 @@ void silc_client_private_message(SilcClient client,
     silc_client_send_private_message(client, conn, remote_client,
                                     SILC_MESSAGE_FLAG_AUTOREPLY |
                                     SILC_MESSAGE_FLAG_NOREPLY,
-                                    conn->away->away,
-                                    strlen(conn->away->away), TRUE);
+                                    conn->internal->away->away,
+                                    strlen(conn->internal->away->away), TRUE);
   }
 
  out:
@@ -280,6 +290,7 @@ void silc_client_private_message_key(SilcClient client,
     return;
 
   silc_client_get_client_by_id_resolve(client, sock->user_data, remote_id,
+                                      NULL,
                                       silc_client_private_message_key_cb,
                                       silc_packet_context_dup(packet));
   silc_free(remote_id);
@@ -320,7 +331,7 @@ int silc_client_add_private_message_key(SilcClient client,
   int i;
   SilcSKEKeyMaterial *keymat;
 
-  assert(client_entry);
+  assert(client && client_entry);
 
   /* Return FALSE if key already set */
   if (client_entry->send_key && client_entry->receive_key)
@@ -349,7 +360,7 @@ int silc_client_add_private_message_key(SilcClient client,
   /* 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->internal->md5hash, keymat) 
+                                        client->md5hash, keymat) 
       != SILC_SKE_STATUS_OK)
     return FALSE;
 
@@ -393,7 +404,7 @@ int silc_client_add_private_message_key_ske(SilcClient client,
                                            SilcSKEKeyMaterial *key,
                                            bool responder)
 {
-  assert(client_entry);
+  assert(client && client_entry);
 
   /* Return FALSE if key already set */
   if (client_entry->send_key && client_entry->receive_key)
@@ -445,16 +456,21 @@ int silc_client_send_private_message_key(SilcClient client,
                                         SilcClientEntry client_entry,
                                         int force_send)
 {
-  SilcSocketConnection sock = conn->sock;
+  SilcSocketConnection sock;
   SilcBuffer buffer;
   int cipher_len;
+  const char *cipher;
 
+  assert(client && conn && client_entry);
+
+  sock = conn->sock;
   if (!client_entry->send_key || !client_entry->key)
     return FALSE;
 
   SILC_LOG_DEBUG(("Sending private message key"));
 
-  cipher_len = strlen(client_entry->send_key->cipher->name);
+  cipher = silc_cipher_get_name(client_entry->send_key);
+  cipher_len = strlen(cipher);
 
   /* Create private message key payload */
   buffer = silc_buffer_alloc(2 + client_entry->key_len);
@@ -464,7 +480,7 @@ int silc_client_send_private_message_key(SilcClient client,
                     SILC_STR_UI_XNSTRING(client_entry->key, 
                                          client_entry->key_len),
                     SILC_STR_UI_SHORT(cipher_len),
-                    SILC_STR_UI_XNSTRING(client_entry->send_key->cipher->name,
+                    SILC_STR_UI_XNSTRING(cipher,
                                          cipher_len),
                     SILC_STR_END);
 
@@ -485,7 +501,7 @@ int silc_client_del_private_message_key(SilcClient client,
                                        SilcClientConnection conn,
                                        SilcClientEntry client_entry)
 {
-  assert(client_entry);
+  assert(client && client_entry);
 
   if (!client_entry->send_key && !client_entry->receive_key)
     return FALSE;
@@ -524,7 +540,9 @@ silc_client_list_private_message_keys(SilcClient client,
   SilcIDCacheList list;
   SilcClientEntry entry;
 
-  if (!silc_idcache_get_all(conn->client_cache, &list))
+  assert(client && conn);
+
+  if (!silc_idcache_get_all(conn->internal->client_cache, &list))
     return NULL;
 
   if (!silc_idcache_list_count(list)) {
@@ -540,7 +558,7 @@ silc_client_list_private_message_keys(SilcClient client,
 
     if (entry->send_key) {
       keys[count].client_entry = entry;
-      keys[count].cipher = entry->send_key->cipher->name;
+      keys[count].cipher = (char *)silc_cipher_get_name(entry->send_key);
       keys[count].key = entry->generated == FALSE ? entry->key : NULL;
       keys[count].key_len = entry->generated == FALSE ? entry->key_len : 0;
       count++;
@@ -577,17 +595,19 @@ void silc_client_set_away_message(SilcClient client,
                                  SilcClientConnection conn,
                                  char *message)
 {
-  if (!message && conn->away) {
-    silc_free(conn->away->away);
-    silc_free(conn->away);
-    conn->away = NULL;
+  assert(client && conn);
+
+  if (!message && conn->internal->away) {
+    silc_free(conn->internal->away->away);
+    silc_free(conn->internal->away);
+    conn->internal->away = NULL;
   }
 
   if (message) {
-    if (!conn->away)
-      conn->away = silc_calloc(1, sizeof(*conn->away));
-    if (conn->away->away)
-      silc_free(conn->away->away);
-    conn->away->away = strdup(message);
+    if (!conn->internal->away)
+      conn->internal->away = silc_calloc(1, sizeof(*conn->internal->away));
+    if (conn->internal->away->away)
+      silc_free(conn->internal->away->away);
+    conn->internal->away->away = strdup(message);
   }
 }