mirror of https://github.com/infosecn1nja/C3.git
Allow retriving N bytes of data without coping using variadic ByteView::Read
parent
17d2604c26
commit
ffe0d66fcd
|
@ -385,7 +385,7 @@ bool MWR::C3::Interfaces::Connectors::TeamServer::Connection::SecondThreadStarte
|
|||
|
||||
MWR::ByteVector MWR::C3::Interfaces::Connectors::TeamServer::PeripheralCreationCommand(ByteView connectionId, ByteView data, bool isX64)
|
||||
{
|
||||
auto [pipeName, maxConnectionTrials, delayBetweenConnectionTrials/*, payload*/] = data.Read<std::string, uint16_t, uint16_t/*, ByteVector*/>();
|
||||
auto [pipeName, maxConnectionTrials, delayBetweenConnectionTrials/*, payload*/] = data.Read<std::string, uint16_t, uint16_t/*, ByteView*/>();
|
||||
|
||||
// custom payload is removed from release.
|
||||
//if (!payload.empty())
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
MWR::C3::Interfaces::Peripherals::Beacon::Beacon(ByteView arguments)
|
||||
{
|
||||
auto [pipeName, maxConnectionTrials, delayBetweenConnectionTrials, payload] = arguments.Read<std::string, uint16_t, uint16_t, ByteVector>();
|
||||
auto [pipeName, maxConnectionTrials, delayBetweenConnectionTrials, payload] = arguments.Read<std::string, uint16_t, uint16_t, ByteView>();
|
||||
|
||||
// Arguments validation.
|
||||
if (payload.empty())
|
||||
|
|
|
@ -40,6 +40,10 @@ namespace MWR
|
|||
/// @returns std::vector<std::string> tokenized string.
|
||||
std::vector<std::string> SplitAndCopy(std::string_view stringToBeSplitted, std::string_view delimiter);
|
||||
|
||||
/// Idiom for detecting ByteView::Get.
|
||||
template <typename X>
|
||||
constexpr bool IsGetter = false;
|
||||
|
||||
/// Non owning container.
|
||||
class ByteView : std::basic_string_view<ByteVector::value_type>
|
||||
{
|
||||
|
@ -136,6 +140,7 @@ namespace MWR
|
|||
using Super::npos;
|
||||
using Super::value_type;
|
||||
|
||||
|
||||
/// @returns ByteVector. Owning container with the read bytes.
|
||||
/// @param byteCount. How many bytes should be read.
|
||||
/// @remarks Read is not compatible with Read<ByteVector>.
|
||||
|
@ -187,7 +192,7 @@ namespace MWR
|
|||
/// Read bytes and remove them from ByteView.
|
||||
/// @returns ByteArray. Owning container with the read bytes.
|
||||
/// @throws std::out_of_range. If ByteView is too short to hold size of object to return.
|
||||
template<typename T, typename std::enable_if_t<IsByteArray<T>, int> = 0>
|
||||
template<typename T>
|
||||
std::enable_if_t<IsByteArray<T>, T> Read()
|
||||
{
|
||||
if (std::tuple_size<typename T>::value > size())
|
||||
|
@ -223,6 +228,35 @@ namespace MWR
|
|||
return TupleGenerator<T>::Generate(*this);
|
||||
}
|
||||
|
||||
/// Class allowing reading N bytes without coping data like in ByeView::Read<ByteArray<N>> or ByteView::Reed(size_t).
|
||||
template <size_t N>
|
||||
class Get
|
||||
{
|
||||
public:
|
||||
/// Define size marker.
|
||||
static constexpr size_t size = N;
|
||||
static constexpr size_t Size = size;
|
||||
|
||||
private:
|
||||
/// Private constructor.
|
||||
/// This class should never be instantiated.
|
||||
Get() = default;
|
||||
};
|
||||
|
||||
/// Read bytes and remove them from ByteView.
|
||||
/// @returns ByteView. Non owning container with the read bytes.
|
||||
/// @throws std::out_of_range. If ByteView is too short to hold size of object to return.
|
||||
template<typename T>
|
||||
std::enable_if_t<IsGetter<T>, ByteView> Read()
|
||||
{
|
||||
if (T::Size > size())
|
||||
throw std::out_of_range{ OBF(": Cannot read data from ByteView") };
|
||||
|
||||
auto retVal = SubString(0, T::Size);
|
||||
remove_prefix(T::Size);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// Read tuple and remove bytes from ByteView.
|
||||
/// @tparam T. Parameter pack of types to be stored in tuple. Must consist more then one type. Each of types must be parsable by Reed template for one type.
|
||||
/// @returns std::tuple. Tuple will store types provided in parameter pack.
|
||||
|
@ -273,7 +307,7 @@ namespace MWR
|
|||
{
|
||||
auto current = std::make_tuple(self.Read<T>());
|
||||
auto rest = VariadicTupleGenerator<Rest...>::Generate(self);
|
||||
return std::tuple_cat(current, rest);
|
||||
return std::tuple_cat(std::move(current), std::move(rest));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -325,6 +359,14 @@ namespace MWR
|
|||
};
|
||||
};
|
||||
|
||||
/// Specialization of idiom for detecting ByteView::Get.
|
||||
template<size_t N>
|
||||
constexpr bool IsGetter<ByteView::Get<N>> = true;
|
||||
|
||||
/// Alias for simpler use of ByteView::Get.
|
||||
template<size_t N>
|
||||
using Bytes = ByteView::Get<N>;
|
||||
|
||||
namespace Literals
|
||||
{
|
||||
/// Create ByteView with syntax ""_bvec
|
||||
|
|
|
@ -47,7 +47,7 @@ void MWR::C3::Core::GateRelay::OnProtocolS2G(ByteView packet0, std::shared_ptr<D
|
|||
try
|
||||
{
|
||||
auto decrypted = MWR::Crypto::DecryptFromAnonymous(packet0.SubString(1), m_AuthenticationKey, m_DecryptionKey);
|
||||
auto [procedure, rid, timestamp] = ByteView{ decrypted }.Read<ProceduresUnderlyingType, ByteArray<RouteId::BinarySize>, int32_t>();
|
||||
auto [procedure, rid, timestamp] = ByteView{ decrypted }.Read<ProceduresUnderlyingType, Bytes<RouteId::BinarySize>, int32_t>();
|
||||
if (!m_Profiler->Get().m_Gateway.ConnectionExist(RouteId::FromByteView(rid).GetAgentId()))
|
||||
throw std::runtime_error{ "S2G packet received from not connected source." };
|
||||
|
||||
|
@ -274,10 +274,10 @@ void MWR::C3::Core::GateRelay::On(ProceduresN2N::InitializeRouteQuery&& query)
|
|||
auto readView = ByteView{ decryptedPacket };
|
||||
auto newRelayBuildId = BuildId{ readView.Read<BuildId::UnderlyingIntegerType>() };
|
||||
// todo prepending fixed-size key with 4 byte length is unnecessary, (remember to change writing, not only reading)
|
||||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteVector>() };
|
||||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
||||
auto hash = readView.Read<HashT>();
|
||||
auto lastSeen = readView.Read<int32_t>();
|
||||
HostInfo hostInfo(ByteView{ readView.Read<ByteVector>() });
|
||||
HostInfo hostInfo(readView.Read<ByteView>());
|
||||
|
||||
auto receivedFrom = query.GetSenderChannel().lock();
|
||||
if (!receivedFrom)
|
||||
|
@ -299,17 +299,17 @@ void MWR::C3::Core::GateRelay::On(ProceduresS2G::InitializeRouteQuery&& query)
|
|||
auto readView = ByteView{ decryptedPacket };
|
||||
|
||||
// part of message created by parent Node
|
||||
auto [procedureID, parentRid, timestamp, childRid, childSideDid] = readView.Read<ProceduresUnderlyingType, ByteArray<RouteId::BinarySize>, int32_t, ByteArray<RouteId::BinarySize>, ByteArray<DeviceId::BinarySize>>();
|
||||
auto [procedureID, parentRid, timestamp, childRid, childSideDid] = readView.Read<ProceduresUnderlyingType, Bytes<RouteId::BinarySize>, int32_t, Bytes<RouteId::BinarySize>, Bytes<DeviceId::BinarySize>>();
|
||||
|
||||
// part of message from new relay. encrypted once again because it was blob for parent relay.
|
||||
auto childPacket = Crypto::DecryptFromAnonymous(readView, m_AuthenticationKey, m_DecryptionKey);
|
||||
readView = ByteView{ childPacket };
|
||||
|
||||
auto newRelayBuildId = BuildId{ readView.Read<BuildId::UnderlyingIntegerType>() }; // todo blocking
|
||||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteVector>() };
|
||||
auto newRelayPublicKey = Crypto::PublicKey{ readView.Read<ByteView>() };
|
||||
auto hash = readView.Read<HashT>();
|
||||
auto lastSeen = readView.Read<int32_t>();
|
||||
HostInfo hostInfo(ByteView{ readView.Read<ByteVector>() });
|
||||
HostInfo hostInfo(readView.Read<ByteView>());
|
||||
|
||||
auto receivedFrom = query.GetSenderChannel().lock();
|
||||
if (!receivedFrom)
|
||||
|
@ -337,9 +337,9 @@ void MWR::C3::Core::GateRelay::On(ProceduresS2G::DeliverToBinder query)
|
|||
auto readView = ByteView{ decryptedPacket };
|
||||
|
||||
auto unusedProtocolId = readView.Read<int8_t>();
|
||||
auto senderRid = RouteId::FromByteView(readView.Read<ByteArray<RouteId::BinarySize>>());
|
||||
auto senderRid = RouteId::FromByteView(readView.Read<Bytes<RouteId::BinarySize>>());
|
||||
auto timestamp = readView.Read<int32_t>();
|
||||
auto deviceId = readView.Read<ByteArray<DeviceId::BinarySize>>();
|
||||
auto deviceId = readView.Read<Bytes<DeviceId::BinarySize>>();
|
||||
auto connectorHash = readView.Read<HashT>();
|
||||
|
||||
auto connector = m_Connectors.Find([&](auto const& e){ return e->GetNameHash() == connectorHash; });
|
||||
|
@ -372,7 +372,7 @@ void MWR::C3::Core::GateRelay::On(ProceduresS2G::AddDeviceResponse response)
|
|||
{
|
||||
auto decryptedPacket = response.GetQueryPacket(m_AuthenticationKey, m_DecryptionKey);
|
||||
auto readView = ByteView{ decryptedPacket };
|
||||
auto [unsusedProcedureNo, unusedSenderRouteId, timestamp, deviceId, deviceTypeHash, flags] = readView.Read<ProceduresUnderlyingType, ByteArray<RouteId::BinarySize>, int32_t, DeviceId::UnderlyingIntegerType, HashT, std::uint8_t>();
|
||||
auto [unsusedProcedureNo, unusedSenderRouteId, timestamp, deviceId, deviceTypeHash, flags] = readView.Read<ProceduresUnderlyingType, Bytes<RouteId::BinarySize>, int32_t, DeviceId::UnderlyingIntegerType, HashT, std::uint8_t>();
|
||||
bool isChannel = flags & 1;
|
||||
bool isNegotiationChannel = flags & (1 << 1);
|
||||
|
||||
|
@ -393,7 +393,7 @@ void MWR::C3::Core::GateRelay::On(ProceduresS2G::AddDeviceResponse response)
|
|||
void MWR::C3::Core::GateRelay::On(ProceduresN2N::ChannelIdExchangeStep1 query)
|
||||
{
|
||||
auto readView = ByteView{ query.GetQueryPacket() };
|
||||
auto newOutputId = readView.Read<ByteVector>();
|
||||
auto newOutputId = readView.Read<ByteView>();
|
||||
|
||||
auto newInputId = MWR::Utils::GenerateRandomString(newOutputId.size());
|
||||
auto sender = query.GetSenderChannel().lock();
|
||||
|
@ -426,7 +426,7 @@ void MWR::C3::Core::GateRelay::On(ProceduresS2G::NewNegotiatedChannelNotificatio
|
|||
{
|
||||
auto decryptedPacket = query.GetQueryPacket(m_AuthenticationKey, m_DecryptionKey);
|
||||
auto readView = ByteView{ decryptedPacket };
|
||||
auto [unsusedProcedureNo, unusedSenderRouteId, timestamp, newDeviceId, negotiatorId, inId, outId] = readView.Read<ProceduresUnderlyingType, ByteArray<RouteId::BinarySize>, int32_t, DeviceId::UnderlyingIntegerType, DeviceId::UnderlyingIntegerType, std::string, std::string>();
|
||||
auto [unsusedProcedureNo, unusedSenderRouteId, timestamp, newDeviceId, negotiatorId, inId, outId] = readView.Read<ProceduresUnderlyingType, Bytes<RouteId::BinarySize>, int32_t, DeviceId::UnderlyingIntegerType, DeviceId::UnderlyingIntegerType, std::string, std::string>();
|
||||
|
||||
auto agent = m_Profiler->Get().m_Gateway.m_Agents.Find(query.GetSenderRouteId().GetAgentId());
|
||||
if (!agent)
|
||||
|
@ -448,7 +448,7 @@ void MWR::C3::Core::GateRelay::On(ProceduresS2G::Notification query)
|
|||
{
|
||||
auto decryptedPacket = query.GetQueryPacket(m_AuthenticationKey, m_DecryptionKey);
|
||||
auto readView = ByteView{ decryptedPacket };
|
||||
auto [unsusedProcedureNo, unusedSenderRouteId, timestamp, blob] = readView.Read<ProceduresUnderlyingType, ByteArray<RouteId::BinarySize>, int32_t, ByteVector>();
|
||||
auto [unsusedProcedureNo, unusedSenderRouteId, timestamp, blob] = readView.Read<ProceduresUnderlyingType, Bytes<RouteId::BinarySize>, int32_t, ByteView>();
|
||||
// blob has not defined structure. Currently Notification is used as ping response.
|
||||
|
||||
auto agent = m_Profiler->Get().m_Gateway.m_Agents.Find(query.GetSenderRouteId().GetAgentId());
|
||||
|
|
|
@ -247,7 +247,7 @@ void MWR::C3::Core::NodeRelay::On(ProceduresG2X::RunCommandOnAgentQuery query)
|
|||
void MWR::C3::Core::NodeRelay::On(ProceduresG2X::AddRoute query)
|
||||
{
|
||||
auto recipient = query.GetRecipientRouteId();
|
||||
auto [newRouteBA, directionDidBA] = ByteView{ query.GetPacketBody() }.Read<ByteArray<RouteId::BinarySize>, ByteArray<DeviceId::BinarySize>>();
|
||||
auto [newRouteBA, directionDidBA] = ByteView{ query.GetPacketBody() }.Read<Bytes<RouteId::BinarySize>, Bytes<DeviceId::BinarySize>>();
|
||||
auto newRoute = RouteId::FromByteView(newRouteBA);
|
||||
auto directionDid = DeviceId(directionDidBA);
|
||||
std::shared_ptr<DeviceBridge> bridge;
|
||||
|
@ -301,7 +301,7 @@ void MWR::C3::Core::NodeRelay::On(ProceduresG2X::DeliverToBinder query)
|
|||
void MWR::C3::Core::NodeRelay::On(ProceduresN2N::ChannelIdExchangeStep1 query)
|
||||
{
|
||||
auto readView = ByteView{ query.GetQueryPacket() };
|
||||
auto newOutputId = readView.Read<ByteVector>();
|
||||
auto newOutputId = readView.Read<ByteView>();
|
||||
|
||||
auto newInputId = MWR::Utils::GenerateRandomString(newOutputId.size());
|
||||
auto sender = query.GetSenderChannel().lock();
|
||||
|
@ -324,7 +324,7 @@ void MWR::C3::Core::NodeRelay::On(ProceduresN2N::ChannelIdExchangeStep1 query)
|
|||
void MWR::C3::Core::NodeRelay::On(ProceduresN2N::ChannelIdExchangeStep2 query)
|
||||
{
|
||||
auto readView = ByteView{ query.GetQueryPacket() };
|
||||
auto newOutputId = readView.Read<ByteVector>();
|
||||
auto newOutputId = readView.Read<ByteView>();
|
||||
|
||||
auto sender = query.GetSenderChannel().lock();
|
||||
|
||||
|
@ -334,7 +334,7 @@ void MWR::C3::Core::NodeRelay::On(ProceduresN2N::ChannelIdExchangeStep2 query)
|
|||
|
||||
ByteVector args = sender->GetChannelParameters();
|
||||
auto hash = sender->GetTypeNameHash();
|
||||
auto newInputId = ByteVector{ sender->GetInputId() };
|
||||
auto newInputId = sender->GetInputId() ;
|
||||
DetachDevice(sender->GetDid());
|
||||
sender.reset();
|
||||
// Don't use sender below;
|
||||
|
|
|
@ -41,7 +41,7 @@ std::shared_ptr<MWR::C3::Core::DeviceBridge> MWR::C3::Core::Relay::CreateAndAtta
|
|||
if (isNegotiationChannel)
|
||||
{
|
||||
auto readView = commandLine;
|
||||
auto negotiationId = readView.Read<ByteVector>();
|
||||
auto negotiationId = readView.Read<ByteView>();
|
||||
helper.reserve(commandLine.size() + negotiationId.size() + sizeof(std::uint32_t));
|
||||
auto generatedId = MWR::Utils::GenerateRandomString(negotiationId.size());
|
||||
if (negotiationClient)
|
||||
|
|
Loading…
Reference in New Issue