mirror of https://github.com/infosecn1nja/C3.git
158 lines
8.4 KiB
C++
158 lines
8.4 KiB
C++
#pragma once
|
|
|
|
#include "Relay.h"
|
|
|
|
namespace FSecure::C3::Core
|
|
{
|
|
/// Relay class specialization that implements a "client" Relay.
|
|
struct NodeRelay : Relay, ProceduresG2X::RequestHandler
|
|
{
|
|
/// Destructor
|
|
virtual ~NodeRelay() = default;
|
|
|
|
/// Factory method.
|
|
/// @param callbackOnLog callback fired whenever a new Log entry is being added.
|
|
/// @param interfaceFactory reference to interface factory.
|
|
/// @param gatewaySignature public signature used by Network's Gateway to authenticate itself.
|
|
/// @param broadcastKey Network's symmetric key.
|
|
/// @param gatewayInitialPackets initial Procedures for this NodeRelay. Should contain creation of a at least a single Channel.
|
|
/// @param buildId Build identifier.
|
|
/// @param agentId Agent identifier.
|
|
/// @param asymmetricKeys asymmetric keys used to communicate with the Gateway.
|
|
static std::shared_ptr<NodeRelay> CreateAndRun(LoggerCallback callbackOnLog, InterfaceFactory& interfaceFactory, Crypto::PublicSignature const& gatewaySignature,
|
|
Crypto::SymmetricKey const& broadcastKey, std::vector<ByteVector> const& gatewayInitialPackets, BuildId buildId, AgentId agentId = AgentId::GenerateRandom(),
|
|
Crypto::AsymmetricKeys const& asymmetricKeys = Crypto::GenerateAsymmetricKeys());
|
|
|
|
protected:
|
|
/// A protected constructor. @see Relay::Relay.
|
|
/// @param callbackOnLog callback fired whenever a new Log entry is being added.
|
|
/// @param interfaceFactory reference to interface factory.
|
|
/// @param gatewaySignature public signature used by Network's Gateway to authenticate itself.
|
|
/// @param broadcastKey Network's symmetric key.
|
|
/// @param buildId Build identifier.
|
|
/// @param agentId Agent identifier.
|
|
/// @param asymmetricKeys asymmetric keys used to communicate with the Gateway.
|
|
NodeRelay(LoggerCallback callbackOnLog, InterfaceFactory& interfaceFactory, Crypto::PublicSignature const& gatewaySignature, Crypto::SymmetricKey const& broadcastKey,
|
|
BuildId buildId, AgentId agentId = AgentId::GenerateRandom(), Crypto::AsymmetricKeys const& asymmetricKeys = Crypto::GenerateAsymmetricKeys());
|
|
|
|
/// Fired when a S2G protocol packet arrives.
|
|
/// @param packet0 a buffer that contains whole packet.
|
|
/// @param sender a Channel that provided the packet.
|
|
void OnProtocolS2G(ByteView packet0, std::shared_ptr<DeviceBridge> sender) override;
|
|
|
|
/// Fired when a G2A protocol packet arrives.
|
|
/// @param packet0 a buffer that contains whole packet.
|
|
/// @param sender a Channel that provided the packet.
|
|
void OnProtocolG2A(ByteView packet0, std::shared_ptr<DeviceBridge> sender) override;
|
|
|
|
/// Fired when a G2R protocol packet arrives.
|
|
/// @param packet0 a buffer that contains whole packet.
|
|
/// @param sender a Channel that provided the packet.
|
|
void OnProtocolG2R(ByteView packet0, std::shared_ptr<DeviceBridge> sender) override;
|
|
|
|
/// Passes provided (most probably an S2X) packet further.
|
|
/// @param packet0 a buffer that contains whole packet.
|
|
/// @param routeId packet's destination.
|
|
virtual void MultiSendPacketFurtherThroughRouteId(ByteView packet0, RouteId routeId);
|
|
|
|
/// Called whenever an attached Binder Peripheral wants to send a Command to its Connector Binder.
|
|
/// @param command full Command with arguments.
|
|
/// @param channel Interface that will be used to send the packet.
|
|
void PostCommandToConnector(ByteView command, std::shared_ptr<DeviceBridge> channel) override;
|
|
|
|
/// Expose all base classes `On` methods.
|
|
using Relay::On;
|
|
using ProceduresG2X::RequestHandler::On;
|
|
|
|
/// Handler fired when a N2N::InitializeRoute Procedure Query arrives.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresN2N::InitializeRouteQuery query) override;
|
|
|
|
/// Handler fired when a N2N::InitializeRoute Procedure arrives.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresS2G::InitializeRouteQuery query) override;
|
|
|
|
/// Handler fired when a G2X::AddRoute Procedure Query arrives.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresG2X::AddRoute query) override;
|
|
|
|
/// Handler Fired N2N::ChannelIdExchangeStep1 Procedure Query arrives.
|
|
/// This query indicates that some relay wants to negotiate joining the network.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresN2N::ChannelIdExchangeStep1 query) override;
|
|
|
|
/// Handler Fired N2N::ChannelIdExchangeStep2 Procedure Query arrives.
|
|
/// This query contains parameters for unique connection. Relay can send initialization query to GateRelay to registration in network.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresN2N::ChannelIdExchangeStep2 query) override;
|
|
|
|
/// Sets the default Device used in communication with the server.
|
|
/// @param gatewayReturnChannel Device to set as a new return channel.
|
|
void SetGatewayReturnChannel(std::shared_ptr<DeviceBridge> const& gatewayReturnChannel);
|
|
|
|
/// Sets the default Device used in communication with the server.
|
|
/// @param args Device id stored in byte form.
|
|
void SetGatewayReturnChannel(FSecure::ByteView args);
|
|
|
|
/// Returns timestamp to Gateway.
|
|
/// @param args unused.
|
|
void Ping(FSecure::ByteView args);
|
|
|
|
/// Gets the default Device used in communication with the server.
|
|
/// @return current Gateway return channel.
|
|
std::shared_ptr<DeviceBridge> GetGatewayReturnChannel() const;
|
|
|
|
/// Creates and attaches a new Device.
|
|
/// @param iid address of Device in Relay.
|
|
/// @param deviceNameHash hash to distinguish devices types.
|
|
/// @param isNegotiationChannel true if channel will support negotiation procedure.
|
|
/// @param commandLine buffer containing Device's construction parameters.
|
|
/// @param negotiationClient true if channel will support negotiation procedure, and should start it.
|
|
/// @return newly created Device or null if there was no factory able to process provided command-line.
|
|
/// @throws std::runtime_error if device cannot be created becouse it was not registrated or commandLine is invalid.
|
|
std::shared_ptr<DeviceBridge> CreateAndAttachDevice(DeviceId iid, HashT deviceNameHash, bool isNegotiationChannel, ByteView commandLine, bool negotiationClient = false) override;
|
|
|
|
/// Send packet through first interface to gateway, with registration request.
|
|
void InitializeRoute();
|
|
|
|
/// Starts procedure of unique channel negotiation.
|
|
/// @param device channel that will perform negotiation.
|
|
void NegotiateChannel(std::shared_ptr<DeviceBridge> const& device);
|
|
|
|
/// Handler fired when a G2X::RunCommandOnAgentQuery Procedure Query arrives.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresG2X::RunCommandOnAgentQuery) override;
|
|
|
|
/// Handler fired when a G2X::RunCommandOnDeviceQuery Procedure Query arrives.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresG2X::RunCommandOnDeviceQuery) override;
|
|
|
|
/// Handler fired when a G2X::DeliverToBinder Procedure Query arrives.
|
|
/// @param query object representing the Query.
|
|
void On(ProceduresG2X::DeliverToBinder query) override;
|
|
|
|
/// Inform gateway that new Device was added correctly.
|
|
/// @param device pointer to newly created device.
|
|
void SendNewDeviceNotification(std::shared_ptr<FSecure::C3::Core::DeviceBridge> const& device);
|
|
|
|
/// Inform gateway that new Device was added by negotiation process.
|
|
/// @param newDeviceId id of new device in relay.
|
|
/// @param negotiatorId id of device that was used for negotiation.
|
|
/// @param inId negotiated input parameter.
|
|
/// @param outId negotiated output parameter.
|
|
void SendNewNegotiatedChannelNotification(DeviceId newDeviceId, DeviceId negotiatorId, ByteView inId, ByteView outId);
|
|
|
|
/// Creates device from provided byte form of arguments @see CreateAndAttachDevice.
|
|
/// @param commandArgs all arguments for CreateAndAttachDevice packed in byte form.
|
|
std::shared_ptr<FSecure::C3::Core::DeviceBridge> RunCommandAddDevice(ByteView commandArgs);
|
|
|
|
private:
|
|
std::atomic<DeviceId::UnderlyingIntegerType> m_LastResevedDeviceId = ~(1 << (8 * DeviceId::BinarySize - 1)); ///< DeviceId with MSB set are used for deviceId assigned by Node
|
|
|
|
std::weak_ptr<DeviceBridge> m_GatewayReturnChannel; ///< Channel used to communicate with the Gateway by default.
|
|
Crypto::PublicSignature m_GatewaySignature; ///< A public signature used by Network's Gateway to authenticate itself.
|
|
Crypto::PublicKey m_GatewayEncryptionKey; ///< Gateway's public key (converted from signature) used to encrypt N2G packets.
|
|
Crypto::PublicKey m_MyEncryptionKey; ///< This is going to be sent to Gateway.
|
|
};
|
|
}
|