1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
// OpenVPN 3 Linux client -- Next generation OpenVPN client
//
// SPDX-License-Identifier: AGPL-3.0-only
//
// Copyright (C) 2017- OpenVPN Inc <sales@openvpn.net>
// Copyright (C) 2024- Răzvan Cojocaru <razvan.cojocaru@openvpn.com>
//
#include <ctime>
#include <iostream>
#include <json/json.h>
#include "src/client/proxy-devposture.hpp"
#include "src/common/cmdargparser.hpp"
#include "src/dbus/path.hpp"
#include "src/common/utils.hpp"
int devposture_proxy(ParsedArgs::Ptr args)
{
std::string mode;
try
{
args->CheckExclusiveOptions({{"list-modules", "enterprise-profile"},
{"list-modules", "protocol"},
{"protocol", "enterprise-profile"}});
mode = args->Present({"list-modules", "enterprise-profile", "protocol"});
}
catch (const OptionNotFound &)
{
throw CommandException(args->GetArgv0(),
"Missing arguments, see --help");
}
catch (const ExclusiveOptionError &excp)
{
throw CommandException(args->GetArgv0(), excp.what());
}
drop_root();
try
{
auto connection = DBus::Connection::Create(DBus::BusType::SYSTEM);
auto proxy = DevPosture::Proxy::Handler::Create(connection);
// List just the registered modules
if ("list-modules" == mode)
{
std::cout << "*** Registered modules:\n";
for (const auto &m : proxy->GetRegisteredModules())
{
std::cout << m << "\n";
}
return 0;
}
// Run DPC checks
if (("enterprise-profile" == mode)
|| ("protocol" == mode))
{
if (!args->Present("test"))
{
throw CommandException("devposture-proxy/enterprise-profile",
"At least one --test must be provided");
};
// Build the DPC request object
Json::Value request_content;
request_content["ver"] = "1.0";
request_content["correlation_id"] = generate_path_uuid("", '-');
std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);
std::ostringstream tstamp;
tstamp << std::put_time(&tm, "%c %Z");
request_content["timestamp"] = tstamp.str();
// Add the checks requested
for (uint32_t i = 0; i < args->GetValueLen("test"); i++)
{
request_content[args->GetValue("test", i)] = true;
}
// Finalize the request object
Json::Value dpc_request;
dpc_request["dpc_request"] = request_content;
Json::StreamWriterBuilder builder;
builder.settings_["indentation"] = "";
std::string dpc_req_str = Json::writeString(builder, dpc_request);
// Extract the DPC protocol to use
std::string protocol;
if ("enterprise-profile" == mode)
{
// In this mode, lookup the protocol for this enterprise profile
std::string profile = args->GetValue("enterprise-profile", 0);
protocol = proxy->ProtocolLookup(profile);
std::cout << "*** ProtocolLookup(\"" + profile + "\"): "
<< protocol << std::endl;
auto alias_split = protocol.find(":");
if (alias_split != std::string::npos)
{
// If the lookup includes aliases, use the first element
std::string p = protocol.substr(0, alias_split);
protocol = p;
}
}
else
{
protocol = args->GetValue("protocol", 0);
}
// Run the DPC checks
std::cout << "\n*** Using DPC protocol '" << protocol << "'" << std::endl;
std::cout << "*** RunChecks(\"" << protocol << "\", \""
<< dpc_req_str << "\"): " << std::endl
<< proxy->RunChecks(protocol, dpc_req_str) << "\n";
return 0;
}
}
catch (const std::exception &e)
{
std::cerr << "Exception caught: " << e.what() << "\n";
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
SingleCommand::Ptr cmd;
cmd.reset(new SingleCommand("devposture-proxy",
"Test program for Device Posture Checks",
devposture_proxy));
cmd->AddOption("list-modules",
"List available device posture check modules");
cmd->AddOption("enterprise-profile",
"PROFILE-NAME",
true,
"Run a device posture check locally based on an Enterprise Profile name");
cmd->AddOption("protocol",
"PROTOCOL",
true,
"Run a device posture check locally using a specific protocol name");
cmd->AddOption("test",
"TEST-NAME",
true,
"Which tests to run. Test names are defined in the protocol profile");
try
{
return cmd->RunCommand("devposture-proxy", argc, argv);
}
catch (const CommandException &excp)
{
std::cout << simple_basename(argv[0])
<< ": ** ERROR ** " << excp.what() << std::endl;
return 2;
}
}
|