If packet processing fails (like integrity check fails etc) the
[silc.git] / lib / silccore / silcpacket.c
index 5c5f6be6606e9db35031cc525e7095286e113a08..b2fad174f51dd4dd2d32c7592e54a89e7e4c755a 100644 (file)
@@ -113,10 +113,10 @@ void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, SilcUInt32 sequence,
 /* Assembles a new packet to be ready for send out. */
 
 bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
-                          SilcCipher cipher, SilcHmac hmac,
-                          SilcSocketConnection sock,
-                          const unsigned char *data, SilcUInt32 data_len,
-                          const SilcBuffer assembled_packet)
+                         SilcCipher cipher, SilcHmac hmac,
+                         SilcSocketConnection sock,
+                         const unsigned char *data, SilcUInt32 data_len,
+                         const SilcBuffer assembled_packet)
 { 
   unsigned char tmppad[SILC_PACKET_MAX_PADLEN];   
   int block_len = cipher ? silc_cipher_get_block_len(cipher) : 0;
@@ -132,7 +132,7 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
      padding. */
   if (!packet->truelen) {
     data_len = SILC_PACKET_DATALEN(data_len, SILC_PACKET_HEADER_LEN +
-                                   packet->src_id_len + packet->dst_id_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;
   }
@@ -141,8 +141,8 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
      the data that will be encrypted. */
   if (!packet->padlen) {
     packet->padlen = (packet->long_pad ?
-                      SILC_PACKET_PADLEN_MAX(packet->truelen) :
-                      SILC_PACKET_PADLEN(packet->truelen, block_len));
+                     SILC_PACKET_PADLEN_MAX(packet->truelen) :
+                     SILC_PACKET_PADLEN(packet->truelen, block_len));
   }
 
   /* Now prepare the outgoing data buffer for packet sending and start
@@ -150,43 +150,43 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
 
   /* Return pointer to the assembled packet */
   if (!silc_packet_send_prepare(sock, packet->truelen - data_len,
-                                packet->padlen, data_len, hmac,
-                                assembled_packet))
+                               packet->padlen, data_len, hmac,
+                               assembled_packet))
     return FALSE;
 
   /* Get random padding */
   if (rng)
     for (i = 0; i < packet->padlen; i++) tmppad[i] =
-                                           silc_rng_get_byte_fast(rng);
+                                          silc_rng_get_byte_fast(rng);
   else
     for (i = 0; i < packet->padlen; i++) tmppad[i] =
-                                           silc_rng_global_get_byte_fast();
+                                          silc_rng_global_get_byte_fast();
 
   /* Create the packet. This creates the SILC header, adds padding, and
      the actual packet data. */
   ret =
     silc_buffer_format(assembled_packet,
-                       SILC_STR_UI_SHORT(packet->truelen),
-                       SILC_STR_UI_CHAR(packet->flags),
-                       SILC_STR_UI_CHAR(packet->type),
-                       SILC_STR_UI_CHAR(packet->padlen),
-                       SILC_STR_UI_CHAR(0),
-                       SILC_STR_UI_CHAR(packet->src_id_len),
-                       SILC_STR_UI_CHAR(packet->dst_id_len),
-                       SILC_STR_UI_CHAR(packet->src_id_type),
-                       SILC_STR_UI_XNSTRING(packet->src_id,
-                                            packet->src_id_len),
-                       SILC_STR_UI_CHAR(packet->dst_id_type),
-                       SILC_STR_UI_XNSTRING(packet->dst_id,
-                                            packet->dst_id_len),
-                       SILC_STR_UI_XNSTRING(tmppad, packet->padlen),
-                       SILC_STR_UI_XNSTRING(data, data_len),
-                       SILC_STR_END);
+                      SILC_STR_UI_SHORT(packet->truelen),
+                      SILC_STR_UI_CHAR(packet->flags),
+                      SILC_STR_UI_CHAR(packet->type),
+                      SILC_STR_UI_CHAR(packet->padlen),
+                      SILC_STR_UI_CHAR(0),
+                      SILC_STR_UI_CHAR(packet->src_id_len),
+                      SILC_STR_UI_CHAR(packet->dst_id_len),
+                      SILC_STR_UI_CHAR(packet->src_id_type),
+                      SILC_STR_UI_XNSTRING(packet->src_id,
+                                           packet->src_id_len),
+                      SILC_STR_UI_CHAR(packet->dst_id_type),
+                      SILC_STR_UI_XNSTRING(packet->dst_id,
+                                           packet->dst_id_len),
+                      SILC_STR_UI_XNSTRING(tmppad, packet->padlen),
+                      SILC_STR_UI_XNSTRING(data, data_len),
+                      SILC_STR_END);
   if (ret < 0)
     return FALSE;
 
   SILC_LOG_HEXDUMP(("Assembled packet, len %d", assembled_packet->len),
-                   assembled_packet->data, assembled_packet->len);
+                  assembled_packet->data, assembled_packet->len);
 
   return TRUE;
 }
@@ -198,11 +198,11 @@ bool silc_packet_assemble(SilcPacketContext *packet, SilcRng rng,
    pointer to that buffer into the `packet'. */
 
 bool silc_packet_send_prepare(SilcSocketConnection sock,
-                              SilcUInt32 header_len,
-                              SilcUInt32 pad_len,
-                              SilcUInt32 data_len,
-                              SilcHmac hmac,
-                              const SilcBuffer packet)
+                             SilcUInt32 header_len,
+                             SilcUInt32 pad_len,
+                             SilcUInt32 data_len,
+                             SilcHmac hmac,
+                             const SilcBuffer packet)
 { 
   int totlen;
   unsigned char *oldptr;
@@ -219,7 +219,7 @@ bool silc_packet_send_prepare(SilcSocketConnection sock,
     SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
 
     sock->outbuf = silc_buffer_alloc(totlen > SILC_PACKET_DEFAULT_SIZE ?
-                                     totlen : SILC_PACKET_DEFAULT_SIZE);
+                                    totlen : SILC_PACKET_DEFAULT_SIZE);
     if (!sock->outbuf)
       return FALSE;
   } else {
@@ -233,7 +233,7 @@ bool silc_packet_send_prepare(SilcSocketConnection sock,
   if ((sock->outbuf->end - sock->outbuf->tail) < (totlen + mac_len)) {
     SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
     sock->outbuf = silc_buffer_realloc(sock->outbuf,
-                                       sock->outbuf->truelen + (totlen * 2));
+                                      sock->outbuf->truelen + (totlen * 2));
     if (!sock->outbuf)
       return FALSE;
   }
@@ -333,7 +333,7 @@ bool silc_packet_receive_process(SilcSocketConnection sock,
 
     /* Sanity checks */
     if (packetlen < SILC_PACKET_MIN_LEN) {
-      SILC_LOG_DEBUG(("Received invalid packet, dropped"));
+      SILC_LOG_ERROR(("Received invalid packet, dropped"));
       silc_buffer_clear(sock->inbuf);
       return FALSE;
     }
@@ -395,6 +395,7 @@ bool silc_packet_receive_process(SilcSocketConnection sock,
                           sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" :
                           sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
                           "Router")));
+       return FALSE;
       }
 
     /* Pull the packet from inbuf thus we'll get the next one
@@ -463,7 +464,7 @@ static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
       if ((buffer->len - silc_hmac_len(hmac)) > SILC_PACKET_MIN_LEN) {
        silc_buffer_push_tail(buffer, silc_hmac_len(hmac));
       } else {
-       SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
+       SILC_LOG_ERROR(("Bad MAC length in packet, packet dropped"));
        return FALSE;
       }
     }
@@ -502,7 +503,7 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher,
       if ((buffer->len - silc_hmac_len(hmac)) > SILC_PACKET_MIN_LEN) {
        silc_buffer_push_tail(buffer, silc_hmac_len(hmac));
       } else {
-       SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
+       SILC_LOG_ERROR(("Bad MAC length in packet, packet dropped"));
        return FALSE;
       }
     }
@@ -517,7 +518,7 @@ static int silc_packet_decrypt_rest_special(SilcCipher cipher,
 
     silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN);
     if (len > buffer->len) {
-      SILC_LOG_DEBUG(("Garbage in header of packet, bad packet length, "
+      SILC_LOG_ERROR(("Garbage in header of packet, bad packet length, "
                      "packet dropped"));
       return FALSE;
     }
@@ -585,6 +586,7 @@ SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher)
   SilcBuffer buffer = ctx->buffer;
   SilcUInt8 tmp;
   int len, ret;
+  SilcUInt8 src_id_len, src_id_type, dst_id_len, dst_id_type, padlen;
 
   SILC_LOG_DEBUG(("Parsing incoming packet"));
 
@@ -599,34 +601,46 @@ SilcPacketType silc_packet_parse(SilcPacketContext *ctx, SilcCipher cipher)
                             SILC_STR_UI_SHORT(&ctx->truelen),
                             SILC_STR_UI_CHAR(&ctx->flags),
                             SILC_STR_UI_CHAR(&ctx->type),
-                            SILC_STR_UI_CHAR(&ctx->padlen),
+                            SILC_STR_UI_CHAR(&padlen),
                             SILC_STR_UI_CHAR(&tmp),
-                            SILC_STR_UI_CHAR(&ctx->src_id_len),
-                            SILC_STR_UI_CHAR(&ctx->dst_id_len),
-                            SILC_STR_UI_CHAR(&ctx->src_id_type),
+                            SILC_STR_UI_CHAR(&src_id_len),
+                            SILC_STR_UI_CHAR(&dst_id_len),
+                            SILC_STR_UI_CHAR(&src_id_type),
                             SILC_STR_END);
   if (len == -1 || tmp != 0)
     return SILC_PACKET_NONE;
 
-  if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
-      ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
+  if (src_id_len > SILC_PACKET_MAX_ID_LEN ||
+      dst_id_len > SILC_PACKET_MAX_ID_LEN) {
     SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
-                   ctx->src_id_len, ctx->dst_id_len));
+                   src_id_len, dst_id_len));
     return SILC_PACKET_NONE;
   }
 
   silc_buffer_pull(buffer, len);
   ret = silc_buffer_unformat(buffer, 
                             SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
-                                                       ctx->src_id_len),
-                            SILC_STR_UI_CHAR(&ctx->dst_id_type),
+                                                       src_id_len),
+                            SILC_STR_UI_CHAR(&dst_id_type),
                             SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
-                                                       ctx->dst_id_len),
-                            SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
+                                                       dst_id_len),
+                            SILC_STR_UI_XNSTRING(NULL, padlen),
                             SILC_STR_END);
   if (ret == -1)
     return SILC_PACKET_NONE;
 
+  if (src_id_type > SILC_ID_CHANNEL || dst_id_type > SILC_ID_CHANNEL) {
+    SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
+                  src_id_type, dst_id_type));
+    return SILC_PACKET_NONE;
+  }
+
+  ctx->src_id_len = src_id_len;
+  ctx->dst_id_len = dst_id_len;
+  ctx->src_id_type = src_id_type;
+  ctx->dst_id_type = dst_id_type;
+  ctx->padlen = padlen;
+
   silc_buffer_push(buffer, len);
 
   SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len), 
@@ -653,6 +667,7 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx,
   SilcBuffer buffer = ctx->buffer;
   SilcUInt8 tmp;
   int len, ret;
+  SilcUInt8 src_id_len, src_id_type, dst_id_len, dst_id_type, padlen;
 
   SILC_LOG_DEBUG(("Parsing incoming packet"));
 
@@ -667,38 +682,50 @@ SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx,
                             SILC_STR_UI_SHORT(&ctx->truelen),
                             SILC_STR_UI_CHAR(&ctx->flags),
                             SILC_STR_UI_CHAR(&ctx->type),
-                            SILC_STR_UI_CHAR(&ctx->padlen),
+                            SILC_STR_UI_CHAR(&padlen),
                             SILC_STR_UI_CHAR(&tmp),
-                            SILC_STR_UI_CHAR(&ctx->src_id_len),
-                            SILC_STR_UI_CHAR(&ctx->dst_id_len),
-                            SILC_STR_UI_CHAR(&ctx->src_id_type),
+                            SILC_STR_UI_CHAR(&src_id_len),
+                            SILC_STR_UI_CHAR(&dst_id_len),
+                            SILC_STR_UI_CHAR(&src_id_type),
                             SILC_STR_END);
   if (len == -1 || tmp != 0) {
     SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
     return SILC_PACKET_NONE;
   }
 
-  if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
-      ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
+  if (src_id_len > SILC_PACKET_MAX_ID_LEN ||
+      dst_id_len > SILC_PACKET_MAX_ID_LEN) {
     SILC_LOG_ERROR(("Bad ID lengths in packet (%d and %d)",
-                   ctx->src_id_len, ctx->dst_id_len));
+                   src_id_len, dst_id_len));
     return SILC_PACKET_NONE;
   }
 
   silc_buffer_pull(buffer, len);
   ret = silc_buffer_unformat(buffer, 
                             SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
-                                                       ctx->src_id_len),
-                            SILC_STR_UI_CHAR(&ctx->dst_id_type),
+                                                       src_id_len),
+                            SILC_STR_UI_CHAR(&dst_id_type),
                             SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
-                                                       ctx->dst_id_len),
-                            SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
+                                                       dst_id_len),
+                            SILC_STR_UI_XNSTRING(NULL, padlen),
                             SILC_STR_END);
   if (ret == -1) {
     SILC_LOG_ERROR(("Malformed packet header, packet dropped"));
     return SILC_PACKET_NONE;
   }
 
+  if (src_id_type > SILC_ID_CHANNEL || dst_id_type > SILC_ID_CHANNEL) {
+    SILC_LOG_ERROR(("Bad ID types in packet (%d and %d)",
+                  src_id_type, dst_id_type));
+    return SILC_PACKET_NONE;
+  }
+
+  ctx->src_id_len = src_id_len;
+  ctx->dst_id_len = dst_id_len;
+  ctx->src_id_type = src_id_type;
+  ctx->dst_id_type = dst_id_type;
+  ctx->padlen = padlen;
+
   silc_buffer_push(buffer, len);
 
   SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),