+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
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);
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);
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;
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);
/* 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;
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 +
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);
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;
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.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);
******************************************************************************/
+/* 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 {
/* 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);
/* 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. */
/* 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
} 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
******************************************************************************/
+/* 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 {
SILC_LOG_DEBUG(("Encoding private message payload"));
+ data_len = SILC_PRIVATE_MESSAGE_DATALEN(data_len);
len = 4 + data_len;
if (cipher) {