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
|
// 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 <gdbuspp/connection.hpp>
#include <gdbuspp/service.hpp>
#include <iostream>
#include <common/cmdargparser.hpp>
#include <dbus/constants.hpp>
#include <log/ansicolours.hpp>
#include <log/logwriter.hpp>
#include <log/logwriters/implementations.hpp>
#include <log/dbus-log.hpp>
#include "service.hpp"
int devposture_main(ParsedArgs::Ptr args)
{
std::cout << get_version(args->GetArgv0()) << std::endl;
if (!args->Present("profile-dir"))
{
throw CommandException("openvpn3-service-devposture",
"--profile-dir is required");
}
// Enable automatic shutdown if the config manager is
// idling for 1 minute or more. By idling, it means
// no configuration files is stored in memory.
unsigned int idle_wait_min = 3;
if (args->Present("idle-exit"))
{
idle_wait_min = std::atoi(args->GetValue("idle-exit", 0).c_str());
}
// Open a log destination, if requested
std::ofstream logfs{};
std::ostream *logfile = nullptr;
LogWriter::Ptr logwr = nullptr;
ColourEngine::Ptr colourengine = nullptr;
if (args->Present("log-file"))
{
std::string fname = args->GetValue("log-file", 0);
if ("stdout:" != fname)
{
logfs.open(fname.c_str(), std::ios_base::app);
logfile = &logfs;
}
else
{
logfile = &std::cout;
}
if (args->Present("colour"))
{
colourengine.reset(new ANSIColours());
logwr.reset(new ColourStreamWriter(*logfile,
colourengine.get()));
}
else
{
logwr.reset(new StreamLogWriter(*logfile));
}
}
unsigned int log_level = 3;
if (args->Present("log-level"))
{
log_level = std::atoi(args->GetValue("log-level", 0).c_str());
}
auto dbuscon = DBus::Connection::Create(DBus::BusType::SYSTEM);
auto devposture_service = DBus::Service::Create<DevPosture::Service>(dbuscon, logwr, log_level);
devposture_service->LoadProtocolProfiles(args->GetValue("profile-dir", 0));
devposture_service->PrepareIdleDetector(std::chrono::minutes(idle_wait_min));
devposture_service->Run();
return 0;
}
int main(int argc, char **argv)
{
SingleCommand argparser(argv[0], "OpenVPN 3 Device Posture", devposture_main);
argparser.AddVersionOption();
argparser.AddOption("log-level",
"LOG-LEVEL",
true,
"Log verbosity level (valid values 0-6, default 3)");
argparser.AddOption("log-file",
"FILE",
true,
"Write log data to FILE. Use 'stdout:' for console logging.");
argparser.AddOption("colour",
0,
"Make the log lines colourful");
argparser.AddOption("idle-exit",
"MINUTES",
true,
"How long to wait before exiting if being idle. "
"0 disables it (Default: 3 minutes)");
argparser.AddOption("profile-dir",
"DIRECTORY",
true,
"Directory containing device posture protocol profiles");
try
{
// This program does not require root privileges,
// so if used - drop those privileges
drop_root();
return argparser.RunCommand(simple_basename(argv[0]), argc, argv);
}
catch (const LogServiceProxyException &excp)
{
std::cerr << "** ERROR ** " << excp.what();
std::cerr << "\n " << excp.debug_details() << "\n";
return 2;
}
catch (const CommandException &excp)
{
std::cerr << excp.getCommand()
<< ": ** ERROR ** " << excp.what() << "\n";
return 2;
}
catch (const std::exception &e)
{
std::cerr << e.what() << "\n";
return 2;
}
}
|