generate user credentials based on command line iuput
This commit is contained in:
+16
-24
@@ -212,10 +212,12 @@ input_t input {
|
|||||||
sunshine_t sunshine {
|
sunshine_t sunshine {
|
||||||
2, // min_log_level
|
2, // min_log_level
|
||||||
0, // flags
|
0, // flags
|
||||||
{}, //User file
|
{}, // User file
|
||||||
{}, //Username
|
{}, // Username
|
||||||
{}, //Password
|
{}, // Password
|
||||||
{} //Password Salt
|
{}, // Password Salt
|
||||||
|
SUNSHINE_ASSETS_DIR "/sunshine.conf", // config file
|
||||||
|
{} // cmd args
|
||||||
};
|
};
|
||||||
|
|
||||||
bool endline(char ch) {
|
bool endline(char ch) {
|
||||||
@@ -500,19 +502,6 @@ void list_int_f(std::unordered_map<std::string, std::string> &vars, const std::s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_help(const char *name) {
|
|
||||||
std::cout
|
|
||||||
<< "Usage: "sv << name << " [options] [/path/to/configuration_file]"sv << std::endl
|
|
||||||
<< " Any configurable option can be overwritten with: \"name=value\""sv << std::endl
|
|
||||||
<< std::endl
|
|
||||||
<< " --help | print help"sv << std::endl
|
|
||||||
<< std::endl
|
|
||||||
<< " flags"sv << std::endl
|
|
||||||
<< " -0 | Read PIN from stdin"sv << std::endl
|
|
||||||
<< " -1 | Do not load previously saved state and do retain any state after shutdown"sv << std::endl
|
|
||||||
<< " | Effectively starting as if for the first time without overwriting any pairings with your devices"sv;
|
|
||||||
}
|
|
||||||
|
|
||||||
int apply_flags(const char *line) {
|
int apply_flags(const char *line) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while(*line != '\0') {
|
while(*line != '\0') {
|
||||||
@@ -651,11 +640,9 @@ void apply_config(std::unordered_map<std::string, std::string> &&vars) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int parse(int argc, char *argv[]) {
|
int parse(int argc, char *argv[]) {
|
||||||
const char *config_file = SUNSHINE_ASSETS_DIR "/sunshine.conf";
|
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> cmd_vars;
|
std::unordered_map<std::string, std::string> cmd_vars;
|
||||||
|
|
||||||
for(auto x = argc - 1; x > 0; --x) {
|
for(auto x = 1; x < argc; ++x) {
|
||||||
auto line = argv[x];
|
auto line = argv[x];
|
||||||
|
|
||||||
if(line == "--help"sv) {
|
if(line == "--help"sv) {
|
||||||
@@ -663,6 +650,13 @@ int parse(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(*line == '-') {
|
else if(*line == '-') {
|
||||||
|
if(*(line + 1) == '-') {
|
||||||
|
sunshine.cmd.name = line + 2;
|
||||||
|
sunshine.cmd.argc = argc - x - 1;
|
||||||
|
sunshine.cmd.argv = argv + x + 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(apply_flags(line + 1)) {
|
if(apply_flags(line + 1)) {
|
||||||
print_help(*argv);
|
print_help(*argv);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -673,7 +667,7 @@ int parse(int argc, char *argv[]) {
|
|||||||
|
|
||||||
auto pos = std::find(line, line_end, '=');
|
auto pos = std::find(line, line_end, '=');
|
||||||
if(pos == line_end) {
|
if(pos == line_end) {
|
||||||
config_file = line;
|
sunshine.config_file = line;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TUPLE_EL(var, 1, parse_option(line, line_end));
|
TUPLE_EL(var, 1, parse_option(line, line_end));
|
||||||
@@ -687,9 +681,7 @@ int parse(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sunshine.config_file = config_file;
|
auto vars = parse_config(read_file(sunshine.config_file.c_str()));
|
||||||
|
|
||||||
auto vars = parse_config(read_file(config_file));
|
|
||||||
|
|
||||||
for(auto &[name, value] : cmd_vars) {
|
for(auto &[name, value] : cmd_vars) {
|
||||||
vars.insert_or_assign(std::move(name), std::move(value));
|
vars.insert_or_assign(std::move(name), std::move(value));
|
||||||
|
|||||||
@@ -96,6 +96,12 @@ struct sunshine_t {
|
|||||||
std::string salt;
|
std::string salt;
|
||||||
|
|
||||||
std::string config_file;
|
std::string config_file;
|
||||||
|
|
||||||
|
struct cmd_t {
|
||||||
|
std::string name;
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
} cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern video_t video;
|
extern video_t video;
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ void savePassword(resp_https_t response, req_https_t request) {
|
|||||||
outputTree.put("error", "Password Mismatch");
|
outputTree.put("error", "Password Mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
http::save_user_creds(config::sunshine.credentials_file, newUsername, newPassword, crypto::rand_alphabet(16));
|
http::save_user_creds(config::sunshine.credentials_file, newUsername, newPassword);
|
||||||
http::reload_user_creds(config::sunshine.credentials_file);
|
http::reload_user_creds(config::sunshine.credentials_file);
|
||||||
outputTree.put("status", true);
|
outputTree.put("status", true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ void init(std::shared_ptr<safe::signal_t> shutdown_event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!user_creds_exist(config::sunshine.credentials_file)) {
|
if(!user_creds_exist(config::sunshine.credentials_file)) {
|
||||||
if(save_user_creds(config::sunshine.credentials_file, "sunshine"s, crypto::rand_alphabet(16), crypto::rand_alphabet(16))) {
|
if(save_user_creds(config::sunshine.credentials_file, "sunshine"s, crypto::rand_alphabet(16), true)) {
|
||||||
shutdown_event->raise(true);
|
shutdown_event->raise(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ void init(std::shared_ptr<safe::signal_t> shutdown_event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int save_user_creds(const std::string &file, const std::string &username, const std::string &password, const std::string &salt) {
|
int save_user_creds(const std::string &file, const std::string &username, const std::string &password, bool run_our_mouth) {
|
||||||
pt::ptree outputTree;
|
pt::ptree outputTree;
|
||||||
|
|
||||||
if(fs::exists(file)) {
|
if(fs::exists(file)) {
|
||||||
@@ -77,7 +77,8 @@ int save_user_creds(const std::string &file, const std::string &username, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
outputTree.put("username", "sunshine");
|
auto salt = crypto::rand_alphabet(16);
|
||||||
|
outputTree.put("username", username);
|
||||||
outputTree.put("salt", salt);
|
outputTree.put("salt", salt);
|
||||||
outputTree.put("password", util::hex(crypto::hash(password + salt)).to_string());
|
outputTree.put("password", util::hex(crypto::hash(password + salt)).to_string());
|
||||||
try {
|
try {
|
||||||
@@ -89,8 +90,11 @@ int save_user_creds(const std::string &file, const std::string &username, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG(info) << "New credentials have been created"sv;
|
BOOST_LOG(info) << "New credentials have been created"sv;
|
||||||
|
|
||||||
|
if(run_our_mouth) {
|
||||||
BOOST_LOG(info) << "Username: "sv << username;
|
BOOST_LOG(info) << "Username: "sv << username;
|
||||||
BOOST_LOG(info) << "Password: "sv << password;
|
BOOST_LOG(info) << "Password: "sv << password;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,12 @@ namespace http {
|
|||||||
|
|
||||||
void init(std::shared_ptr<safe::signal_t> shutdown_event);
|
void init(std::shared_ptr<safe::signal_t> shutdown_event);
|
||||||
int create_creds(const std::string &pkey, const std::string &cert);
|
int create_creds(const std::string &pkey, const std::string &cert);
|
||||||
int save_user_creds(const std::string &file, const std::string &username, const std::string &password, const std::string &salt);
|
int save_user_creds(
|
||||||
|
const std::string &file,
|
||||||
|
const std::string &username,
|
||||||
|
const std::string &password,
|
||||||
|
bool run_our_mouth = false);
|
||||||
|
|
||||||
int reload_user_creds(const std::string &file);
|
int reload_user_creds(const std::string &file);
|
||||||
extern std::string unique_id;
|
extern std::string unique_id;
|
||||||
extern net::net_e origin_pin_allowed;
|
extern net::net_e origin_pin_allowed;
|
||||||
|
|||||||
+56
-1
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <boost/log/attributes/clock.hpp>
|
#include <boost/log/attributes/clock.hpp>
|
||||||
#include <boost/log/common.hpp>
|
#include <boost/log/common.hpp>
|
||||||
@@ -52,6 +52,27 @@ struct NoDelete {
|
|||||||
|
|
||||||
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
|
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", int)
|
||||||
|
|
||||||
|
void print_help(const char *name) {
|
||||||
|
std::cout
|
||||||
|
<< "Usage: "sv << name << " [options] [/path/to/configuration_file] [--cmd]"sv << std::endl
|
||||||
|
<< " Any configurable option can be overwritten with: \"name=value\""sv << std::endl
|
||||||
|
<< std::endl
|
||||||
|
<< " --help | print help"sv << std::endl
|
||||||
|
<< " --creds username password | set user credentials for the Web manager" << std::endl
|
||||||
|
<< std::endl
|
||||||
|
<< " flags"sv << std::endl
|
||||||
|
<< " -0 | Read PIN from stdin"sv << std::endl
|
||||||
|
<< " -1 | Do not load previously saved state and do retain any state after shutdown"sv << std::endl
|
||||||
|
<< " | Effectively starting as if for the first time without overwriting any pairings with your devices"sv << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace help {
|
||||||
|
int entry(const char *name, int argc, char *argv[]) {
|
||||||
|
print_help(name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace help
|
||||||
|
|
||||||
void log_flush() {
|
void log_flush() {
|
||||||
sink->flush();
|
sink->flush();
|
||||||
}
|
}
|
||||||
@@ -68,6 +89,24 @@ void on_signal(int sig, FN &&fn) {
|
|||||||
std::signal(sig, on_signal_forwarder);
|
std::signal(sig, on_signal_forwarder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace gen_creds {
|
||||||
|
int entry(const char *name, int argc, char *argv[]) {
|
||||||
|
if(argc < 2 || argv[0] == "help"sv || argv[1] == "help"sv) {
|
||||||
|
print_help(name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
http::save_user_creds(config::sunshine.credentials_file, argv[0], argv[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} // namespace gen_creds
|
||||||
|
|
||||||
|
std::map<std::string_view, std::function<int(const char *name, int argc, char **argv)>> cmd_to_func {
|
||||||
|
{ "creds"sv, gen_creds::entry },
|
||||||
|
{ "help"sv, help::entry }
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if(config::parse(argc, argv)) {
|
if(config::parse(argc, argv)) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -123,6 +162,22 @@ int main(int argc, char *argv[]) {
|
|||||||
bl::core::get()->add_sink(sink);
|
bl::core::get()->add_sink(sink);
|
||||||
auto fg = util::fail_guard(log_flush);
|
auto fg = util::fail_guard(log_flush);
|
||||||
|
|
||||||
|
if(!config::sunshine.cmd.name.empty()) {
|
||||||
|
auto fn = cmd_to_func.find(config::sunshine.cmd.name);
|
||||||
|
if(fn == std::end(cmd_to_func)) {
|
||||||
|
BOOST_LOG(fatal) << "Unknown command: "sv << config::sunshine.cmd.name;
|
||||||
|
|
||||||
|
BOOST_LOG(info) << "Possible commands:"sv;
|
||||||
|
for(auto &[key, _] : cmd_to_func) {
|
||||||
|
BOOST_LOG(info) << '\t' << key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fn->second(argv[0], config::sunshine.cmd.argc, config::sunshine.cmd.argv);
|
||||||
|
}
|
||||||
|
|
||||||
// Create signal handler after logging has been initialized
|
// Create signal handler after logging has been initialized
|
||||||
auto shutdown_event = std::make_shared<safe::event_t<bool>>();
|
auto shutdown_event = std::make_shared<safe::event_t<bool>>();
|
||||||
on_signal(SIGINT, [shutdown_event]() {
|
on_signal(SIGINT, [shutdown_event]() {
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ extern boost::log::sources::severity_logger<int> fatal;
|
|||||||
|
|
||||||
void log_flush();
|
void log_flush();
|
||||||
|
|
||||||
|
void print_help(const char *name);
|
||||||
|
|
||||||
std::string read_file(const char *path);
|
std::string read_file(const char *path);
|
||||||
int write_file(const char *path, const std::string_view &contents);
|
int write_file(const char *path, const std::string_view &contents);
|
||||||
#endif //SUNSHINE_MAIN_H
|
#endif //SUNSHINE_MAIN_H
|
||||||
|
|||||||
Reference in New Issue
Block a user