mirror of https://github.com/infosecn1nja/C3.git
202 lines
9.3 KiB
C++
202 lines
9.3 KiB
C++
#include "StdAfx.h"
|
|
#include "DeviceBridge.h"
|
|
#include "Relay.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
FSecure::C3::Core::DeviceBridge::DeviceBridge(std::shared_ptr<Relay>&& relay, DeviceId did, HashT typeNameHash, std::shared_ptr<Device>&& device, bool isNegotiationChannel, bool isSlave, ByteVector args /*= ByteVector()*/)
|
|
: m_IsNegotiationChannel(isNegotiationChannel)
|
|
, m_IsSlave(isSlave)
|
|
, m_Did{ did }
|
|
, m_TypeNameHash(typeNameHash)
|
|
, m_Relay{ relay }
|
|
, m_Device{ std::move(device) }
|
|
{
|
|
if (!isNegotiationChannel)
|
|
return;
|
|
|
|
auto readView = ByteView{ args };
|
|
std::tie(m_InputId, m_OutpuId) = readView.Read<ByteVector, ByteVector>();
|
|
m_NonNegotiatiedArguments = readView;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::OnAttach()
|
|
{
|
|
GetDevice()->OnAttach(shared_from_this());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::Detach()
|
|
{
|
|
m_IsAlive = false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::Close()
|
|
{
|
|
auto relay = GetRelay();
|
|
relay->DetachDevice(GetDid());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::OnReceive()
|
|
{
|
|
GetDevice()->OnReceive();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::PassNetworkPacket(ByteView packet)
|
|
{
|
|
if (m_IsNegotiationChannel && !m_IsSlave) // negotiation channel does not support chunking. Just pass packet and leave.
|
|
return GetRelay()->OnPacketReceived(packet, shared_from_this());
|
|
|
|
m_QoS.PushReceivedChunk(packet);
|
|
auto nextPacket = m_QoS.GetNextPacket();
|
|
if (!nextPacket.empty())
|
|
GetRelay()->OnPacketReceived(nextPacket, shared_from_this());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::OnPassNetworkPacket(ByteView packet)
|
|
{
|
|
auto lock = std::lock_guard<std::mutex>{ m_ProtectWriteInConcurrentThreads };
|
|
|
|
if (m_IsNegotiationChannel) // negotiation channel does not support chunking. Just pass packet and leave.
|
|
{
|
|
auto sent = GetDevice()->OnSendToChannelInternal(packet);
|
|
if (sent != packet.size())
|
|
throw std::runtime_error{OBF("Negotiation channel does not support chunking. Packet size: ") + std::to_string(packet.size()) + OBF(" Channel sent: ") + std::to_string(sent)};
|
|
|
|
return;
|
|
}
|
|
|
|
auto packetSplitter = m_QoS.GetPacketSplitter(packet);
|
|
while (packetSplitter.HasMore())
|
|
packetSplitter.Update(GetDevice()->OnSendToChannelInternal(packetSplitter.NextChunk()));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::PostCommandToConnector(ByteView packet)
|
|
{
|
|
GetRelay()->PostCommandToConnector(packet, shared_from_this());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::OnCommandFromConnector(ByteView command)
|
|
{
|
|
auto lock = std::lock_guard<std::mutex>{ m_ProtectWriteInConcurrentThreads };
|
|
GetDevice()->OnCommandFromConnector(command);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
FSecure::ByteVector FSecure::C3::Core::DeviceBridge::RunCommand(ByteView command)
|
|
{
|
|
return GetDevice()->OnRunCommand(command);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
FSecure::ByteVector FSecure::C3::Core::DeviceBridge::WhoAreYou()
|
|
{
|
|
return GetDevice()->OnWhoAmI();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::Log(LogMessage const& message)
|
|
{
|
|
GetRelay()->Log(message, GetDid());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
FSecure::C3::DeviceId FSecure::C3::Core::DeviceBridge::GetDid() const
|
|
{
|
|
return m_Did;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::StartUpdatingInSeparateThread()
|
|
{
|
|
std::thread{
|
|
[this, self = shared_from_this()]()
|
|
{
|
|
WinTools::StructuredExceptionHandling::SehWrapper([&]()
|
|
{
|
|
while (m_IsAlive)
|
|
try
|
|
{
|
|
std::this_thread::sleep_for(GetDevice()->GetUpdateDelay());
|
|
OnReceive();
|
|
}
|
|
catch (std::exception const& exception)
|
|
{
|
|
Log({ OBF_SEC("std::exception while updating: ") + exception.what(), LogMessage::Severity::Error });
|
|
}
|
|
catch (...)
|
|
{
|
|
Log({ OBF_SEC("Unknown exception while updating."), LogMessage::Severity::Error });
|
|
}
|
|
}, [this]()
|
|
{
|
|
# if defined _DEBUG
|
|
Log({ "Signal captured, ending thread execution.", LogMessage::Severity::Error });
|
|
# endif
|
|
});
|
|
}}.detach();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::SetUpdateDelay(std::chrono::milliseconds minUpdateDelayInMs, std::chrono::milliseconds maxUpdateDelayInMs)
|
|
{
|
|
GetDevice()->SetUpdateDelay(minUpdateDelayInMs, maxUpdateDelayInMs);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::SetUpdateDelay(std::chrono::milliseconds frequencyInMs)
|
|
{
|
|
GetDevice()->SetUpdateDelay(frequencyInMs);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
std::shared_ptr<FSecure::C3::Device> FSecure::C3::Core::DeviceBridge::GetDevice() const
|
|
{
|
|
return m_Device;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
std::shared_ptr<FSecure::C3::Core::Relay> FSecure::C3::Core::DeviceBridge::GetRelay() const
|
|
{
|
|
return m_Relay;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
FSecure::HashT FSecure::C3::Core::DeviceBridge::GetTypeNameHash() const
|
|
{
|
|
return m_TypeNameHash;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool FSecure::C3::Core::DeviceBridge::IsChannel() const
|
|
{
|
|
auto device = GetDevice();
|
|
|
|
return device ? device->IsChannel() : false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
bool FSecure::C3::Core::DeviceBridge::IsNegotiationChannel() const
|
|
{
|
|
return m_IsNegotiationChannel && IsChannel();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
void FSecure::C3::Core::DeviceBridge::SetErrorStatus(std::string_view errorMessage)
|
|
{
|
|
m_Error = errorMessage;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
std::string FSecure::C3::Core::DeviceBridge::GetErrorStatus()
|
|
{
|
|
return m_Error;
|
|
}
|