mirror of https://github.com/infosecn1nja/C3.git
Add detailed help to channel linter
parent
e0b253f6aa
commit
471ea7cc7a
|
@ -13,8 +13,14 @@ namespace MWR::C3::Linter
|
||||||
return m_ChannelArguments || m_Command || m_TestChannelIO;
|
return m_ChannelArguments || m_Command || m_TestChannelIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether -h was set
|
||||||
|
bool m_ShowHelp = false;
|
||||||
|
|
||||||
|
/// Whether -l was set
|
||||||
|
bool m_ListChannels = false;
|
||||||
|
|
||||||
/// Channel name e.g. Slack
|
/// Channel name e.g. Slack
|
||||||
std::string m_ChannelName;
|
std::optional<std::string> m_ChannelName;
|
||||||
|
|
||||||
/// String representation of arguments passed to create a channel
|
/// String representation of arguments passed to create a channel
|
||||||
std::optional<StringVector> m_ChannelArguments;
|
std::optional<StringVector> m_ChannelArguments;
|
||||||
|
|
|
@ -6,17 +6,22 @@ namespace MWR::C3::Linter
|
||||||
ArgumentParser::ArgumentParser(int argc, char** argv) : m_ArgParser()
|
ArgumentParser::ArgumentParser(int argc, char** argv) : m_ArgParser()
|
||||||
{
|
{
|
||||||
ConfigureParser();
|
ConfigureParser();
|
||||||
|
m_AppName = argv[0];
|
||||||
m_ArgParser.parse(argc, argv);
|
m_ArgParser.parse(argc, argv);
|
||||||
m_Config = CreateConfig();
|
FillConfig();
|
||||||
|
ValidateConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArgumentParser::ConfigureParser()
|
void ArgumentParser::ConfigureParser()
|
||||||
{
|
{
|
||||||
m_ArgParser.addArgument("-n", "--name", 1, false);
|
m_ArgParser.addArgument("-h", "--help");
|
||||||
|
m_ArgParser.addArgument("-l", "--list");
|
||||||
|
m_ArgParser.addArgument("-n", "--name", 1);
|
||||||
m_ArgParser.addArgument("-a", "--args", '*');
|
m_ArgParser.addArgument("-a", "--args", '*');
|
||||||
m_ArgParser.addArgument("-c", "--complementary", '*');
|
m_ArgParser.addArgument("-c", "--complementary", '*');
|
||||||
m_ArgParser.addArgument("-i", "--test-io");
|
m_ArgParser.addArgument("-i", "--test-io");
|
||||||
m_ArgParser.addArgument("-x", "--command", '+');
|
m_ArgParser.addArgument("-x", "--command", '+');
|
||||||
|
m_ArgParser.useExceptions(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppConfig const& ArgumentParser::GetConfig() const
|
AppConfig const& ArgumentParser::GetConfig() const
|
||||||
|
@ -26,31 +31,57 @@ namespace MWR::C3::Linter
|
||||||
|
|
||||||
std::string ArgumentParser::GetUsage() const
|
std::string ArgumentParser::GetUsage() const
|
||||||
{
|
{
|
||||||
return m_ArgParser.usage();
|
return "Usage: " + m_AppName.filename().string() + R"( {-h|-l|-n NAME [options]}
|
||||||
|
Mode:
|
||||||
|
-h, --help Show this message and exit.
|
||||||
|
|
||||||
|
-l, --list List registered Channels and exit.
|
||||||
|
|
||||||
|
-n <NAME>, --name <NAME>
|
||||||
|
Select channel with given <NAME> for further processing
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-a [ARGS...], --args [ARGS...]
|
||||||
|
Create channel with given ARGS using the Capability/create/arguments.
|
||||||
|
|
||||||
|
-c [ARGS...], --complementary [ARGS...]
|
||||||
|
Create a complementary channel with given ARGS.
|
||||||
|
|
||||||
|
-i, --test-io Create a pair of channels and send packets through.
|
||||||
|
If this option is present -a [ARGS...] must be specified.
|
||||||
|
If -c is not present, complementary channel arguments are deduced by swapping
|
||||||
|
parameters from Capability/create/arguments arrays.
|
||||||
|
|
||||||
|
-x <ID> [ARGS... ], --command <ID> [ARGS... ]
|
||||||
|
Execute a command with a given <ID> and arguments [ARGS...]
|
||||||
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
MWR::C3::Linter::AppConfig ArgumentParser::CreateConfig() const
|
void ArgumentParser::FillConfig()
|
||||||
{
|
{
|
||||||
AppConfig config;
|
m_Config.m_ShowHelp = m_ArgParser.exists("help");
|
||||||
config.m_ChannelName = m_ArgParser.retrieve<std::string>("name");
|
m_Config.m_ListChannels = m_ArgParser.exists("list");
|
||||||
|
|
||||||
|
if (m_ArgParser.exists("name"))
|
||||||
|
m_Config.m_ChannelName = m_ArgParser.retrieve<std::string>("name");
|
||||||
|
|
||||||
if (m_ArgParser.exists("args"))
|
if (m_ArgParser.exists("args"))
|
||||||
config.m_ChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("args");
|
m_Config.m_ChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("args");
|
||||||
|
|
||||||
if (m_ArgParser.exists("complementary"))
|
if (m_ArgParser.exists("complementary"))
|
||||||
config.m_ComplementaryChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("complementary");
|
m_Config.m_ComplementaryChannelArguments = m_ArgParser.retrieve<std::vector<std::string>>("complementary");
|
||||||
|
|
||||||
config.m_TestChannelIO = m_ArgParser.exists("test-io");
|
m_Config.m_TestChannelIO = m_ArgParser.exists("test-io");
|
||||||
|
|
||||||
if (m_ArgParser.exists("command"))
|
if (m_ArgParser.exists("command"))
|
||||||
config.m_Command = m_ArgParser.retrieve<StringVector>("command");
|
m_Config.m_Command = m_ArgParser.retrieve<StringVector>("command");
|
||||||
|
|
||||||
ValidateConfig();
|
|
||||||
return config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArgumentParser::ValidateConfig() const
|
void ArgumentParser::ValidateConfig() const
|
||||||
{
|
{
|
||||||
|
if(!(m_Config.m_ShowHelp || m_Config.m_ListChannels || m_Config.m_ChannelName))
|
||||||
|
throw std::invalid_argument("Argument error: either -h (--help), -l (--list) or -n (--name) must be specified");
|
||||||
|
|
||||||
if (m_Config.m_TestChannelIO && !m_Config.m_ChannelArguments)
|
if (m_Config.m_TestChannelIO && !m_Config.m_ChannelArguments)
|
||||||
throw std::invalid_argument("Argument error: specified -i (--test-io) without -a (--args)");
|
throw std::invalid_argument("Argument error: specified -i (--test-io) without -a (--args)");
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,15 @@ namespace MWR::C3::Linter
|
||||||
void ConfigureParser();
|
void ConfigureParser();
|
||||||
|
|
||||||
/// Helper create AppConfig
|
/// Helper create AppConfig
|
||||||
AppConfig CreateConfig() const;
|
void FillConfig();
|
||||||
|
|
||||||
/// Validate created config, uses ArgumentParser options in messages
|
/// Validate created config, uses ArgumentParser options in messages
|
||||||
/// @throws std::invalid_argument if config is not valid
|
/// @throws std::invalid_argument if config is not valid
|
||||||
void ValidateConfig() const;
|
void ValidateConfig() const;
|
||||||
|
|
||||||
|
/// place to store argv[0]
|
||||||
|
std::filesystem::path m_AppName;
|
||||||
|
|
||||||
/// Internal argument parser
|
/// Internal argument parser
|
||||||
argparse::ArgumentParser m_ArgParser;
|
argparse::ArgumentParser m_ArgParser;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace MWR::C3::Linter
|
||||||
|
|
||||||
ChannelLinter::ChannelLinter(AppConfig config) :
|
ChannelLinter::ChannelLinter(AppConfig config) :
|
||||||
m_Config(std::move(config)),
|
m_Config(std::move(config)),
|
||||||
m_ChannelData(GetChannelInfo(m_Config.m_ChannelName)),
|
m_ChannelData(GetChannelInfo(*m_Config.m_ChannelName)),
|
||||||
m_ChannelCapability(GetChannelCapability(m_ChannelData)),
|
m_ChannelCapability(GetChannelCapability(m_ChannelData)),
|
||||||
m_CreateForm{ [this]
|
m_CreateForm{ [this]
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,9 +11,26 @@ try
|
||||||
using namespace MWR;
|
using namespace MWR;
|
||||||
C3::Linter::ArgumentParser argParser(argc, argv);
|
C3::Linter::ArgumentParser argParser(argc, argv);
|
||||||
auto const& config = argParser.GetConfig();
|
auto const& config = argParser.GetConfig();
|
||||||
std::cout << "Channel: " << config.m_ChannelName << std::endl;
|
if (config.m_ShowHelp)
|
||||||
|
{
|
||||||
|
std::cout << argParser.GetUsage() << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.m_ListChannels)
|
||||||
|
{
|
||||||
|
auto const& channels = C3::InterfaceFactory::Instance().GetMap<C3::AbstractChannel>();
|
||||||
|
std::cout << "Registered channels: \n";
|
||||||
|
for (auto [hash, channelData] : channels)
|
||||||
|
std::cout << channelData.m_Name << '\n';
|
||||||
|
std::cout << std::flush;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(config.m_ChannelName);
|
||||||
|
std::cout << "Channel: " << *config.m_ChannelName << std::endl;
|
||||||
auto channelLinter = C3::Linter::ChannelLinter(config);
|
auto channelLinter = C3::Linter::ChannelLinter(config);
|
||||||
std::cout << config.m_ChannelName << "'s Capability json verified OK." << std::endl;
|
std::cout << *config.m_ChannelName << "'s Capability json verified OK." << std::endl;
|
||||||
|
|
||||||
channelLinter.Process();
|
channelLinter.Process();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,11 +1,39 @@
|
||||||
# C3 Channel Linter
|
# C3 Channel Linter
|
||||||
|
|
||||||
Standalone tool to ease the development and debugging of channels.
|
Tool to ease the development and debugging of channels.
|
||||||
|
Main goal is to provide a simple application to test channels without the need of spinning up the whole C3 network.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
This tool provides console frontend for channel usage
|
This tool provides console frontend for channel usage.
|
||||||
|
|
||||||
|
```
|
||||||
|
Usage: ChannelLinter.exe {-h|-l|-n NAME [options]}
|
||||||
|
Mode:
|
||||||
|
-h, --help Show this message and exit.
|
||||||
|
|
||||||
|
-l, --list List registered Channels and exit.
|
||||||
|
|
||||||
|
-n <NAME>, --name <NAME>
|
||||||
|
Select channel with given <NAME> for further processing
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-a [ARGS...], --args [ARGS...]
|
||||||
|
Create channel with given ARGS using the Capability/create/arguments.
|
||||||
|
|
||||||
|
-c [ARGS...], --complementary [ARGS...]
|
||||||
|
Create a complementary channel with given ARGS.
|
||||||
|
|
||||||
|
-i, --test-io Create a pair of channels and send packets through.
|
||||||
|
If this option is present -a [ARGS...] must be specified.
|
||||||
|
If -c is not present, complementary channel arguments are deduced by swapping
|
||||||
|
parameters from Capability/create/arguments arrays.
|
||||||
|
|
||||||
|
-x <ID> [ARGS... ], --command <ID> [ARGS... ]
|
||||||
|
Execute a command with a given <ID> and arguments [ARGS...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Example workflows:
|
||||||
1. Parse the json returned from `GetCapability()` and validate it against C3 rules:
|
1. Parse the json returned from `GetCapability()` and validate it against C3 rules:
|
||||||
`-n ChannelName`
|
`-n ChannelName`
|
||||||
`--name ChannelName`
|
`--name ChannelName`
|
||||||
|
@ -16,7 +44,7 @@ This tool provides console frontend for channel usage
|
||||||
`--args [Argument1 Argument2 ...]`
|
`--args [Argument1 Argument2 ...]`
|
||||||
e.g. `ChannelLinter.exe -n UncShareFile --args inputId outputId C:\Temp\C3Store false`
|
e.g. `ChannelLinter.exe -n UncShareFile --args inputId outputId C:\Temp\C3Store false`
|
||||||
Note: Messeges logged by calls to `this->Log()` will not be displayed if the channel constructor throws.
|
Note: Messeges logged by calls to `this->Log()` will not be displayed if the channel constructor throws.
|
||||||
3. Test channel permeability - create a complemetary pair of channels and send message through.
|
3. Test channel permeability - create a complemetary pair of channels and send messages through.
|
||||||
`-i`
|
`-i`
|
||||||
`--test-io`
|
`--test-io`
|
||||||
e.g. `ChannelLinter.exe -n UncShareFile --args inputId outputId C:\Temp\C3Store false -i`
|
e.g. `ChannelLinter.exe -n UncShareFile --args inputId outputId C:\Temp\C3Store false -i`
|
||||||
|
|
Loading…
Reference in New Issue