Added checking for maximum packet length.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 18 Mar 2002 19:40:27 +0000 (19:40 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 18 Mar 2002 19:40:27 +0000 (19:40 +0000)
CHANGES
apps/silcd/packet_send.c
lib/silcclient/client.c
lib/silcclient/client_channel.c
lib/silcclient/client_prvmsg.c
lib/silccore/silcchannel.c
lib/silccore/silcpacket.c
lib/silccore/silcpacket.h
lib/silccore/silcprivate.c

diff --git a/CHANGES b/CHANGES
index 317fa64ba233166916b3499f2f7cc03ba56a21a0..a627f5e02b7e2561a68db6ed9df42a29e149064d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,21 @@
+Mon Mar 18 21:00:41 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added macro SILC_PACKET_DATALEN which can be used during
+         packet assembling to check whether the data to be added to    
+         the packet will fit to SILC_PACKET_MAX_LEN.  If not the data
+         len is truncated until it fits it.
+
+         Added checks for maximum length of channel message payload and
+         private message payload also.
+
+         Added checks for maximum packet length in server and in
+         client library.
+
+         Affected files are lib/silccore/silcpacket.h, silcd/packet_send.c,
+         lib/silcclient/client.c, lib/silccore/silcchannel.c and
+         lib/silccore/silcprivate.c, lib/silcclient/client_channel.c and
+         lib/silcclient/client_prvmsg.c.
+
 Mon Mar 18 14:54:42 CET 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Added silc_server_packet_queue_purge call to the
index 4519cc75446464e5cbc489dc90a6924d511030a7..e9d70fbb076fd87abdd7b702f9fe1b8c36021139 100644 (file)
@@ -176,6 +176,9 @@ void silc_server_packet_send_dest(SilcServer server,
   packetdata.dst_id = dst_id_data;
   packetdata.dst_id_len = dst_id_len;
   packetdata.dst_id_type = dst_id_type;
+  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 + dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
@@ -277,6 +280,9 @@ void silc_server_packet_send_srcdest(SilcServer server,
   packetdata.dst_id = dst_id_data;
   packetdata.dst_id_len = dst_id_len;
   packetdata.dst_id_type = dst_id_type;
+  data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
+                                           packetdata.src_id_len + 
+                                           dst_id_len));
   packetdata.truelen = data_len + SILC_PACKET_HEADER_LEN + 
     packetdata.src_id_len + dst_id_len;
   packetdata.padlen = SILC_PACKET_PADLEN(packetdata.truelen, block_len);
@@ -480,6 +486,9 @@ silc_server_packet_send_to_channel_real(SilcServer server,
   if (!sock)
     return;
 
+  data_len = SILC_PACKET_DATALEN(data_len, (SILC_PACKET_HEADER_LEN +
+                                           packet->src_id_len + 
+                                           packet->dst_id_len));
   packet->truelen = data_len + SILC_PACKET_HEADER_LEN + 
     packet->src_id_len + packet->dst_id_len;
 
index af4de6513b719cd065905a6c275af92d8381c40c..5cbfc58816b6f2ce3391bdb34e40e60affad063b 100644 (file)
@@ -1234,6 +1234,9 @@ void silc_client_packet_send(SilcClient client,
     packetdata.dst_id_len = 0;
     packetdata.dst_id_type = SILC_ID_NONE;
   }
+  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(packetdata.truelen, block_len);
index ee2cc2b8eccd26e45cfb6ec1cda4e3182f4dcf65..dbc60834a5ee67f7e49a8c83ed7413cf32c51c6d 100644 (file)
@@ -112,6 +112,8 @@ void silc_client_send_channel_message(SilcClient client,
   /* Set the packet context pointers. The destination ID is always
      the Channel ID of the channel. Server and router will handle the
      distribution of the packet. */
+  data = payload->data;
+  data_len = payload->len;
   packetdata.flags = 0;
   packetdata.type = SILC_PACKET_CHANNEL_MESSAGE;
   packetdata.src_id = conn->local_id_data;
@@ -120,7 +122,10 @@ void silc_client_send_channel_message(SilcClient client,
   packetdata.dst_id = id_string;
   packetdata.dst_id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
   packetdata.dst_id_type = SILC_ID_CHANNEL;
-  packetdata.truelen = payload->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 +
@@ -132,12 +137,12 @@ void silc_client_send_channel_message(SilcClient client,
                           packetdata.src_id_len + 
                           packetdata.dst_id_len,
                           packetdata.padlen,
-                          payload->len);
+                          data_len);
 
   packetdata.buffer = sock->outbuf;
 
   /* Put the channel message payload to the outgoing data buffer */
-  silc_buffer_put(sock->outbuf, payload->data, payload->len);
+  silc_buffer_put(sock->outbuf, data, data_len);
 
   /* Create the outgoing packet */
   silc_packet_assemble(&packetdata, cipher);
index eb90186885a55de14ff53fdf507886f0a471d2bb..be4d8b0d70ce410f51880b201ee356152ad6498a 100644 (file)
@@ -75,6 +75,8 @@ void silc_client_send_private_message(SilcClient client,
   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;
@@ -83,7 +85,10 @@ 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 +
@@ -95,12 +100,12 @@ void silc_client_send_private_message(SilcClient client,
                           packetdata.src_id_len + 
                           packetdata.dst_id_len,
                           packetdata.padlen,
-                          buffer->len);
+                          data_len);
   
   packetdata.buffer = sock->outbuf;
 
   /* Put the actual encrypted message payload data into the buffer. */
-  silc_buffer_put(sock->outbuf, buffer->data, buffer->len);
+  silc_buffer_put(sock->outbuf, data, data_len);
 
   /* Create the outgoing packet */
   silc_packet_assemble(&packetdata, cipher);
index cb28fab434df0b27f4551938921bc6c133bb6b36..d104cc182aaea154b5c2e438a10e66870ea07d32 100644 (file)
@@ -230,8 +230,20 @@ SilcUInt32 silc_channel_get_mode(SilcChannelPayload payload)
 
 ******************************************************************************/
 
+/* Calculates padding length for message payload */
 #define SILC_CHANNEL_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
 
+/* Header length plus maximum padding length */
+#define SILC_CHANNEL_MESSAGE_HLEN 6 + 16
+
+/* Returns the data length that fits to the packet.  If data length is too
+   big it will be truncated to fit to the payload. */
+#define SILC_CHANNEL_MESSAGE_DATALEN(data_len, header_len)             \
+  ((data_len + SILC_CHANNEL_MESSAGE_HLEN + header_len) >               \
+   SILC_PACKET_MAX_LEN ?                                               \
+   data_len - ((data_len + SILC_CHANNEL_MESSAGE_HLEN + header_len) -   \
+              SILC_PACKET_MAX_LEN) : data_len)
+
 /* Channel Message Payload structure. Contents of this structure is parsed
    from SILC packets. */
 struct SilcChannelMessagePayloadStruct {
@@ -384,6 +396,7 @@ SilcBuffer silc_channel_message_payload_encode(SilcUInt16 flags,
   /* Calculate length of padding. IV is not included into the calculation
      since it is not encrypted. */
   mac_len = silc_hmac_len(hmac);
+  data_len = SILC_CHANNEL_MESSAGE_DATALEN(data_len, mac_len + iv_len);
   len = 6 + data_len + mac_len;
   pad_len = SILC_CHANNEL_MESSAGE_PAD(len);
 
index c8e17e601a823988894829c2eefe7d3003c4a4e6..16124e29ea75bd9224ca9347b93968ddfe1844ca 100644 (file)
@@ -169,9 +169,14 @@ void silc_packet_assemble(SilcPacketContext *ctx, SilcCipher cipher)
   /* Get the true length of the packet. This is saved as payload length
      into the packet header. This does not include the length of the
      padding. */
-  if (!ctx->truelen)
+  if (!ctx->truelen) {
     ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN + 
       ctx->src_id_len + ctx->dst_id_len;
+    if (ctx->truelen > SILC_PACKET_MAX_LEN) {
+      ctx->truelen -= (SILC_PACKET_MAX_LEN - ctx->truelen);
+      silc_buffer_push_tail(ctx->buffer, (SILC_PACKET_MAX_LEN - ctx->truelen));
+    }
+  }
 
   /* Calculate the length of the padding. The padding is calculated from
      the data that will be encrypted. */
index b5789fe0142dc6d9f401dad752b5a784bbf214c4..a944d332f6fb65e96e0e91819f19a3f49a614cc7 100644 (file)
@@ -51,6 +51,9 @@
 /* Minimum packet length */
 #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1)
 
+/* Maximum packet length */
+#define SILC_PACKET_MAX_LEN 0xffff
+
 /* Maximum length of ID */
 #define SILC_PACKET_MAX_ID_LEN 16
 
@@ -327,6 +330,29 @@ do {                                                                       \
 } while(0)
 /***/
 
+/****d* silccore/SilcPacketAPI/SILC_PACKET_DATALEN
+ *
+ * NAME
+ * 
+ *    #define SILC_PACKET_DATALEN ...
+ *
+ * DESCRIPTION
+ *
+ *    Calculates the data length with given header length.  This macro
+ *    can be used to check whether the data_len with header_len exceeds
+ *    SILC_PACKET_MAX_LEN.  If it does, this returns the new data_len
+ *    so that the SILC_PACKET_MAX_LEN is not exceeded.  If the data_len
+ *    plus header_len fits SILC_PACKET_MAX_LEN the returned data length
+ *    is the data_len given as argument.  This macro can be used when
+ *    assembling packet.
+ *
+ * SOURCE
+ */
+#define SILC_PACKET_DATALEN(data_len, header_len)                        \
+  ((data_len + header_len) > SILC_PACKET_MAX_LEN ?                       \
+   data_len - ((data_len + header_len) - SILC_PACKET_MAX_LEN) : data_len)
+/***/
+
 /****d* silccore/SilcPacketAPI/SILC_PACKET_PADLEN
  *
  * NAME
index 6136dc75349eb720bae50ac568731c558616adfc..ac99257f21595ee14a737d7fb8be608a9c1e6d84 100644 (file)
 
 ******************************************************************************/
 
+/* Calculates padding length for message payload */
 #define SILC_PRIVATE_MESSAGE_PAD(__payloadlen) (16 - (__payloadlen) % 16)
 
+/* Header length plus maximum padding length */
+#define SILC_PRIVATE_MESSAGE_HLEN 4 + 16
+
+/* Returns the data length that fits to the packet.  If data length is too
+   big it will be truncated to fit to the payload. */
+#define SILC_PRIVATE_MESSAGE_DATALEN(data_len)                         \
+  ((data_len + SILC_PRIVATE_MESSAGE_HLEN) > SILC_PACKET_MAX_LEN ?      \
+   data_len - ((data_len + SILC_PRIVATE_MESSAGE_HLEN) -                \
+              SILC_PACKET_MAX_LEN) : data_len)
+
 /* Private Message Payload structure. Contents of this structure is parsed
    from SILC packets. */
 struct SilcPrivateMessagePayloadStruct {
@@ -105,6 +116,7 @@ SilcBuffer silc_private_message_payload_encode(SilcUInt16 flags,
 
   SILC_LOG_DEBUG(("Encoding private message payload"));
 
+  data_len = SILC_PRIVATE_MESSAGE_DATALEN(data_len);
   len = 4 + data_len;
 
   if (cipher) {