Configure prevention pairing over non-private network
This commit is contained in:
parent
b054adae06
commit
b3ae81cb3a
8 changed files with 195 additions and 11 deletions
|
|
@ -79,6 +79,8 @@ set(SUNSHINE_TARGET_FILES
|
|||
sunshine/platform/common.h
|
||||
sunshine/process.cpp
|
||||
sunshine/process.h
|
||||
sunshine/network.cpp
|
||||
sunshine/network.h
|
||||
sunshine/move_by_copy.h
|
||||
sunshine/task_pool.h
|
||||
sunshine/thread_pool.h
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit e70509e078ade2eb9679862ab6a48b4ee2fefb66
|
||||
Subproject commit f4b7101ad369f56423291d6ac39ebf61a6518298
|
||||
|
|
@ -10,6 +10,15 @@
|
|||
# The name displayed by Moonlight
|
||||
# sunshine_name = sunshine
|
||||
|
||||
# The origin of the remote endpoint address that is not denied for HTTP method /pin
|
||||
# Could be any of the following values:
|
||||
# pc|lan|wan
|
||||
# pc: Only localhost may access /pin
|
||||
# lan: Only those in LAN may access /pin
|
||||
# wan: Anyone may access /pin
|
||||
#
|
||||
# origin_pin_allowed = lan
|
||||
|
||||
# Pretty self-explanatory
|
||||
unique_id = 03904e64-51da-4fb3-9afd-a9f7ff70fea4
|
||||
|
||||
|
|
@ -25,7 +34,7 @@ ping_timeout = 2000
|
|||
# How much error correcting packets must be send for every video max_b_frames
|
||||
# This is just some random number, don't know the optimal value
|
||||
# The higher fec_percentage, the lower space for the actual data to send per frame there is
|
||||
fec_percentage = 1
|
||||
fec_percentage = 10
|
||||
|
||||
|
||||
# The back/select button on the controller
|
||||
|
|
@ -39,7 +48,7 @@ fec_percentage = 1
|
|||
# FFmpeg software encoding parameters
|
||||
# Honestly, I have no idea what the optimal values would be.
|
||||
# Play around with this :)
|
||||
max_b_frames = 16
|
||||
max_b_frames = 4
|
||||
gop_size = 24
|
||||
|
||||
# Constant Rate Factor. Between 1 and 52. It allows QP to go up during motion and down with still image, resulting in constant perceived quality
|
||||
|
|
|
|||
|
|
@ -36,12 +36,13 @@ stream_t stream {
|
|||
};
|
||||
|
||||
nvhttp_t nvhttp {
|
||||
"lan", // origin_pin
|
||||
PRIVATE_KEY_FILE,
|
||||
CERTIFICATE_FILE,
|
||||
|
||||
"sunshine", // sunshine_name
|
||||
"03904e64-51da-4fb3-9afd-a9f7ff70fea4", // unique_id
|
||||
"devices.json" // file_devices
|
||||
"sunshine"s, // sunshine_name,
|
||||
"03904e64-51da-4fb3-9afd-a9f7ff70fea4"s, // unique_id
|
||||
"devices.json"s // file_devices
|
||||
};
|
||||
|
||||
input_t input {
|
||||
|
|
@ -102,6 +103,32 @@ void string_f(std::unordered_map<std::string, std::string> &vars, const std::str
|
|||
input = std::move(it->second);
|
||||
}
|
||||
|
||||
void string_restricted_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, std::string &input, const std::vector<std::string_view> &allowed_vals) {
|
||||
std::string temp;
|
||||
string_f(vars, name, temp);
|
||||
|
||||
for(auto &allowed_val : allowed_vals) {
|
||||
if(temp == allowed_val) {
|
||||
input = std::move(temp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void int_restricted_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input, const std::vector<std::string_view> &allowed_vals) {
|
||||
std::string temp;
|
||||
string_f(vars, name, temp);
|
||||
|
||||
for(int x = 0; x < allowed_vals.size(); ++x) {
|
||||
auto &allowed_val = allowed_vals[x];
|
||||
|
||||
if(temp == allowed_val) {
|
||||
input = x;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input) {
|
||||
auto it = vars.find(name);
|
||||
|
||||
|
|
@ -142,6 +169,10 @@ void parse_file(const char *file) {
|
|||
string_f(vars, "file_devices", nvhttp.file_devices);
|
||||
string_f(vars, "external_ip", nvhttp.external_ip);
|
||||
|
||||
string_restricted_f(vars, "origin_pin_allowed", nvhttp.origin_pin_allowed, {
|
||||
"pc"sv, "lan"sv, "wan"sv
|
||||
});
|
||||
|
||||
int to = -1;
|
||||
int_f(vars, "ping_timeout", to);
|
||||
if(to > 0) {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ struct stream_t {
|
|||
};
|
||||
|
||||
struct nvhttp_t {
|
||||
// Could be any of the following values:
|
||||
// pc|lan|wan
|
||||
std::string origin_pin_allowed;
|
||||
|
||||
std::string pkey; // must be 2048 bits
|
||||
std::string cert; // must be signed with a key of 2048 bits
|
||||
|
||||
|
|
|
|||
96
sunshine/network.cpp
Normal file
96
sunshine/network.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// Created by loki on 12/27/19.
|
||||
//
|
||||
|
||||
#include <algorithm>
|
||||
#include "network.h"
|
||||
#include "utility.h"
|
||||
|
||||
namespace net {
|
||||
using namespace std::literals;
|
||||
// In the format "xxx.xxx.xxx.xxx/x"
|
||||
std::pair<std::uint32_t, std::uint32_t> ip_block(const std::string_view &ip);
|
||||
|
||||
std::vector<std::pair<std::uint32_t, std::uint32_t>> pc_ips {
|
||||
ip_block("127.0.0.1/32"sv)
|
||||
};
|
||||
std::vector<std::tuple<std::uint32_t, std::uint32_t>> lan_ips {
|
||||
ip_block("192.168.0.0/16"sv),
|
||||
ip_block("172.16.0.0/12"),
|
||||
ip_block("10.0.0.0/8"sv)
|
||||
};
|
||||
|
||||
std::uint32_t ip(const std::string_view &ip_str) {
|
||||
auto begin = std::begin(ip_str);
|
||||
auto end = std::end(ip_str);
|
||||
auto temp_end = std::find(begin, end, '.');
|
||||
|
||||
std::uint32_t ip = 0;
|
||||
auto shift = 24;
|
||||
while(temp_end != end) {
|
||||
ip += (util::from_chars(begin, temp_end) << shift);
|
||||
shift -= 8;
|
||||
|
||||
begin = temp_end + 1;
|
||||
temp_end = std::find(begin, end, '.');
|
||||
}
|
||||
|
||||
ip += util::from_chars(begin, end);
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
// In the format "xxx.xxx.xxx.xxx/x"
|
||||
std::pair<std::uint32_t, std::uint32_t> ip_block(const std::string_view &ip_str) {
|
||||
auto begin = std::begin(ip_str);
|
||||
auto end = std::find(begin, std::end(ip_str), '/');
|
||||
|
||||
auto addr = ip({ begin, (std::size_t)(end - begin) });
|
||||
|
||||
auto bits = 32 - util::from_chars(end + 1, std::end(ip_str));
|
||||
|
||||
return { addr, addr + ((1 << bits) - 1) };
|
||||
}
|
||||
|
||||
net_e from_enum_string(const std::string_view &view) {
|
||||
if(view == "wan") {
|
||||
return WAN;
|
||||
}
|
||||
if(view == "lan") {
|
||||
return LAN;
|
||||
}
|
||||
|
||||
return PC;
|
||||
}
|
||||
net_e from_address(const std::string_view &view) {
|
||||
auto addr = ip(view);
|
||||
|
||||
for(auto [ip_low, ip_high] : pc_ips) {
|
||||
if(addr >= ip_low && addr <= ip_high) {
|
||||
return PC;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto [ip_low, ip_high] : lan_ips) {
|
||||
if(addr >= ip_low && addr <= ip_high) {
|
||||
return LAN;
|
||||
}
|
||||
}
|
||||
|
||||
return WAN;
|
||||
}
|
||||
|
||||
std::string_view to_enum_string(net_e net) {
|
||||
switch(net) {
|
||||
case PC:
|
||||
return "pc"sv;
|
||||
case LAN:
|
||||
return "lan"sv;
|
||||
case WAN:
|
||||
return "wan"sv;
|
||||
}
|
||||
|
||||
// avoid warning
|
||||
return "wan"sv;
|
||||
}
|
||||
}
|
||||
22
sunshine/network.h
Normal file
22
sunshine/network.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Created by loki on 12/27/19.
|
||||
//
|
||||
|
||||
#ifndef SUNSHINE_NETWORK_H
|
||||
#define SUNSHINE_NETWORK_H
|
||||
|
||||
#include <tuple>
|
||||
namespace net {
|
||||
enum net_e : int {
|
||||
PC,
|
||||
LAN,
|
||||
WAN
|
||||
};
|
||||
|
||||
net_e from_enum_string(const std::string_view &view);
|
||||
std::string_view to_enum_string(net_e net);
|
||||
|
||||
net_e from_address(const std::string_view &view);
|
||||
}
|
||||
|
||||
#endif //SUNSHINE_NETWORK_H
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
#include "nvhttp.h"
|
||||
#include "platform/common.h"
|
||||
#include "process.h"
|
||||
#include "network.h"
|
||||
|
||||
|
||||
namespace nvhttp {
|
||||
|
|
@ -37,7 +38,6 @@ namespace pt = boost::property_tree;
|
|||
|
||||
std::string read_file(const char *path);
|
||||
|
||||
std::string local_ip;
|
||||
using https_server_t = SimpleWeb::Server<SimpleWeb::HTTPS>;
|
||||
using http_server_t = SimpleWeb::Server<SimpleWeb::HTTP>;
|
||||
|
||||
|
|
@ -88,6 +88,8 @@ enum class op_e {
|
|||
};
|
||||
|
||||
std::int64_t current_appid { -1 };
|
||||
std::string local_ip;
|
||||
net::net_e origin_pin_allowed;
|
||||
|
||||
void save_devices() {
|
||||
pt::ptree root;
|
||||
|
|
@ -105,7 +107,7 @@ void save_devices() {
|
|||
cert_nodes.push_back(std::make_pair(""s, cert_node));
|
||||
}
|
||||
node.add_child("certs"s, cert_nodes);
|
||||
|
||||
|
||||
nodes.push_back(std::make_pair(""s, node));
|
||||
}
|
||||
|
||||
|
|
@ -374,6 +376,16 @@ template<class T>
|
|||
void pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
|
||||
print_req<T>(request);
|
||||
|
||||
auto address = request->remote_endpoint_address();
|
||||
auto ip_type = net::from_address(address);
|
||||
if(ip_type > origin_pin_allowed) {
|
||||
std::cout << '[' << address << "] -- denied"sv << std::endl;
|
||||
|
||||
response->write(SimpleWeb::StatusCode::client_error_forbidden);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
pt::ptree tree;
|
||||
|
||||
auto &sess = std::begin(map_id_sess)->second;
|
||||
|
|
@ -384,16 +396,22 @@ void pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response,
|
|||
pt::write_xml(data, tree);
|
||||
|
||||
auto &async_response = sess.async_insert_pin.response;
|
||||
if(async_response.left()) {
|
||||
if(async_response.has_left() && async_response.left()) {
|
||||
async_response.left()->write(data.str());
|
||||
}
|
||||
else {
|
||||
else if(async_response.has_right() && async_response.right()){
|
||||
async_response.right()->write(data.str());
|
||||
}
|
||||
else {
|
||||
response->write(SimpleWeb::StatusCode::client_error_im_a_teapot);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// reset async_response
|
||||
async_response = std::decay_t<decltype(async_response.left())>();
|
||||
// response to the current request
|
||||
response->write(""s);
|
||||
response->write(SimpleWeb::StatusCode::success_ok);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
|
|
@ -631,6 +649,8 @@ void appasset(resp_https_t response, req_https_t request) {
|
|||
|
||||
void start() {
|
||||
local_ip = platf::get_local_ip();
|
||||
origin_pin_allowed = net::from_enum_string(config::nvhttp.origin_pin_allowed);
|
||||
|
||||
if(local_ip.empty()) {
|
||||
std::cout << "Error: Could not determine the local ip-address"sv << std::endl;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue