From: Pekka Riikonen Date: Mon, 18 Mar 2002 19:40:27 +0000 (+0000) Subject: Added checking for maximum packet length. X-Git-Tag: silc.toolkit.0.8.1~14 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=c41b6607947087a49fec26756966dad8e1f39508 Added checking for maximum packet length. --- diff --git a/CHANGES b/CHANGES index 317fa64b..a627f5e0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +Mon Mar 18 21:00:41 EET 2002 Pekka Riikonen + + * 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 * Added silc_server_packet_queue_purge call to the diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 4519cc75..e9d70fbb 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -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; diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index af4de651..5cbfc588 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -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); diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index ee2cc2b8..dbc60834 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -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); diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index eb901868..be4d8b0d 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -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); diff --git a/lib/silccore/silcchannel.c b/lib/silccore/silcchannel.c index cb28fab4..d104cc18 100644 --- a/lib/silccore/silcchannel.c +++ b/lib/silccore/silcchannel.c @@ -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); diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index c8e17e60..16124e29 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -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. */ diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index b5789fe0..a944d332 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -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 diff --git a/lib/silccore/silcprivate.c b/lib/silccore/silcprivate.c index 6136dc75..ac99257f 100644 --- a/lib/silccore/silcprivate.c +++ b/lib/silccore/silcprivate.c @@ -29,8 +29,19 @@ ******************************************************************************/ +/* 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) {