Add flags for testing pairing

This commit is contained in:
loki 2020-03-19 19:59:27 +01:00
parent ad34fef228
commit ad87463784
5 changed files with 156 additions and 25 deletions

View File

@ -117,3 +117,14 @@
# See x264 --fullhelp for the different presets
# preset = superfast
# tune = zerolatency
#
#
##############################################
# Some configurable parameters, are merely toggles for specific features
# The first occurrence turns it on, the second occurence turns it off, the third occurence turns it on again, etc, etc
# Here, you change the default state of any flag
#
# To set the initial state of flags -0 and -1 to on, set the following flags:
# flags = 01
#
# See: sunshine --help for all options under the header: flags

View File

@ -53,7 +53,8 @@ input_t input {
};
sunshine_t sunshine {
2 // min_log_level
2, // min_log_level
0 // flags
};
bool whitespace(char ch) {
@ -74,7 +75,7 @@ std::optional<std::pair<std::string, std::string>> parse_line(std::string_view::
return std::nullopt;
}
auto end_name = std::find_if(std::make_reverse_iterator(eq - 1), std::make_reverse_iterator(begin), std::not_fn(whitespace)).base();
auto end_name = std::find_if(std::make_reverse_iterator(eq), std::make_reverse_iterator(begin), std::not_fn(whitespace)).base();
auto begin_val = std::find_if(eq + 1, end, std::not_fn(whitespace));
return std::pair { to_string(begin, end_name), to_string(begin_val, end) };
@ -148,15 +149,38 @@ void int_between_f(std::unordered_map<std::string, std::string> &vars, const std
}
}
void parse_file(const char *file) {
std::ifstream in(file);
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 read/write state to/from disk" << std::endl;
}
auto vars = parse_config(std::string {
// Quick and dirty
std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>()
});
int apply_flags(const char *line) {
int ret = 0;
while(*line != '\0') {
switch(*line) {
case '0':
config::sunshine.flags[config::flag::PIN_STDIN].flip();
break;
case '1':
config::sunshine.flags[config::flag::CLEAN_SLATE].flip();
break;
default:
std::cout << "Warning: Unrecognized flag: ["sv << *line << ']' << std::endl;
ret = -1;
}
++line;
}
return ret;
}
void apply_config(std::unordered_map<std::string, std::string> &&vars) {
for(auto &[name, val] : vars) {
std::cout << "["sv << name << "] -- ["sv << val << ']' << std::endl;
}
@ -191,7 +215,7 @@ void parse_file(const char *file) {
if(to != -1) {
stream.ping_timeout = std::chrono::milliseconds(to);
}
int_between_f(vars, "channels", stream.channels, {
1, std::numeric_limits<int>::max()
});
@ -237,6 +261,13 @@ void parse_file(const char *file) {
}
}
auto it = vars.find("flags"s);
if(it != std::end(vars)) {
apply_flags(it->second.c_str());
vars.erase(it);
}
if(sunshine.min_log_level <= 3) {
for(auto &[var,_] : vars) {
std::cout << "Warning: Unrecognized configurable option ["sv << var << ']' << std::endl;
@ -244,5 +275,63 @@ void parse_file(const char *file) {
}
}
int parse(int argc, char *argv[]) {
const char *config_file = SUNSHINE_ASSETS_DIR "/sunshine.conf";
std::unordered_map<std::string, std::string> cmd_vars;
for(auto x = argc -1; x > 0; --x) {
auto line = argv[x];
if(line == "--help"sv) {
print_help(*argv);
return 1;
}
else if(*line == '-') {
if(apply_flags(line + 1)) {
print_help(*argv);
return -1;
}
}
else {
auto line_end = line + strlen(line);
auto pos = std::find(line, line_end, '=');
if(pos == line_end) {
config_file = line;
}
else {
auto var = parse_line(line, line_end);
if(!var) {
print_help(*argv);
return -1;
}
cmd_vars.emplace(std::move(*var));
}
}
}
std::ifstream in { config_file };
if(!in.is_open()) {
std::cout << "Error: Couldn't open "sv << config_file << std::endl;
return -1;
}
auto vars = parse_config(std::string {
// Quick and dirty
std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>()
});
for(auto &var : cmd_vars) {
vars.emplace(std::move(var));
}
apply_config(std::move(vars));
return 0;
}
}

View File

@ -3,6 +3,7 @@
#include <chrono>
#include <string>
#include <bitset>
namespace config {
struct video_t {
@ -54,8 +55,18 @@ struct input_t {
std::chrono::milliseconds back_button_timeout;
};
namespace flag {
enum flag_e : std::size_t {
PIN_STDIN = 0, // Read PIN from stdin instead of http
CLEAN_SLATE, // Do not load or save state
FLAG_SIZE
};
}
struct sunshine_t {
int min_log_level;
std::bitset<flag::FLAG_SIZE> flags;
};
extern video_t video;
@ -65,7 +76,7 @@ extern nvhttp_t nvhttp;
extern input_t input;
extern sunshine_t sunshine;
void parse_file(const char *file);
int parse(int argc, char *argv[]);
}
#endif

View File

@ -64,16 +64,8 @@ void on_signal(int sig, FN &&fn) {
}
int main(int argc, char *argv[]) {
const char *config_file = SUNSHINE_ASSETS_DIR "/sunshine.conf";
if(argc > 1) {
config_file = argv[1];
}
if(!std::filesystem::exists(config_file)) {
std::cout << "Warning: Couldn't find configuration file ["sv << config_file << ']' << std::endl;
}
else {
config::parse_file(config_file);
if(config::parse(argc, argv)) {
return 0;
}
sink = boost::make_shared<text_sink>();

View File

@ -162,7 +162,9 @@ void update_id_client(const std::string &uniqueID, std::string &&cert, op_e op)
break;
}
save_state();
if(!config::sunshine.flags[config::flag::CLEAN_SLATE]) {
save_state();
}
}
void getservercert(pair_session_t &sess, pt::ptree &tree, const std::string &pin) {
@ -349,8 +351,20 @@ void pair(std::shared_ptr<safe::queue_t<crypto::x509_t>> &add_cert, std::shared_
auto ptr = map_id_sess.emplace(sess.client.uniqueID, std::move(sess)).first;
ptr->second.async_insert_pin.salt = std::move(args.at("salt"s));
ptr->second.async_insert_pin.response = std::move(response);
return;
if(config::sunshine.flags[config::flag::PIN_STDIN]) {
std::string pin;
std::cout << "Please insert pin: "sv;
std::getline(std::cin, pin);
getservercert(ptr->second, tree, pin);
}
else {
ptr->second.async_insert_pin.response = std::move(response);
return;
}
}
else if(it->second == "pairchallenge"sv) {
tree.put("root.paired", 1);
@ -710,6 +724,17 @@ int create_creds(const std::string &pkey, const std::string &cert) {
}
void start(std::shared_ptr<safe::signal_t> shutdown_event) {
bool clean_slate = config::sunshine.flags[config::flag::CLEAN_SLATE];
if(clean_slate) {
unique_id = util::uuid_t::generate().string();
auto dir = std::filesystem::temp_directory_path() / "Sushine"sv;
config::nvhttp.cert = dir / ("cert-"s + unique_id);
config::nvhttp.pkey = dir / ("pkey-"s + unique_id);
}
if(!fs::exists(config::nvhttp.pkey) || !fs::exists(config::nvhttp.cert)) {
if(create_creds(config::nvhttp.pkey, config::nvhttp.cert)) {
shutdown_event->raise(true);
@ -718,7 +743,10 @@ void start(std::shared_ptr<safe::signal_t> shutdown_event) {
}
origin_pin_allowed = net::from_enum_string(config::nvhttp.origin_pin_allowed);
load_state();
if(!clean_slate) {
load_state();
}
conf_intern.pkey = read_file(config::nvhttp.pkey.c_str());
conf_intern.servercert = read_file(config::nvhttp.cert.c_str());