<commit_before>#include <stdio.h>
#include <string.h>
#include "I2PEndian.h"
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "version.h"
#include "Crypto.h"
#include "Base.h"
#include "Timestamp.h"
#include "Log.h"
#include "NetDb.h"
#include "RouterInfo.h"

namespace i2p
{
namespace data
{		
	RouterInfo::RouterInfo (): m_Buffer (nullptr) 
	{ 
		m_Addresses = std::make_shared<Addresses>(); // create empty list
	}
	
	RouterInfo::RouterInfo (const std::string& fullPath):
		m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), 
		m_SupportedTransports (0), m_Caps (0)
	{
		m_Addresses = std::make_shared<Addresses>(); // create empty list
		m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
		ReadFromFile ();
	}	

	RouterInfo::RouterInfo (const uint8_t * buf, int len):
		m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
	{
		m_Addresses = std::make_shared<Addresses>(); // create empty list
		m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
		memcpy (m_Buffer, buf, len);
		m_BufferLen = len;
		ReadFromBuffer (true);
	}	

	RouterInfo::~RouterInfo ()
	{
		delete[] m_Buffer;
	}	
		
	void RouterInfo::Update (const uint8_t * buf, int len)
	{
		// verify signature since we have indentity already
		int l = len - m_RouterIdentity->GetSignatureLen ();
		if (m_RouterIdentity->Verify (buf, l, buf + l))
		{
			// clean up
			m_IsUpdated = true;
			m_IsUnreachable = false;
			m_SupportedTransports = 0;
			m_Caps = 0;
			// don't clean up m_Addresses, it will be replaced in ReadFromStream
			m_Properties.clear ();
			// copy buffer
			if (!m_Buffer)	
				m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
			memcpy (m_Buffer, buf, len);
			m_BufferLen = len;
			// skip identity
			size_t identityLen = m_RouterIdentity->GetFullLen ();
			// read new RI	
			std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
			ReadFromStream (str);
			// don't delete buffer until saved to the file
		}
		else
		{	
			LogPrint (eLogError, "RouterInfo: signature verification failed");
			m_IsUnreachable = true;
		}
	}	
		
	void RouterInfo::SetRouterIdentity (std::shared_ptr<const IdentityEx> identity)
	{	
		m_RouterIdentity = identity;
		m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
	}
	
	bool RouterInfo::LoadFile ()
	{
		std::ifstream s(m_FullPath, std::ifstream::binary);
		if (s.is_open ())	
		{	
			s.seekg (0,std::ios::end);
			m_BufferLen = s.tellg ();
			if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE)
			{
				LogPrint(eLogError, "RouterInfo: File", m_FullPath, " is malformed");
				return false;
			}
			s.seekg(0, std::ios::beg);
			if (!m_Buffer)
				m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
			s.read((char *)m_Buffer, m_BufferLen);
		}	
		else
		{
			LogPrint (eLogError, "RouterInfo: Can't open file ", m_FullPath);
			return false;		
		}
		return true;
	}	

	void RouterInfo::ReadFromFile ()
	{
		if (LoadFile ())
			ReadFromBuffer (false); 
		else
			m_IsUnreachable = true;	
	}	

	void RouterInfo::ReadFromBuffer (bool verifySignature)
	{
		m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
		size_t identityLen = m_RouterIdentity->GetFullLen ();
		if (identityLen >= m_BufferLen)
		{
			LogPrint (eLogError, "RouterInfo: identity length ", identityLen, " exceeds buffer size ", m_BufferLen);
			m_IsUnreachable = true;
			return;
		}
		std::stringstream str;
		str.write ((const char *)m_Buffer + identityLen, m_BufferLen - identityLen);
		ReadFromStream (str);
		if (!str)
		{
			LogPrint (eLogError, "RouterInfo: malformed message");
			m_IsUnreachable = true;
			return;
		}
		if (verifySignature)
		{	
			// verify signature
			int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();	
			if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
			{	
				LogPrint (eLogError, "RouterInfo: signature verification failed");
				m_IsUnreachable = true;
			}
			m_RouterIdentity->DropVerifier ();
		}	<commit_msg>check RI signture before processing<commit_after>#include <stdio.h>
#include <string.h>
#include "I2PEndian.h"
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "version.h"
#include "Crypto.h"
#include "Base.h"
#include "Timestamp.h"
#include "Log.h"
#include "NetDb.h"
#include "RouterInfo.h"

namespace i2p
{
namespace data
{		
	RouterInfo::RouterInfo (): m_Buffer (nullptr) 
	{ 
		m_Addresses = std::make_shared<Addresses>(); // create empty list
	}
	
	RouterInfo::RouterInfo (const std::string& fullPath):
		m_FullPath (fullPath), m_IsUpdated (false), m_IsUnreachable (false), 
		m_SupportedTransports (0), m_Caps (0)
	{
		m_Addresses = std::make_shared<Addresses>(); // create empty list
		m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
		ReadFromFile ();
	}	

	RouterInfo::RouterInfo (const uint8_t * buf, int len):
		m_IsUpdated (true), m_IsUnreachable (false), m_SupportedTransports (0), m_Caps (0)
	{
		m_Addresses = std::make_shared<Addresses>(); // create empty list
		m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
		memcpy (m_Buffer, buf, len);
		m_BufferLen = len;
		ReadFromBuffer (true);
	}	

	RouterInfo::~RouterInfo ()
	{
		delete[] m_Buffer;
	}	
		
	void RouterInfo::Update (const uint8_t * buf, int len)
	{
		// verify signature since we have indentity already
		int l = len - m_RouterIdentity->GetSignatureLen ();
		if (m_RouterIdentity->Verify (buf, l, buf + l))
		{
			// clean up
			m_IsUpdated = true;
			m_IsUnreachable = false;
			m_SupportedTransports = 0;
			m_Caps = 0;
			// don't clean up m_Addresses, it will be replaced in ReadFromStream
			m_Properties.clear ();
			// copy buffer
			if (!m_Buffer)	
				m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
			memcpy (m_Buffer, buf, len);
			m_BufferLen = len;
			// skip identity
			size_t identityLen = m_RouterIdentity->GetFullLen ();
			// read new RI	
			std::stringstream str (std::string ((char *)m_Buffer + identityLen, m_BufferLen - identityLen));
			ReadFromStream (str);
			// don't delete buffer until saved to the file
		}
		else
		{	
			LogPrint (eLogError, "RouterInfo: signature verification failed");
			m_IsUnreachable = true;
		}
	}	
		
	void RouterInfo::SetRouterIdentity (std::shared_ptr<const IdentityEx> identity)
	{	
		m_RouterIdentity = identity;
		m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
	}
	
	bool RouterInfo::LoadFile ()
	{
		std::ifstream s(m_FullPath, std::ifstream::binary);
		if (s.is_open ())	
		{	
			s.seekg (0,std::ios::end);
			m_BufferLen = s.tellg ();
			if (m_BufferLen < 40 || m_BufferLen > MAX_RI_BUFFER_SIZE)
			{
				LogPrint(eLogError, "RouterInfo: File", m_FullPath, " is malformed");
				return false;
			}
			s.seekg(0, std::ios::beg);
			if (!m_Buffer)
				m_Buffer = new uint8_t[MAX_RI_BUFFER_SIZE];
			s.read((char *)m_Buffer, m_BufferLen);
		}	
		else
		{
			LogPrint (eLogError, "RouterInfo: Can't open file ", m_FullPath);
			return false;		
		}
		return true;
	}	

	void RouterInfo::ReadFromFile ()
	{
		if (LoadFile ())
			ReadFromBuffer (false); 
		else
			m_IsUnreachable = true;	
	}	

	void RouterInfo::ReadFromBuffer (bool verifySignature)
	{
		m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer, m_BufferLen);
		size_t identityLen = m_RouterIdentity->GetFullLen ();
		if (identityLen >= m_BufferLen)
		{
			LogPrint (eLogError, "RouterInfo: identity length ", identityLen, " exceeds buffer size ", m_BufferLen);
			m_IsUnreachable = true;
			return;
		}
		if (verifySignature)
		{	
			// verify signature
			int l = m_BufferLen - m_RouterIdentity->GetSignatureLen ();	
			if (l < 0 || !m_RouterIdentity->Verify ((uint8_t *)m_Buffer, l, (uint8_t *)m_Buffer + l))
			{	
				LogPrint (eLogError, "RouterInfo: signature verification failed");
				m_IsUnreachable = true;
				return;
			}
			m_RouterIdentity->DropVerifier ();
		}	
		// parse RI
		std::stringstream str;
		str.write ((const char *)m_Buffer + identityLen, m_BufferLen - identityLen);
		ReadFromStream (str);
		if (!str)
		{
			LogPrint (eLogError, "RouterInfo: malformed message");
			m_IsUnreachable = true;
		}
		
{'fraction_non_alphanumeric': 0.12960199004975123, 'fraction_numerical': 0.005472636815920398, 'mean_word_length': 3.988213399503722, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7169473', 'n_tokens_mistral': 3265, 'n_tokens_neox': 2902, 'n_words': 652}