예제 #1
0
int lit_i_read_sections(lit_file * litfile )
{
    U8          *pNamelist;
    int         status;
    int         nbytes, num_sections, size, section, idx;

    status = lit_get_file(litfile, namelist_string, &pNamelist,&nbytes);
    if (status) return status;

    idx = 2;
    size = 2;
    if ((idx + size) > nbytes) goto bad;
    num_sections = READ_U16(pNamelist+idx);
    idx += 2;

    litfile->sections = malloc(num_sections * sizeof(section_type));
    if (!litfile->sections) {
        lit_error(ERR_R|ERR_LIBC,"malloc(%d) failed!\n",
            num_sections*sizeof(section_type));
        free(pNamelist);
        return E_LIT_OUT_OF_MEMORY;
    }
    memset(litfile->sections, 0, num_sections * sizeof(section_type));

    litfile->num_sections = num_sections;

    for (section = 0; section < num_sections; section++) {
        int j;

        size = 2;
        if ((idx + size) > nbytes) goto bad;
        size = READ_U16(pNamelist + idx);
        idx += 2;

        if (size > MAX_SECTION_NAME) {
            lit_error(ERR_R,
"litlib.c cannot handle a %d byte section name, fix MAX_SECTION_NAME (%d)\n",
                size, MAX_SECTION_NAME);
            return -1;
        }
        size = (size * 2) + 2;

        if ((idx + size) > nbytes) goto bad;

        for (j = 0; j < size; j+=2) {
            litfile->sections[section].name[j/2] = pNamelist[idx + j];
        }
        litfile->sections[section].name[j/2] = '\0';
        idx += size;
    }
    free(pNamelist);
    return 0;
bad:
    lit_error(ERR_R,
        "Invalid or corrupt ::DataSpace/Namelist!\n"
        "\nTried to read %d bytes past length of (%ld)\n", size,nbytes);
    if (pNamelist) free(pNamelist);
    return -1;
}
예제 #2
0
/*--[guid2string]--------------------------------------------------------------
 |
 | Careful - uses a static string.  Will be awkward if called the same
 | time in a statement.
 | Assumes GUID is in Little Endian Order
 |
*/
const char * guid2string(U8 * guid)
{
    static char guid_buffer[7+8+4+4+4+12+1];

    sprintf(guid_buffer, "{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
        (U32)READ_U32(guid), (U16)READ_U16((guid+4)),
        (U16)READ_U16((guid+6)),
        (U8)*(guid+8), (U8)*(guid+9), /*-*/
        (U8)*(guid+10), (U8)*(guid+11), (U8)*(guid+12),
        (U8)*(guid+13), (U8)*(guid+14),
        (U8)*(guid+15));
   return guid_buffer;
}
예제 #3
0
bool unabto_util_test(void) {

    uint8_t buf[] = {0x00,0x00,0x00,0x00,0x12, 0x34, 0x56, 0x78};
    uint32_t* buf2 = (uint32_t*)buf;
    uint32_t testNr;
    uint16_t testu16;
    bool ret = true;
    READ_U32(testNr, buf+4);
    if (testNr != 305419896) {       // 0x12345678 in host byte order
        NABTO_LOG_TRACE(("testNr: %i", testNr));
        ret = false;
    }
    
    READ_U32(testNr, buf2+1);
    if (testNr != 0x12345678) {
        NABTO_LOG_TRACE(("testNr: %i", testNr));
        ret = false;
    }

    READ_U16(testu16, buf+4);
    if (testu16 != 4660) {
        NABTO_LOG_TRACE(("testu16 read failed %i", testu16));
        ret = false;
    }

    WRITE_U32(buf, 0x01020304);
    if (buf[0] != 0x01 ||
        buf[1] != 0x02 || 
        buf[2] != 0x03 ||
        buf[3] != 0x04) {
        NABTO_LOG_TRACE(("WRITE u32 failed"));
        ret = false;
    }
    
    WRITE_U16(buf, 0x0506);
    if (buf[0] != 0x05 || 
        buf[1] != 0x06) {
        NABTO_LOG_TRACE(("WRITE u16 failed"));
        ret = false;
    }

    return ret;
    
}
예제 #4
0
파일: ps_reader.c 프로젝트: ms-iot/userland
static VC_CONTAINER_STATUS_T ps_read_system_header( VC_CONTAINER_T *ctx )
{
   uint8_t header[8];
   uint32_t length;
   VC_CONTAINER_BITS_T bits;

   if(_READ_U32(ctx) != 0x1BB) return VC_CONTAINER_ERROR_CORRUPTED;
   LOG_FORMAT(ctx, "system_header");
   ctx->priv->module->level++;

   length = READ_U16(ctx, "header_length");
   if(length < 6) return VC_CONTAINER_ERROR_CORRUPTED;
   if(READ_BYTES(ctx, header, 6) != 6) return VC_CONTAINER_ERROR_EOS;

   BITS_INIT(ctx, &bits, header, 6);

   if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   BITS_SKIP(ctx, &bits, 22, "rate_bound");
   if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   BITS_SKIP(ctx, &bits, 6, "audio_bound");
   BITS_SKIP(ctx, &bits, 1, "fixed_flag");
   BITS_SKIP(ctx, &bits, 1, "CSPS_flag");
   BITS_SKIP(ctx, &bits, 1, "system_audio_lock_flag");
   BITS_SKIP(ctx, &bits, 1, "system_video_lock_flag");
   if(BITS_READ_U32(ctx, &bits, 1, "marker_bit") != 0x1) return VC_CONTAINER_ERROR_CORRUPTED;
   BITS_SKIP(ctx, &bits, 5, "video_bound");
   BITS_SKIP(ctx, &bits, 1, "packet_rate_restriction_flag");
   BITS_SKIP(ctx, &bits, 7, "reserved_bits");
   length -= 6;

   while(length >= 3 && (PEEK_U8(ctx) & 0x80))
   {
      SKIP_U8(ctx, "stream_id");
      SKIP_BYTES(ctx, 2);
      length -= 3;
   }
   SKIP_BYTES(ctx, length);

   ctx->priv->module->level--;
   return STREAM_STATUS(ctx);
}
예제 #5
0
int CDVDOverlayCodecTX3G::Decode(BYTE* data, int size, double pts, double duration)
{
  if (m_pOverlay)
    SAFE_RELEASE(m_pOverlay);

  m_pOverlay = new CDVDOverlayText();
  m_pOverlay->iPTSStartTime = pts;
  m_pOverlay->iPTSStopTime  = pts + duration;

  // do not move this. READ_XXXX macros modify pos.
  uint8_t  *pos = data;
  uint8_t  *end = pos + size;

  // Parse the packet as a TX3G TextSample.
  // Look for a single StyleBox ('styl') and 
  // read all contained StyleRecords.
  // Ignore all other box types.
  // NOTE: Buffer overflows on read are not checked.
  // ALSO: READ_XXXX/SKIP_XXXX macros will modify pos.
  uint16_t textLength = READ_U16();
  uint8_t *text = READ_ARRAY(textLength);

  int numStyleRecords = 0;
  uint8_t *bgnStyle   = (uint8_t*)calloc(textLength, 1);
  uint8_t *endStyle   = (uint8_t*)calloc(textLength, 1);
  int bgnColorIndex = 0, endColorIndex = 0;
  uint32_t textColorRGBA = m_textColor;
  while (pos < end)
  {
    // Read TextSampleModifierBox
    uint32_t size = READ_U32();
    if (size == 0)
      size = pos - end;   // extends to end of packet
    if (size == 1)
    {
      CLog::Log(LOGDEBUG, "CDVDOverlayCodecTX3G: TextSampleModifierBox has unsupported large size" );
      break;
    }
    uint32_t type = READ_U32();
    if (type == FOURCC("uuid"))
    {
      CLog::Log(LOGDEBUG, "CDVDOverlayCodecTX3G: TextSampleModifierBox has unsupported extended type" );
      break;
    }

    if (type == FOURCC("styl"))
    {
      // Found a StyleBox. Parse the contained StyleRecords
      if ( numStyleRecords != 0 )
      {
        CLog::Log(LOGDEBUG, "CDVDOverlayCodecTX3G: found additional StyleBoxes on subtitle; skipping" );
        SKIP_ARRAY(size);
        continue;
      }

      numStyleRecords = READ_U16();
      for (int i = 0; i < numStyleRecords; i++)
      {
        StyleRecord curRecord;
        curRecord.bgnChar         = READ_U16();
        curRecord.endChar         = READ_U16();
        curRecord.fontID          = READ_U16();
        curRecord.faceStyleFlags  = READ_U8();
        curRecord.fontSize        = READ_U8();
        curRecord.textColorRGBA   = READ_U32();

        bgnStyle[curRecord.bgnChar] |= curRecord.faceStyleFlags;
        endStyle[curRecord.endChar] |= curRecord.faceStyleFlags;
        bgnColorIndex = curRecord.bgnChar;
        endColorIndex = curRecord.endChar;
        textColorRGBA = curRecord.textColorRGBA;
      }
    }
    else
    {
      // Found some other kind of TextSampleModifierBox. Skip it.
      SKIP_ARRAY(size);
    }
  }

  // Copy text to out and add HTML markup for the style records
  int charIndex = 0;
  CStdStringA strUTF8;
  for (pos = text, end = text + textLength; pos < end; pos++)
  {
    if ((*pos & 0xC0) == 0x80)
    {
      // Is a non-first byte of a multi-byte UTF-8 character
      strUTF8.append((const char*)pos, 1);
      continue;   // ...without incrementing 'charIndex'
    }

    uint8_t bgnStyles = bgnStyle[charIndex];
    uint8_t endStyles = endStyle[charIndex];

    // [B] or [/B] -> toggle bold on and off
    // [I] or [/I] -> toggle italics on and off
    // [COLOR ffab007f] or [/COLOR] -> toggle color on and off
    // [CAPS <option>]  or [/CAPS]  -> toggle capatilization on and off

    if (endStyles & BOLD)
      strUTF8.append("[/B]");
    if (endStyles & ITALIC)
      strUTF8.append("[/I]");
    // we do not support underline
    //if (endStyles & UNDERLINE)
    //  strUTF8.append("[/U]");
    if (endColorIndex == charIndex && textColorRGBA != m_textColor)
      strUTF8.append("[/COLOR]");

    // invert the order from above so we bracket the text correctly.
    if (bgnColorIndex == charIndex && textColorRGBA != m_textColor)
      strUTF8.AppendFormat("[COLOR %8x]", textColorRGBA);
    // we do not support underline
    //if (bgnStyles & UNDERLINE)
    //  strUTF8.append("[U]");
    if (bgnStyles & ITALIC)
      strUTF8.append("[I]");
    if (bgnStyles & BOLD)
      strUTF8.append("[B]");

    // stuff the UTF8 char
    strUTF8.append((const char*)pos, 1);

    // this is a char index, not a byte index.
    charIndex++;
  }
  
  free(bgnStyle);
  free(endStyle);
    
  if (strUTF8.IsEmpty())
    return OC_BUFFER;

  if (strUTF8[strUTF8.size()-1] == '\n')
    strUTF8.Delete(strUTF8.size()-1);

  // add a new text element to our container
  m_pOverlay->AddElement(new CDVDOverlayText::CElementText(strUTF8.c_str()));

  return OC_OVERLAY;
}
예제 #6
0
int CDVDOverlayCodecTX3G::Decode(DemuxPacket *pPacket)
{
  if (m_pOverlay)
    SAFE_RELEASE(m_pOverlay);

  m_pOverlay = new CDVDOverlayText();
  CDVDOverlayCodec::GetAbsoluteTimes(m_pOverlay->iPTSStartTime, m_pOverlay->iPTSStopTime, pPacket, m_pOverlay->replace);

  // do not move this. READ_XXXX macros modify pos.
  uint8_t  *pos = pPacket->pData;
  uint8_t  *end = pPacket->pData + pPacket->iSize;

  // Parse the packet as a TX3G TextSample.
  // Look for a single StyleBox ('styl') and 
  // read all contained StyleRecords.
  // Ignore all other box types.
  // NOTE: Buffer overflows on read are not checked.
  // ALSO: READ_XXXX/SKIP_XXXX macros will modify pos.
  LEN_CHECK(2);
  uint16_t textLength = READ_U16();
  LEN_CHECK(textLength);
  uint8_t *text = READ_ARRAY(textLength);

  int numStyleRecords = 0;
  // reserve one more style slot for broken encoders

  XUTILS::auto_buffer bgnStyle(textLength+1);
  XUTILS::auto_buffer endStyle(textLength+1);

  memset(bgnStyle.get(), 0, textLength+1);
  memset(endStyle.get(), 0, textLength+1);

  int bgnColorIndex = 0, endColorIndex = 0;
  uint32_t textColorRGBA = m_textColor;
  while (pos < end)
  {
    // Read TextSampleModifierBox
    LEN_CHECK(4);
    uint32_t size = READ_U32();
    if (size == 0)
      size = pos - end;   // extends to end of packet
    if (size == 1)
    {
      CLog::Log(LOGDEBUG, "CDVDOverlayCodecTX3G: TextSampleModifierBox has unsupported large size" );
      break;
    }
    LEN_CHECK(4);
    uint32_t type = READ_U32();
    if (type == FOURCC("uuid"))
    {
      CLog::Log(LOGDEBUG, "CDVDOverlayCodecTX3G: TextSampleModifierBox has unsupported extended type" );
      break;
    }

    if (type == FOURCC("styl"))
    {
      // Found a StyleBox. Parse the contained StyleRecords
      if ( numStyleRecords != 0 )
      {
        CLog::Log(LOGDEBUG, "CDVDOverlayCodecTX3G: found additional StyleBoxes on subtitle; skipping" );
        LEN_CHECK(size);
        SKIP_ARRAY(size);
        continue;
      }

      LEN_CHECK(2);
      numStyleRecords = READ_U16();
      for (int i = 0; i < numStyleRecords; i++)
      {
        StyleRecord curRecord;
        LEN_CHECK(12);
        curRecord.bgnChar         = READ_U16();
        curRecord.endChar         = READ_U16();
        curRecord.fontID          = READ_U16();
        curRecord.faceStyleFlags  = READ_U8();
        curRecord.fontSize        = READ_U8();
        curRecord.textColorRGBA   = READ_U32();
        // clamp bgnChar/bgnChar to textLength,
        // we alloc enough space above and this
        // fixes borken encoders that do not handle
        // endChar correctly.
        if (curRecord.bgnChar > textLength)
          curRecord.bgnChar = textLength;
        if (curRecord.endChar > textLength)
          curRecord.endChar = textLength;

        bgnStyle.get()[curRecord.bgnChar] |= curRecord.faceStyleFlags;
        endStyle.get()[curRecord.endChar] |= curRecord.faceStyleFlags;
        bgnColorIndex = curRecord.bgnChar;
        endColorIndex = curRecord.endChar;
        textColorRGBA = curRecord.textColorRGBA;
      }
    }
    else
    {
      // Found some other kind of TextSampleModifierBox. Skip it.
      LEN_CHECK(size);
      SKIP_ARRAY(size);
    }
  }

  // Copy text to out and add HTML markup for the style records
  int charIndex = 0;
  std::string strUTF8;
  // index over textLength chars to include broken encoders,
  // so we pickup closing styles on broken encoders
  for (pos = text, end = text + textLength; pos <= end; pos++)
  {
    if ((*pos & 0xC0) == 0x80)
    {
      // Is a non-first byte of a multi-byte UTF-8 character
      strUTF8.append((const char*)pos, 1);
      continue;   // ...without incrementing 'charIndex'
    }

    uint8_t bgnStyles = bgnStyle.get()[charIndex];
    uint8_t endStyles = endStyle.get()[charIndex];

    // [B] or [/B] -> toggle bold on and off
    // [I] or [/I] -> toggle italics on and off
    // [COLOR ffab007f] or [/COLOR] -> toggle color on and off
    // [CAPS <option>]  or [/CAPS]  -> toggle capatilization on and off

    if (endStyles & BOLD)
      strUTF8.append("[/B]");
    if (endStyles & ITALIC)
      strUTF8.append("[/I]");
    // we do not support underline
    //if (endStyles & UNDERLINE)
    //  strUTF8.append("[/U]");
    if (endColorIndex == charIndex && textColorRGBA != m_textColor)
      strUTF8.append("[/COLOR]");

    // invert the order from above so we bracket the text correctly.
    if (bgnColorIndex == charIndex && textColorRGBA != m_textColor)
      strUTF8 += StringUtils::Format("[COLOR %8x]", textColorRGBA);
    // we do not support underline
    //if (bgnStyles & UNDERLINE)
    //  strUTF8.append("[U]");
    if (bgnStyles & ITALIC)
      strUTF8.append("[I]");
    if (bgnStyles & BOLD)
      strUTF8.append("[B]");

    // stuff the UTF8 char
    strUTF8.append((const char*)pos, 1);

    // this is a char index, not a byte index.
    charIndex++;
  }
  
  if (strUTF8.empty())
    return OC_BUFFER;

  if (strUTF8[strUTF8.size()-1] == '\n')
    strUTF8.erase(strUTF8.size()-1);

  // add a new text element to our container
  m_pOverlay->AddElement(new CDVDOverlayText::CElementText(strUTF8.c_str()));

  return OC_OVERLAY;
}
void unabto_tcp_fallback_read_packet(nabto_connect* con) {
    unabto_tcp_fallback_connection* fbConn = &fbConns[nabto_connection_index(con)];
    while(true) {
        if (fbConn->recvBufferLength < 16) {
            int status = recv(fbConn->socket, fbConn->recvBuffer + fbConn->recvBufferLength, 16-fbConn->recvBufferLength, 0);
            int err = errno;
            if (status < 0) {
                if ((err == EAGAIN) || err == EWOULDBLOCK) {
                    return;
                } else {
                    NABTO_LOG_ERROR((PRI_tcp_fb "unabto_tcp_fallback_read_single_packet failed", TCP_FB_ARGS(con)));
                    unabto_tcp_fallback_close(con);
                    return;
                }
            } else if (status == 0) {
                NABTO_LOG_INFO((PRI_tcp_fb "TCP fallback connection closed by peer", TCP_FB_ARGS(con)));
                unabto_tcp_fallback_close(con);
                return;
            } else {
                fbConn->recvBufferLength+=status;
            }
        }

        if (fbConn->recvBufferLength >= 16) {
            uint16_t packetLength;
            int status;
            int err;
            READ_U16(packetLength, fbConn->recvBuffer+14);
            
            status = recv(fbConn->socket, fbConn->recvBuffer + fbConn->recvBufferLength, packetLength - fbConn->recvBufferLength, 0);
            err = errno;
            if (status < 0) {
                if ((err == EAGAIN) || err == EWOULDBLOCK) {
                    return;
                } else {
                    NABTO_LOG_ERROR((PRI_tcp_fb "Tcp read failed", TCP_FB_ARGS(con)));
                    unabto_tcp_fallback_close(con);
                    return;
                }
            } else if (status == 0) {
                NABTO_LOG_INFO((PRI_tcp_fb "TCP fallback connection closed by peer", TCP_FB_ARGS(con)));
                unabto_tcp_fallback_close(con);
                return;
            } else {
                fbConn->recvBufferLength += status;
            }
            
            if (fbConn->recvBufferLength == packetLength) {
                message_event event;
                event.type = MT_TCP_FALLBACK;
                
                memcpy(nabtoCommunicationBuffer, fbConn->recvBuffer, fbConn->recvBufferLength);
                
                NABTO_LOG_TRACE((PRI_tcp_fb "Received fallback packet length %" PRIsize, TCP_FB_ARGS(con), fbConn->recvBufferLength));
                
                nabto_message_event(&event, fbConn->recvBufferLength);
                NABTO_LOG_TRACE((PRI_tcp_fb "fallback packet done\n==================================================", TCP_FB_ARGS(con)));
                
                fbConn->recvBufferLength = 0;
            }
        }
    }
}
예제 #8
0
void unabto_sha256_final(sha256_ctx* context,sha2_byte digest[]) {
	sha2_word32	*d = (sha2_word32*)digest;
	unsigned int	usedspace;

	/* Sanity check: */
//	assert(context != (sha256_ctx*)0);

	/* If no digest buffer is passed, we don't bother doing this: */
	if (digest != (sha2_byte*)0) {
		usedspace = context->byteCount % SHA256_BLOCK_LENGTH;

		if (usedspace > 0) {
			/* Begin padding with a 1 bit: */
			context->buffer[usedspace++] = 0x80;

			if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
				/* Set-up for the last transform: */
				MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
			} else {
				if (usedspace < SHA256_BLOCK_LENGTH) {
					MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
				}
				/* Do second-to-last transform: */
				SHA256_Transform(context, (sha2_word32*)context->buffer);

				/* And set-up for the last transform: */
				MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
			}
		} else {
			/* Set-up for the last transform: */
			MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);

			/* Begin padding with a 1 bit: */
			*context->buffer = 0x80;
		}

		/* Set the bit count: */
		/* Convert FROM host byte order */
    {
      uint16_t tmp16;
      uint16_t tmp16_ = context->byteCount;
      tmp16_ <<= 3;
      READ_U16(tmp16, &tmp16_);
      memset(&context->buffer[SHA256_BLOCK_LENGTH - 8], 0, 6);
      *(uint16_t*)&context->buffer[SHA256_BLOCK_LENGTH - 2] = tmp16;
    }
        //print_sha256_ctx(context);
		/* Final transform: */
		SHA256_Transform(context, (sha2_word32*)context->buffer);
        //print_sha256_ctx(context);

		{
			/* Convert TO host byte order */
			uint8_t	j;
			for (j = 0; j < 8; j++) {
        WRITE_U32(d, context->state[j]);
        d++;
			}
		}
	}

	/* Clean up state data: */
	MEMSET_BZERO(context, sizeof(sha256_ctx));
	usedspace = 0;
}
bool rendezvous_event(message_event* event, nabto_packet_header* hdr)
{
    uint8_t*          end = nabtoCommunicationBuffer + hdr->len;
    uint16_t          res = hdr->hlen;

    uint8_t*          ptr;
    uint8_t           type;
    nabto_endpoint  epUD;
    nabto_connect*  con   = 0;
    nabto_endpoint  src;
    uint32_t        interval = 5000;

    src = event->udpMessage.peer;
    NABTO_LOG_TRACE((PRInsi " Received from " PRIep " seq=%" PRIu16, MAKE_NSI_PRINTABLE(0, hdr->nsi_sp, 0), MAKE_EP_PRINTABLE(src), hdr->seq));

    ptr = nabtoCommunicationBuffer + res;
    res = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER;
    if (res != 6 || type != NP_PAYLOAD_TYPE_EP) {
        NABTO_LOG_TRACE(("Can't read first EP"));
        return false;
    }
    READ_U32(epUD.addr, ptr); ptr += 4;
    READ_U16(epUD.port, ptr); ptr += 2;
    res = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER;
    if (res == 6 && type == NP_PAYLOAD_TYPE_EP) {
        // The second EP is not neccessary since we read the destination ep from the udp packet.
        
        ptr += 6;
        res = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER;
        if (res == 4 && type == NP_PAYLOAD_TYPE_NONCE) {
            READ_U32(interval, ptr);
            NABTO_LOG_TRACE((PRInsi " Read interval from packet: %" PRIu32, MAKE_NSI_PRINTABLE(0, hdr->nsi_sp, 0), interval));
            if (interval == 0) {
                NABTO_LOG_WARN(("Interval was 0, setting to 5000"));
                interval = 5000;
            }
        }
    }

    con  = nabto_find_connection(hdr->nsi_sp);

    if (!con) {
        NABTO_LOG_ERROR(("Connection was not found, nsi: %i", hdr->nsi_sp));
    } else {
        if (hdr->seq == 0) {
            send_rendezvous_socket(event->udpMessage.socket, con, 1, &src, &epUD);
        } else if (hdr->seq == 1) {
            send_rendezvous_socket(event->udpMessage.socket, con, 2, &src, &epUD);
            if (!conclude_connection(con, &src, interval)) {
                return false;
            }
        } else if (hdr->seq == 2) {
            if (!conclude_connection(con, &src, interval)) {
                return false;
            }
        } else {
            NABTO_LOG_ERROR(("Invalid Sequence Number"));
        }
    }
    return false;
}
nabto_connect* nabto_init_connection(nabto_packet_header* hdr, uint32_t* nsi, uint32_t* ec, bool isLocal)
{
    uint8_t  type;
    uint8_t  flags;   /* NP_PAYLOAD_IPX_FLAG_* */
    nabto_connect* con;

    const uint8_t* end = nabtoCommunicationBuffer + hdr->len;
    uint8_t* ptr = nabtoCommunicationBuffer + hdr->hlen;
    uint16_t res;
    uint16_t ipxPayloadLength;
    
    ipxPayloadLength = nabto_rd_payload(ptr, end, &type); ptr += SIZE_PAYLOAD_HEADER;
    
    *nsi = 0;
    *ec  = 0;

    if ((ipxPayloadLength != IPX_PAYLOAD_LENGTH_WITHOUT_NSI) && 
        (ipxPayloadLength != IPX_PAYLOAD_LENGTH_WITH_NSI) && 
        (ipxPayloadLength != IPX_PAYLOAD_LENGTH_FULL_NSI)) {
        NABTO_LOG_TRACE(("Illegal payload size in U_CONNECT request from GSP: %" PRIu16 " %" PRIu8, ipxPayloadLength, type));
        return 0;
    }
    if (type != NP_PAYLOAD_TYPE_IPX) {
        NABTO_LOG_TRACE(("Illegal payload type in U_CONNECT request from GSP: %" PRIu16 " %" PRIu8, ipxPayloadLength, type));
        return 0;
    }
    
    if (ipxPayloadLength == IPX_PAYLOAD_LENGTH_WITH_NSI || 
        ipxPayloadLength == IPX_PAYLOAD_LENGTH_FULL_NSI) {
        READ_U32(*nsi, ptr + 13);
        NABTO_LOG_TRACE(("IPX payload with NSI (SPNSI=%" PRIu32 ")", *nsi));
    } else {
        *nsi = fresh_nsi();
        NABTO_LOG_TRACE(("IPX payload without NSI (fresh NSI=%" PRIu32 ")", *nsi));
    }

    if (*nsi == 0) {
        NABTO_LOG_ERROR(("Trying to create connection with spnsi == 0"));
        return 0;
    }

    if (nabto_find_connection(*nsi)) {
        NABTO_LOG_DEBUG((PRInsi " A connection already exists this is probably a retransmission", MAKE_NSI_PRINTABLE(0, *nsi, 0)));
        *ec = NOTIFY_CONNECT_OK;
        return 0;
    }

    con = nabto_init_connection_real(*nsi);

    if (con == 0) {
        if (nabto_find_connection(*nsi)) {
            NABTO_LOG_DEBUG((PRInsi " U_CONNECT: A connection resource is already pending new connection", MAKE_NSI_PRINTABLE(0, *nsi, 0)));
        } else {
            NABTO_LOG_INFO((PRInsi " U_CONNECT: No connection resources free for new connection", MAKE_NSI_PRINTABLE(0, *nsi, 0)));
#if NABTO_ENABLE_DEVICE_BUSY_AS_FATAL
            NABTO_LOG_FATAL((PRInsi " U_CONNECT: No free connections configured to be considered fatal", MAKE_NSI_PRINTABLE(0, *nsi, 0)));
#endif
        }
        *ec = NOTIFY_ERROR_BUSY_MICRO;
        return 0;
    }

    NABTO_LOG_DEBUG((PRInsi " U_CONNECT: Connecting using record %i", MAKE_NSI_PRINTABLE(0, *nsi, 0), nabto_connection_index(con)));
    READ_U32(con->cp.privateEndpoint.addr, ptr +  0);
    READ_U16(con->cp.privateEndpoint.port, ptr +  4);
    READ_U32(con->cp.globalEndpoint.addr, ptr +  6);
    READ_U16(con->cp.globalEndpoint.port, ptr + 10);
    READ_U8(flags,                ptr + 12); /* the final word (4 bytes) has been read already (nsi) */
    con->noRendezvous = (flags & NP_PAYLOAD_IPX_FLAG_NO_RENDEZVOUS) ? 1 : 0;
    con->cpEqual      = EP_EQUAL(con->cp.privateEndpoint, con->cp.globalEndpoint);
    con->cpAsync      = (flags & NP_PAYLOAD_IPX_FLAG_CP_ASYNC) ? 1 : 0;
    con->clientNatType      = (flags & NP_PAYLOAD_IPX_NAT_MASK);
    con->isLocal      = isLocal;
    NABTO_LOG_INFO((PRInsi " U_CONNECT: cp.private: " PRIep " cp.global: " PRIep ", noRdv=%" PRIu8 ", cpeq=%" PRIu8 ", asy=%" PRIu8 ", NATType: %" PRIu8 , MAKE_NSI_PRINTABLE(0, *nsi, 0), MAKE_EP_PRINTABLE(con->cp.privateEndpoint), MAKE_EP_PRINTABLE(con->cp.globalEndpoint), con->noRendezvous, con->cpEqual, con->cpAsync, con->clientNatType));

#if NABTO_ENABLE_TCP_FALLBACK
    if (ipxPayloadLength == IPX_PAYLOAD_LENGTH_FULL_NSI) {
        memcpy(con->consi, ptr+17, 8);
        con->nsico = con->consi;
        READ_U32(con->cpnsi, ptr+25);
    }
#endif

    ptr += ipxPayloadLength;  //IPX_PAYLOAD_LENGTH_WITHOUT_NSI or IPX_PAYLOAD_LENGTH_WITH_NSI
        
    con->clientId[0]  = 0;
    res = nabto_rd_payload(ptr, end, &type);
    if (type == NP_PAYLOAD_TYPE_CP_ID) {
        uint8_t idType;
        ptr += SIZE_PAYLOAD_HEADER;
        if (res > 0) {
            READ_U8(idType, ptr); ++ptr; --res;
            if (idType == 1) { // 1 == EMAIL
                size_t sz = res;
                if (sz >= sizeof(con->clientId)) {
                    if (sizeof(con->clientId) > 1) {
                        NABTO_LOG_WARN(("Client ID truncated"));
                    }
                    sz = sizeof(con->clientId) - 1;
                }
                if (sz) {
                    memcpy(con->clientId, (const void*) ptr, sz);
                }
                con->clientId[sz] = 0;
            }
        }
        NABTO_LOG_TRACE(("Connection opened from '%s' (to %s)", con->clientId, nmc.nabtoMainSetup.id));
        ptr += res;
    }
#if NABTO_ENABLE_CONNECTION_ESTABLISHMENT_ACL_CHECK
    if (!allow_client_access(con)) {
        *ec = NOTIFY_ERROR_CP_ACCESS;
        goto init_error;
    }
#endif

#if NABTO_ENABLE_TCP_FALLBACK
    {
        uint8_t* gatewayPtr = ptr;
        res = nabto_rd_payload(ptr, end, &type);
        if (type == NP_PAYLOAD_TYPE_GW && ipxPayloadLength == IPX_PAYLOAD_LENGTH_FULL_NSI) {
            uint8_t* gatewayEndPtr;
            size_t idLength;
            NABTO_LOG_TRACE(("The connect contains a gateway payload."));
            ptr += res + SIZE_PAYLOAD_HEADER;
            gatewayPtr += SIZE_PAYLOAD_HEADER;
            gatewayEndPtr = ptr;

            READ_U32(con->fallbackHost.addr, gatewayPtr); gatewayPtr+=4;
            READ_U16(con->fallbackHost.port, gatewayPtr); gatewayPtr+=2;
            // skip the nsi
            gatewayPtr+=4;
        
            idLength = gatewayEndPtr-gatewayPtr;
            if (idLength != 20) {
                NABTO_LOG_FATAL(("The id length should be 20 bytes. bytes=%" PRIsize, idLength));
                // todo
            } 
            memcpy(con->gatewayId, gatewayPtr, 20);
            con->hasTcpFallbackCapabilities = true;
        }
    }
#endif


#if NABTO_ENABLE_UCRYPTO
    if (nmc.context.nonceSize == NONCE_SIZE) {
        uint8_t* decryptedDataStart;
        uint16_t decryptedDataLength;
        if (!unabto_connection_verify_and_decrypt_connect_packet(hdr, &decryptedDataStart, &decryptedDataLength)) {
            NABTO_LOG_TRACE(("Failed to read crypto payload in U_CONNECT"));
        } else {
            unabto_crypto_reinit_d(&con->cryptoctx, nmc.nabtoMainSetup.cryptoSuite, decryptedDataStart, decryptedDataLength);
        }
    } else
#endif
    {
        NABTO_LOG_TRACE(("########    U_CONNECT without crypto payload"));
        unabto_crypto_reinit_d(&con->cryptoctx, CRYPT_W_NULL_DATA, 0, 0);
    }


    con->timeOut = CONNECTION_TIMEOUT;
    nabtoSetFutureStamp(&con->stamp, 20000); /* give much extra time during initialisation */

    if (!verify_connection_encryption(con)) {
        goto init_crypto_error;
    }

    if (con->cpEqual) {
        NABTO_LOG_DEBUG((PRInsi " U_CONNECT: addr:" PRIep " rendezvous:%" PRIu8, MAKE_NSI_PRINTABLE(0, *nsi, 0), MAKE_EP_PRINTABLE(con->cp.privateEndpoint), !con->noRendezvous));
    } else {
        NABTO_LOG_DEBUG((PRInsi " U_CONNECT: private:" PRIep ", global:" PRIep " rendezvous:%" PRIu8, MAKE_NSI_PRINTABLE(0, *nsi, 0), MAKE_EP_PRINTABLE(con->cp.privateEndpoint), MAKE_EP_PRINTABLE(con->cp.globalEndpoint), !con->noRendezvous));
    }

    NABTO_LOG_INFO(("Connection opened from '%s' (to %s). Encryption code %i", con->clientId, nmc.nabtoMainSetup.id, con->cryptoctx.code));

    return con;

init_crypto_error:
    *ec = NOTIFY_ERROR_ENCR_MISMATCH;

#if NABTO_ENABLE_CONNECTION_ESTABLISHMENT_ACL_CHECK
init_error:
    nabto_release_connection(con);
#endif

    return 0;
}
예제 #11
0
void nabto_stream_event(nabto_connect*       con,
                        nabto_packet_header* hdr,
                        uint8_t*             info, //WINDOW payload with payload header
                        uint8_t*             start,
                        int                  dlen,
                        uint8_t*             sackStart,
                        uint16_t             sackLength)
{
    struct nabto_win_info  win;
    struct nabto_stream_s* stream;
    struct nabto_stream_sack_data sackData;
    uint16_t len;

    // We must have a WINDOW payload to continue.
    if (!info) {
        NABTO_LOG_ERROR(("Stream %i, Packet has no WINDOW payload!", hdr->tag));
        return;
    }
    
    READ_U16(len, info + 2);
    if (!nabto_stream_read_window(info + SIZE_PAYLOAD_HEADER, len - SIZE_PAYLOAD_HEADER, &win)) {
        NABTO_LOG_DEBUG(("ReadWin failure"));
        return;
    }

    {
        text msg;
        switch (win.type) {
        case NP_PAYLOAD_WINDOW_FLAG_SYN                             : msg = "SYN";     break;
        case NP_PAYLOAD_WINDOW_FLAG_SYN | NP_PAYLOAD_WINDOW_FLAG_ACK: msg = "SYN|ACK"; break;
        case NP_PAYLOAD_WINDOW_FLAG_FIN | NP_PAYLOAD_WINDOW_FLAG_ACK: msg = "FIN|ACK"; break;
        case NP_PAYLOAD_WINDOW_FLAG_RST                             : msg = "RST";     break;
        case NP_PAYLOAD_WINDOW_FLAG_ACK                             : msg = "DATA";    break;
        default       : msg = "?"; NABTO_LOG_TRACE(("Type?: %" PRIu8, win.type)); break;

        }
        NABTO_NOT_USED(msg);
        NABTO_LOG_DEBUG(("%" PRIu16 " --> [%" PRIu32 ",%" PRIu32 "] %" PRItext ", %d bytes", hdr->tag, win.seq, win.ack, msg, dlen));
    }

    stream = find_stream(hdr->tag, con);
    if (stream == NULL) {
        if (win.type == NP_PAYLOAD_WINDOW_FLAG_SYN) {
            stream = find_free_stream(hdr->tag, con);
            if (stream == NULL) {
                NABTO_LOG_DEBUG(("Stream with tag %i not accepted", hdr->tag));
            }
        } else {
            NABTO_LOG_DEBUG(("Received non syn packet for stream which is not available tag %i", hdr->tag));
        }
    }

    if (stream == NULL) {
        if (! (win.type & NP_PAYLOAD_WINDOW_FLAG_RST)) {
            build_and_send_rst_packet(con, hdr->tag, &win);
        }
        return;
    }
    
    if (!nabto_stream_validate_win(&win, stream)) {
        NABTO_LOG_ERROR(("Cannot validate received stream window."));
        return;
    }

    NABTO_LOG_TRACE(("(.%i.) Stream with tag %i accepted, slot=%i", con->spnsi, hdr->tag, unabto_stream_index(stream)));

    stream->stats.receivedPackets++;
 
    memset(&sackData, 0, sizeof(sackData));
    {
        uint8_t* ptr = sackStart;
        while(sackLength >= 8 && sackData.nPairs < NP_PAYLOAD_SACK_MAX_PAIRS) {
            uint32_t sackSeqStart; // start of sack 
            uint32_t sackSeqEnd; // end of sack one larger than actual acked window.
            READ_FORWARD_U32(sackSeqStart, ptr);
            READ_FORWARD_U32(sackSeqEnd, ptr);
            sackLength -= 8;
            
            sackData.pairs[sackData.nPairs].start = sackSeqStart;
            sackData.pairs[sackData.nPairs].end = sackSeqEnd;
            sackData.nPairs++;
        }
    }

    nabto_stream_tcb_event(stream, &win, start, dlen, &sackData);
}
예제 #12
0
uint16_t uip_nthos(uint16_t s)
{
    uint16_t t;
    READ_U16(t , &s);
    return t;
}
예제 #13
0
/*--[lit_i_read_directory]-----------------------------------------------------
 |
 | This reads the directory chunks from the piece and converts the list into
 | entry elements in the lit_file structure.
 |
*/
int lit_i_read_directory(lit_file * litfile, U8 * piece, int piece_size)
{
    U8      * p = NULL;
    int     nEntries, nRemaining, nChunks, chunk, idx, sizeChunk;
    entry_type * entry, * prev;

    if (!piece || (READ_U32(piece) != IFCM_TAG)) {
        lit_error(ERR_R,
           "Header Piece #3 is not the main directory! (TAG=%08lx)",
           (piece)?(READ_U32(piece)):0);
        return E_LIT_FORMAT_ERROR;
    }
    sizeChunk = READ_INT32(piece + 8);
    nChunks = READ_INT32(piece + 24);

    if ((32 + (nChunks * sizeChunk)) !=  piece_size) {
        lit_error(ERR_R, "IFCM HEADER (%d chunks of %d bytes) != %d total.",
        nChunks, sizeChunk, piece_size - 32);
        return E_LIT_FORMAT_ERROR;
    }
    prev = NULL;
    for (chunk = 0; chunk < nChunks; chunk++)
    {
        p = piece + 32 + (chunk * sizeChunk);

        /* This can either be AOLL or AOLI.
         * AOLI isn't useful for reading */
        if (READ_U32(p) != AOLL_TAG)  continue;

        nRemaining = READ_INT32(p + 4);
        if (nRemaining >= sizeChunk) {
            lit_error(ERR_R,
"AOLL remaining count is NEGATIVE! (%d of %d) %x\n",
            (int)nRemaining, (int)sizeChunk, (int)nRemaining);
            return E_LIT_FORMAT_ERROR;
        }
        nRemaining = sizeChunk - (nRemaining + 48);

        nEntries = READ_U16(p + sizeChunk - 2);

        /* Sometimes, the nEntries doesn't get written. When this happens,
         * I don't know how many to read.  Fortunately, there is "nRemaining",
         * and if everything is working fine, read_entry will consume JUST
         * enough bytes */
        if (!nEntries) nEntries = 65535;

        p += 48;
        if (nRemaining < 0) return E_LIT_FORMAT_ERROR;
        for (idx = 0; idx < nEntries; idx ++) {
            if (nRemaining <= 0) break;
            entry = read_entry(&p, &nRemaining);
            if (!entry) {
                return E_LIT_FORMAT_ERROR;
            }
            if (!prev) {
                litfile->entry = entry;
                prev = entry;
            } else {
                prev->next = entry;
                prev = entry;
            }
        }
    }
    return 0;
}
예제 #14
0
static hb_buffer_t *tx3g_decode_to_utf8( hb_buffer_t *in )
{
    uint8_t *pos = in->data;
    uint8_t *end = in->data + in->size;
    
    uint16_t numStyleRecords = 0;
    
    uint8_t *startStyle;
    uint8_t *endStyle;
    
    /*
     * Parse the packet as a TX3G TextSample.
     * 
     * Look for a single StyleBox ('styl') and read all contained StyleRecords.
     * Ignore all other box types.
     * 
     * NOTE: Buffer overflows on read are not checked.
     */
    uint16_t textLength = READ_U16();
    uint8_t *text = READ_ARRAY(textLength);
    startStyle = calloc( textLength, 1 );
    endStyle = calloc( textLength, 1 );
    while ( pos < end ) {
        /*
         * Read TextSampleModifierBox
         */
        uint32_t size = READ_U32();
        if ( size == 0 ) {
            size = pos - end;   // extends to end of packet
        }
        if ( size == 1 ) {
            hb_log( "dectx3gsub: TextSampleModifierBox has unsupported large size" );
            break;
        }
        uint32_t type = READ_U32();
        if ( type == FOURCC("uuid") ) {
            hb_log( "dectx3gsub: TextSampleModifierBox has unsupported extended type" );
            break;
        }
        
        if ( type == FOURCC("styl") ) {
            // Found a StyleBox. Parse the contained StyleRecords
            
            if ( numStyleRecords != 0 ) {
                hb_log( "dectx3gsub: found additional StyleBoxes on subtitle; skipping" );
                SKIP_ARRAY(size);
                continue;
            }
            
            numStyleRecords = READ_U16();
            
            int i;
            for (i=0; i<numStyleRecords; i++) {
                StyleRecord curRecord;
                curRecord.startChar         = READ_U16();
                curRecord.endChar           = READ_U16();
                curRecord.fontID            = READ_U16();
                curRecord.faceStyleFlags    = READ_U8();
                curRecord.fontSize          = READ_U8();
                curRecord.textColorRGBA     = READ_U32();
                
                startStyle[curRecord.startChar] |= curRecord.faceStyleFlags;
                endStyle[curRecord.endChar]     |= curRecord.faceStyleFlags;
            }
        } else {
            // Found some other kind of TextSampleModifierBox. Skip it.
            SKIP_ARRAY(size);
        }
    }
    
    /*
     * Copy text to output buffer, and add HTML markup for the style records
     */
    int maxOutputSize = textLength + (numStyleRecords * NUM_FACE_STYLE_FLAGS * (MAX_OPEN_TAG_SIZE + MAX_CLOSE_TAG_SIZE));
    hb_buffer_t *out = hb_buffer_init( maxOutputSize );
    if ( out == NULL )
        goto fail;
    uint8_t *dst = out->data;
    int charIndex = 0;
    for ( pos = text, end = text + textLength; pos < end; pos++ ) {
        if (IS_10xxxxxx(*pos)) {
            // Is a non-first byte of a multi-byte UTF-8 character
            WRITE_CHAR(*pos);
            continue;   // ...without incrementing 'charIndex'
        }
        
        uint8_t plusStyles = startStyle[charIndex];
        uint8_t minusStyles = endStyle[charIndex];
        
        if (minusStyles & UNDERLINE)
            WRITE_END_TAG('u');
        if (minusStyles & ITALIC)
            WRITE_END_TAG('i');
        if (minusStyles & BOLD)
            WRITE_END_TAG('b');
        
        if (plusStyles & BOLD)
            WRITE_START_TAG('b');
        if (plusStyles & ITALIC)
            WRITE_START_TAG('i');
        if (plusStyles & UNDERLINE)
            WRITE_START_TAG('u');
        
        WRITE_CHAR(*pos);
        charIndex++;
    }
    
    // Trim output buffer to the actual amount of data written
    out->size = dst - out->data;
    
    // Copy metadata from the input packet to the output packet
    out->s.start = in->s.start;
    out->s.stop = in->s.stop;
    
fail:
    free( startStyle );
    free( endStyle );
    
    return out;
}