Пример #1
0
bool cMapSerializer::Load(void)
{
	AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path);
	if (Data.empty())
	{
		return false;
	}

	AString Uncompressed;
	int res = UncompressStringGZIP(Data.data(), Data.size(), Uncompressed);

	if (res != Z_OK)
	{
		return false;
	}

	// Parse the NBT data:
	cParsedNBT NBT(Uncompressed.data(), Uncompressed.size());
	if (!NBT.IsValid())
	{
		// NBT Parsing failed
		return false;
	}

	return LoadMapFromNBT(NBT);
}
Пример #2
0
AString cLuaTCPLink::StartTLSServer(
	const AString & a_OwnCertData,
	const AString & a_OwnPrivKeyData,
	const AString & a_OwnPrivKeyPassword,
	const AString & a_StartTLSData
)
{
	auto link = m_Link;
	if (link != nullptr)
	{
	// Create the peer cert:
	auto OwnCert = std::make_shared<cX509Cert>();
	int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size());
	if (res != 0)
	{
		return Printf("Cannot parse server certificate: -0x%x", res);
	}
	auto OwnPrivKey = std::make_shared<cCryptoKey>();
	res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword);
	if (res != 0)
	{
		return Printf("Cannot parse server private key: -0x%x", res);
	}

		return link->StartTLSServer(OwnCert, OwnPrivKey, a_StartTLSData);
	}
	return "";
}
Пример #3
0
AString cLuaTCPLink::StartTLSClient(
	const AString & a_OwnCertData,
	const AString & a_OwnPrivKeyData,
	const AString & a_OwnPrivKeyPassword
)
{
	auto link = m_Link;
	if (link != nullptr)
	{
		cX509CertPtr ownCert;
		if (!a_OwnCertData.empty())
		{
			ownCert = std::make_shared<cX509Cert>();
			auto res = ownCert->Parse(a_OwnCertData.data(), a_OwnCertData.size());
			if (res != 0)
			{
				return Printf("Cannot parse client certificate: -0x%x", res);
			}
		}
		cCryptoKeyPtr ownPrivKey;
		if (!a_OwnPrivKeyData.empty())
		{
			ownPrivKey = std::make_shared<cCryptoKey>();
			auto res = ownPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword);
			if (res != 0)
			{
				return Printf("Cannot parse client private key: -0x%x", res);
			}
		}
		return link->StartTLSClient(ownCert, ownPrivKey);
	}
	return "";
}
Пример #4
0
QString MainWindow::getWorldName(const AString & a_Path)
{
	AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat");
	if (levelData.empty())
	{
		// No such file / no data
		return QString();
	}

	AString uncompressed;
	if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK)
	{
		return QString();
	}
	cParsedNBT nbt(uncompressed.data(), uncompressed.size());
	if (!nbt.IsValid())
	{
		return QString();
	}
	AString name = nbt.GetName(1);
	int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName");
	if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String))
	{
		return QString();
	}
	return QString::fromStdString(nbt.GetString(levelNameTag));
}
Пример #5
0
bool cWSSCompact::cPAKFile::SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World)
{
	// Serialize the chunk:
	cJsonChunkSerializer Serializer;
	if (!a_World->GetChunkData(a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, Serializer))
	{
		// Chunk not valid
		LOG("cWSSCompact: Trying to save chunk [%d, %d, %d] that has no data, ignoring request.", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
		return false;
	}

	AString Data;
	Data.assign((const char *)Serializer.GetBlockData(), cChunkDef::BlockDataSize);
	if (Serializer.HasJsonData())
	{
		AString JsonData;
		Json::StyledWriter writer;
		JsonData = writer.write(Serializer.GetRoot());
		Data.append(JsonData);
	}
	
	// Compress the data:
	AString CompressedData;
	int errorcode = CompressString(Data.data(), Data.size(), CompressedData, m_CompressionFactor);
	if ( errorcode != Z_OK )
	{
		LOGERROR("Error %i compressing data for chunk [%d, %d, %d]", errorcode, a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
		return false;
	}
	
	// Erase any existing data for the chunk:
	EraseChunkData(a_Chunk);
	
	// Save the header:
	sChunkHeader * Header = new sChunkHeader;
	if (Header == NULL)
	{
		LOGWARNING("Cannot create a new chunk header to save chunk [%d, %d, %d]", a_Chunk.m_ChunkX, a_Chunk.m_ChunkY, a_Chunk.m_ChunkZ);
		return false;
	}
	Header->m_CompressedSize = (int)CompressedData.size();
	Header->m_ChunkX = a_Chunk.m_ChunkX;
	Header->m_ChunkZ = a_Chunk.m_ChunkZ;
	Header->m_UncompressedSize = (int)Data.size();
	m_ChunkHeaders.push_back(Header);
	
	m_DataContents.append(CompressedData.data(), CompressedData.size());
	
	m_NumDirty++;
	return true;
}
Пример #6
0
bool cHTTPServer::Initialize(const AString & a_PortsIPv4, const AString & a_PortsIPv6)
{
	// Read the HTTPS cert + key:
	AString CertFile = cFile::ReadWholeFile("webadmin/httpscert.crt");
	AString KeyFile  = cFile::ReadWholeFile("webadmin/httpskey.pem");
	if (!CertFile.empty() && !KeyFile.empty())
	{
		m_Cert.reset(new cX509Cert);
		int res = m_Cert->Parse(CertFile.data(), CertFile.size());
		if (res == 0)
		{
			m_CertPrivKey.reset(new cCryptoKey);
			int res2 = m_CertPrivKey->ParsePrivate(KeyFile.data(), KeyFile.size(), "");
			if (res2 != 0)
			{
				// Reading the private key failed, reset the cert:
				LOGWARNING("WebServer: Cannot read HTTPS certificate private key: -0x%x", -res2);
				m_Cert.reset();
			}
		}
		else
		{
			LOGWARNING("WebServer: Cannot read HTTPS certificate: -0x%x", -res);
		}
	}

	// Notify the admin about the HTTPS / HTTP status
	if (m_Cert.get() == nullptr)
	{
		LOGWARNING("WebServer: The server is running in unsecured HTTP mode.");
		LOGINFO("Put a valid HTTPS certificate in file 'webadmin/httpscert.crt' and its corresponding private key to 'webadmin/httpskey.pem' (without any password) to enable HTTPS support");
	}
	else
	{
		LOGINFO("WebServer: The server is running in secure HTTPS mode.");
	}
	
	// Open up requested ports:
	bool HasAnyPort;
	m_ListenThreadIPv4.SetReuseAddr(true);
	m_ListenThreadIPv6.SetReuseAddr(true);
	HasAnyPort = m_ListenThreadIPv4.Initialize(a_PortsIPv4);
	HasAnyPort = m_ListenThreadIPv6.Initialize(a_PortsIPv6) || HasAnyPort;
	if (!HasAnyPort)
	{
		return false;
	}
	
	return true;
}
Пример #7
0
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce)
{
	// Decrypt EncNonce using privkey
	cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey();

	Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)];
	int res = rsaDecryptor.Decrypt((const Byte *)a_EncNonce.data(), a_EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce));
	if (res != 4)
	{
		LOGD("Bad nonce length");
		m_Client->Kick("Hacked client");
		return;
	}
	if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this)
	{
		LOGD("Bad nonce value");
		m_Client->Kick("Hacked client");
		return;
	}
	
	// Decrypt the symmetric encryption key using privkey:
	Byte DecryptedKey[MAX_ENC_LEN];
	res = rsaDecryptor.Decrypt((const Byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey, sizeof(DecryptedKey));
	if (res != 16)
	{
		LOGD("Bad key length");
		m_Client->Kick("Hacked client");
		return;
	}
	
	{
		// Send encryption key response:
		cCSLock Lock(m_CSPacket);
		WriteByte(0xfc);
		WriteShort(0);
		WriteShort(0);
		Flush();
	}
	
	#ifdef _DEBUG
	AString DecryptedKeyHex;
	CreateHexDump(DecryptedKeyHex, DecryptedKey, res, 16);
	LOGD("Received encryption key, %d bytes:\n%s", res, DecryptedKeyHex.c_str());
	#endif
	
	StartEncryption(DecryptedKey);
	return;
}
Пример #8
0
AString cLuaTCPLink::StartTLSClient(
	const AString & a_OwnCertData,
	const AString & a_OwnPrivKeyData,
	const AString & a_OwnPrivKeyPassword
)
{
	// Check preconditions:
	if (m_SslContext != nullptr)
	{
		return "TLS is already active on this link";
	}
	if (
		(a_OwnCertData.empty()  && !a_OwnPrivKeyData.empty()) ||
		(!a_OwnCertData.empty() && a_OwnPrivKeyData.empty())
	)
	{
		return "Either provide both the certificate and private key, or neither";
	}

	// Create the SSL context:
	m_SslContext.reset(new cLinkSslContext(*this));
	m_SslContext->Initialize(true);

	// Create the peer cert, if required:
	if (!a_OwnCertData.empty() && !a_OwnPrivKeyData.empty())
	{
		auto OwnCert = std::make_shared<cX509Cert>();
		int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size());
		if (res != 0)
		{
			m_SslContext.reset();
			return Printf("Cannot parse peer certificate: -0x%x", res);
		}
		auto OwnPrivKey = std::make_shared<cCryptoKey>();
		res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword);
		if (res != 0)
		{
			m_SslContext.reset();
			return Printf("Cannot parse peer private key: -0x%x", res);
		}
		m_SslContext->SetOwnCert(OwnCert, OwnPrivKey);
	}
	m_SslContext->SetSelf(cLinkSslContextWPtr(m_SslContext));

	// Start the handshake:
	m_SslContext->Handshake();
	return "";
}
Пример #9
0
void cLuaState::Push(const AString & a_String)
{
	ASSERT(IsValid());

	lua_pushlstring(m_LuaState, a_String.data(), a_String.size());
	m_NumCurrentFunctionArgs += 1;
}
Пример #10
0
void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size)
{
	if (m_Protocol == nullptr)
	{
		if (!m_Buffer.Write(a_Data, a_Size))
		{
			m_Client->Kick("Unsupported protocol version");
			return;
		}

		if (!TryRecognizeProtocol())
		{
			return;
		}

		// The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing:
		AString Dump;
		m_Buffer.ResetRead();
		m_Buffer.ReadAll(Dump);
		m_Protocol->DataReceived(Dump.data(), Dump.size());
	}
	else
	{
		m_Protocol->DataReceived(a_Data, a_Size);
	}
}
Пример #11
0
bool cMapSerializer::Save(void)
{
	cFastNBTWriter Writer;

	SaveMapToNBT(Writer);

	Writer.Finish();
	
	#ifdef _DEBUG
	cParsedNBT TestParse(Writer.GetResult().data(), Writer.GetResult().size());
	ASSERT(TestParse.IsValid());
	#endif  // _DEBUG

	cFile File;
	if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmWrite))
	{
		return false;
	}

	AString Compressed;
	int res = CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);

	if (res != Z_OK)
	{
		return false;
	}

	File.Write(Compressed.data(), Compressed.size());
	File.Close();

	return true;
}
Пример #12
0
int cFile::ReadRestOfFile(AString & a_Contents)
{
	ASSERT(IsOpen());

	if (!IsOpen())
	{
		return -1;
	}

	long TotalSize = GetSize();
	if (TotalSize < 0)
	{
		return -1;
	}

	long Position = Tell();
	if (Position < 0)
	{
		return -1;
	}

	auto DataSize = static_cast<size_t>(TotalSize - Position);

	// HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly
	a_Contents.assign(DataSize, '\0');
	return Read(reinterpret_cast<void *>(const_cast<char *>(a_Contents.data())), DataSize);
}
Пример #13
0
bool cWSSAnvil::LoadChunkFromData(const cChunkCoords & a_Chunk, const AString & a_Data)
{
    // Decompress the data:
    char Uncompressed[CHUNK_INFLATE_MAX];
    z_stream strm;
    strm.zalloc = (alloc_func)NULL;
    strm.zfree = (free_func)NULL;
    strm.opaque = NULL;
    inflateInit(&strm);
    strm.next_out  = (Bytef *)Uncompressed;
    strm.avail_out = sizeof(Uncompressed);
    strm.next_in   = (Bytef *)a_Data.data();
    strm.avail_in  = a_Data.size();
    int res = inflate(&strm, Z_FINISH);
    inflateEnd(&strm);
    if (res != Z_STREAM_END)
    {
        return false;
    }

    // Parse the NBT data:
    cParsedNBT NBT(Uncompressed, strm.total_out);
    if (!NBT.IsValid())
    {
        // NBT Parsing failed
        return false;
    }

    // Load the data from NBT:
    return LoadChunkFromNBT(a_Chunk, NBT);
}
Пример #14
0
bool cBlockArea::LoadFromSchematicFile(const AString & a_FileName)
{
	// Un-GZip the contents:
	AString Contents;
	cGZipFile File;
	if (!File.Open(a_FileName, cGZipFile::fmRead))
	{
		LOG("Cannot open the schematic file \"%s\".", a_FileName.c_str());
		return false;
	}
	int NumBytesRead = File.ReadRestOfFile(Contents);
	if (NumBytesRead < 0)
	{
		LOG("Cannot read GZipped data in the schematic file \"%s\", error %d", a_FileName.c_str(), NumBytesRead);
		return false;
	}
	File.Close();
	
	// Parse the NBT:
	cParsedNBT NBT(Contents.data(), Contents.size());
	if (!NBT.IsValid())
	{
		LOG("Cannot parse the NBT in the schematic file \"%s\".", a_FileName.c_str());
		return false;
	}
	
	return LoadFromSchematicNBT(NBT);
}
Пример #15
0
bool cIDCountSerializer::Load(void)
{
	AString Data = cFile::ReadWholeFile(FILE_IO_PREFIX + m_Path);
	if (Data.empty())
	{
		return false;
	}

	// NOTE: idcounts.dat is not compressed (raw format)

	// Parse the NBT data:
	cParsedNBT NBT(Data.data(), Data.size());
	if (!NBT.IsValid())
	{
		// NBT Parsing failed
		return false;
	}

	int CurrLine = NBT.FindChildByName(0, "map");
	if (CurrLine >= 0)
	{
		m_MapCount = (int)NBT.GetShort(CurrLine) + 1;
	}
	else
	{
		m_MapCount = 0;
	}

	return true;
}
Пример #16
0
bool cSocketThreads::cSocketThread::SendDataThroughSocket(cSocket & a_Socket, AString & a_Data)
{
	// Send data in smaller chunks, so that the OS send buffers aren't overflown easily
	while (!a_Data.empty())
	{
		size_t NumToSend = std::min(a_Data.size(), (size_t)1024);
		int Sent = a_Socket.Send(a_Data.data(), NumToSend);
		if (Sent < 0)
		{
			int Err = cSocket::GetLastError();
			if (Err == cSocket::ErrWouldBlock)
			{
				// The OS send buffer is full, leave the outgoing data for the next time
				return true;
			}
			// An error has occured
			return false;
		}
		if (Sent == 0)
		{
			a_Socket.CloseSocket();
			return true;
		}
		a_Data.erase(0, Sent);
	}
	return true;
}
Пример #17
0
AString cTCPLinkImpl::StartTLSServer(
	cX509CertPtr a_OwnCert,
	cCryptoKeyPtr a_OwnPrivKey,
	const AString & a_StartTLSData
)
{
	// Check preconditions:
	if (m_TlsContext != nullptr)
	{
		return "TLS is already active on this link";
	}
	if ((a_OwnCert == nullptr)  || (a_OwnPrivKey == nullptr))
	{
		return "Provide the server certificate and private key";
	}

	// Create the TLS context:
	m_TlsContext.reset(new cLinkTlsContext(*this));
	m_TlsContext->Initialize(false);
	m_TlsContext->SetOwnCert(a_OwnCert, a_OwnPrivKey);
	m_TlsContext->SetSelf(cLinkTlsContextWPtr(m_TlsContext));

	// Push the initial data:
	m_TlsContext->StoreReceivedData(a_StartTLSData.data(), a_StartTLSData.size());

	// Start the handshake:
	m_TlsContext->Handshake();
	return "";
}
Пример #18
0
void cHTTPConnection::SendStatusAndReason(int a_StatusCode, const AString & a_Response)
{
	SendData(Printf("HTTP/1.1 %d %s\r\n", a_StatusCode, a_Response.c_str()));
	SendData(Printf("Content-Length: %u\r\n\r\n", static_cast<unsigned>(a_Response.size())));
	SendData(a_Response.data(), a_Response.size());
	m_State = wcsRecvHeaders;
}
Пример #19
0
bool cPrefabPiecePool::LoadFromString(const AString & a_Contents, const AString & a_FileName, bool a_LogWarnings)
{
	// If the contents start with GZip signature, ungzip and retry:
	if (a_Contents.substr(0, 3) == "\x1f\x8b\x08")
	{
		AString Uncompressed;
		auto res = UncompressStringGZIP(a_Contents.data(), a_Contents.size(), Uncompressed);
		if (res == Z_OK)
		{
			return LoadFromString(Uncompressed, a_FileName, a_LogWarnings);
		}
		else
		{
			CONDWARNING(a_LogWarnings, "Failed to decompress Gzip data in file %s: %d", a_FileName.c_str(), res);
			return false;
		}
	}

	// Search the first 8 KiB of the file for the format auto-detection string:
	auto Header = a_Contents.substr(0, 8192);
	if (Header.find("CubesetFormatVersion =") != AString::npos)
	{
		return LoadFromCubeset(a_Contents, a_FileName, a_LogWarnings);
	}
	CONDWARNING(a_LogWarnings, "Cannot load prefabs from file %s, unknown file format", a_FileName.c_str());
	return false;
}
Пример #20
0
cFastNBTWriter::cFastNBTWriter(const AString & a_RootTagName) :
	m_CurrentStack(0)
{
	m_Stack[0].m_Type = TAG_Compound;
	m_Result.reserve(100 * 1024);
	m_Result.push_back(TAG_Compound);
	WriteString(a_RootTagName.data(), a_RootTagName.size());
}
Пример #21
0
AString cLuaTCPLink::StartTLSServer(
	const AString & a_OwnCertData,
	const AString & a_OwnPrivKeyData,
	const AString & a_OwnPrivKeyPassword,
	const AString & a_StartTLSData
)
{
	// Check preconditions:
	if (m_SslContext != nullptr)
	{
		return "TLS is already active on this link";
	}
	if (a_OwnCertData.empty()  || a_OwnPrivKeyData.empty())
	{
		return "Provide the server certificate and private key";
	}

	// Create the SSL context:
	m_SslContext.reset(new cLinkSslContext(*this));
	m_SslContext->Initialize(false);

	// Create the peer cert:
	auto OwnCert = std::make_shared<cX509Cert>();
	int res = OwnCert->Parse(a_OwnCertData.data(), a_OwnCertData.size());
	if (res != 0)
	{
		m_SslContext.reset();
		return Printf("Cannot parse server certificate: -0x%x", res);
	}
	auto OwnPrivKey = std::make_shared<cCryptoKey>();
	res = OwnPrivKey->ParsePrivate(a_OwnPrivKeyData.data(), a_OwnPrivKeyData.size(), a_OwnPrivKeyPassword);
	if (res != 0)
	{
		m_SslContext.reset();
		return Printf("Cannot parse server private key: -0x%x", res);
	}
	m_SslContext->SetOwnCert(OwnCert, OwnPrivKey);
	m_SslContext->SetSelf(cLinkSslContextWPtr(m_SslContext));

	// Push the initial data:
	m_SslContext->StoreReceivedData(a_StartTLSData.data(), a_StartTLSData.size());

	// Start the handshake:
	m_SslContext->Handshake();
	return "";
}
Пример #22
0
bool cWSSAnvil::cMCAFile::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Data)
{
    if (!OpenFile(false))
    {
        LOGWARNING("Cannot save chunk [%d, %d], opening file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
        return false;
    }

    int LocalX = a_Chunk.m_ChunkX % 32;
    if (LocalX < 0)
    {
        LocalX = 32 + LocalX;
    }
    int LocalZ = a_Chunk.m_ChunkZ % 32;
    if (LocalZ < 0)
    {
        LocalZ = 32 + LocalZ;
    }

    unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data);

    // Store the chunk data:
    m_File.Seek(ChunkSector * 4096);
    unsigned ChunkSize = htonl(a_Data.size() + 1);
    if (m_File.Write(&ChunkSize, 4) != 4)
    {
        LOGWARNING("Cannot save chunk [%d, %d], writing(1) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
        return false;
    }
    char CompressionType = 2;
    if (m_File.Write(&CompressionType, 1) != 1)
    {
        LOGWARNING("Cannot save chunk [%d, %d], writing(2) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
        return false;
    }
    if (m_File.Write(a_Data.data(), a_Data.size()) != (int)(a_Data.size()))
    {
        LOGWARNING("Cannot save chunk [%d, %d], writing(3) data to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
        return false;
    }

    // Store the header:
    ChunkSize = (a_Data.size() + MCA_CHUNK_HEADER_LENGTH + 4095) / 4096;  // Round data size *up* to nearest 4KB sector, make it a sector number
    ASSERT(ChunkSize < 256);
    m_Header[LocalX + 32 * LocalZ] = htonl((ChunkSector << 8) | ChunkSize);
    if (m_File.Seek(0) < 0)
    {
        LOGWARNING("Cannot save chunk [%d, %d], seeking in file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
        return false;
    }
    if (m_File.Write(m_Header, sizeof(m_Header)) != sizeof(m_Header))
    {
        LOGWARNING("Cannot save chunk [%d, %d], writing header to file \"%s\" failed", a_Chunk.m_ChunkX, a_Chunk.m_ChunkZ, GetFileName().c_str());
        return false;
    }

    return true;
}
Пример #23
0
void cProtocol125::SendEntityMetadata(const cEntity & a_Entity)
{
	cCSLock Lock(m_CSPacket);
	WriteByte(PACKET_METADATA);
	WriteInt (a_Entity.GetUniqueID());
	AString MetaData = GetEntityMetaData(a_Entity);
	SendData(MetaData.data(), MetaData.size());
	Flush();
}
Пример #24
0
void cProtocol125::SendPluginMessage(const AString & a_Channel, const AString & a_Message)
{
	cCSLock Lock(m_CSPacket);
	WriteByte(PACKET_PLUGIN_MESSAGE);
	WriteString(a_Channel);
	WriteShort((short)a_Message.size());
	SendData(a_Message.data(), a_Message.size());
	Flush();
}
Пример #25
0
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce)
{
	// Decrypt EncNonce using privkey
	RSAES<PKCS1v15>::Decryptor rsaDecryptor(cRoot::Get()->GetServer()->GetPrivateKey());
	time_t CurTime = time(NULL);
	CryptoPP::RandomPool rng;
	rng.Put((const byte *)&CurTime, sizeof(CurTime));
	byte DecryptedNonce[MAX_ENC_LEN];
	DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce);
	if (!res.isValidCoding || (res.messageLength != 4))
	{
		LOGD("Bad nonce length");
		m_Client->Kick("Hacked client");
		return;
	}
	if (ntohl(*((int *)DecryptedNonce)) != (unsigned)(uintptr_t)this)
	{
		LOGD("Bad nonce value");
		m_Client->Kick("Hacked client");
		return;
	}
	
	// Decrypt the symmetric encryption key using privkey:
	byte DecryptedKey[MAX_ENC_LEN];
	res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey);
	if (!res.isValidCoding || (res.messageLength != 16))
	{
		LOGD("Bad key length");
		m_Client->Kick("Hacked client");
		return;
	}
	
	{
		// Send encryption key response:
		cCSLock Lock(m_CSPacket);
		WriteByte((char)0xfc);
		WriteShort(0);
		WriteShort(0);
		Flush();
	}
	
	StartEncryption(DecryptedKey);
	return;
}
Пример #26
0
cPublicKey::cPublicKey(const AString & a_PublicKeyDER)
{
	pk_init(&m_Pk);
	if (pk_parse_public_key(&m_Pk, (const Byte *)a_PublicKeyDER.data(), a_PublicKeyDER.size()) != 0)
	{
		ASSERT(!"Cannot parse PubKey");
		return;
	}
	InitRnd();
}
Пример #27
0
bool cSchematicFileSerializer::LoadFromSchematicString(cBlockArea & a_BlockArea, const AString & a_SchematicData)
{
	// Uncompress the data:
	AString UngzippedData;
	if (UncompressStringGZIP(a_SchematicData.data(), a_SchematicData.size(), UngzippedData) != Z_OK)
	{
		LOG("%s: Cannot unGZip the schematic data.", __FUNCTION__);
		return false;
	}

	// Parse the NBT:
	cParsedNBT NBT(UngzippedData.data(), UngzippedData.size());
	if (!NBT.IsValid())
	{
		LOG("%s: Cannot parse the NBT in the schematic data.", __FUNCTION__);
		return false;
	}

	return LoadFromSchematicNBT(a_BlockArea, NBT);
}
Пример #28
0
static void TestWrite(void)
{
	cByteBuffer buf(50);
	buf.WriteVarInt32(5);
	buf.WriteVarInt32(300);
	buf.WriteVarInt32(0);
	AString All;
	buf.ReadAll(All);
	assert_test(All.size() == 4);
	assert_test(memcmp(All.data(), "\x05\xac\x02\x00", All.size()) == 0);
}
Пример #29
0
bool cByteBuffer::WriteBEUTF16String16(const AString & a_Value)
{
	CHECK_THREAD;
	CheckValid();
	PUTBYTES(2);
	AString UTF16BE;
	UTF8ToRawBEUTF16(a_Value.data(), a_Value.size(), UTF16BE);
	WriteBEShort((short)(UTF16BE.size() / 2));
	PUTBYTES(UTF16BE.size());
	WriteBuf(UTF16BE.data(), UTF16BE.size());
	return true;
}
Пример #30
0
void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size)
{
	if (m_Protocol == nullptr)
	{
		if (!m_Buffer.Write(a_Data, a_Size))
		{
			m_Client->Kick("Unsupported protocol version");
			return;
		}

		if (m_InPingForUnrecognizedVersion)
		{
			// We already know the verison; handle it here.
			UInt32 PacketLen;
			UInt32 PacketID;
			if (!m_Buffer.ReadVarInt32(PacketLen))
			{
				return;
			}
			if (!m_Buffer.ReadVarInt32(PacketID))
			{
				return;
			}
			ASSERT(PacketID == 0x01);  // Ping packet
			ASSERT(PacketLen == 9);  // Payload of the packet ID and a UInt64

			Int64 Data;
			if (!m_Buffer.ReadBEInt64(Data))
			{
				return;
			}

			cPacketizer Pkt(*this, 0x01);  // Pong packet
			Pkt.WriteBEInt64(Data);
			return;
		}

		if (!TryRecognizeProtocol())
		{
			return;
		}

		// The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing:
		AString Dump;
		m_Buffer.ResetRead();
		m_Buffer.ReadAll(Dump);
		m_Protocol->DataReceived(Dump.data(), Dump.size());
	}
	else
	{
		m_Protocol->DataReceived(a_Data, a_Size);
	}
}