Configure prevention pairing over non-private network
This commit is contained in:
@@ -79,6 +79,8 @@ set(SUNSHINE_TARGET_FILES
|
|||||||
sunshine/platform/common.h
|
sunshine/platform/common.h
|
||||||
sunshine/process.cpp
|
sunshine/process.cpp
|
||||||
sunshine/process.h
|
sunshine/process.h
|
||||||
|
sunshine/network.cpp
|
||||||
|
sunshine/network.h
|
||||||
sunshine/move_by_copy.h
|
sunshine/move_by_copy.h
|
||||||
sunshine/task_pool.h
|
sunshine/task_pool.h
|
||||||
sunshine/thread_pool.h
|
sunshine/thread_pool.h
|
||||||
|
|||||||
Submodule Simple-Web-Server updated: e70509e078...f4b7101ad3
@@ -10,6 +10,15 @@
|
|||||||
# The name displayed by Moonlight
|
# The name displayed by Moonlight
|
||||||
# sunshine_name = sunshine
|
# 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
|
# Pretty self-explanatory
|
||||||
unique_id = 03904e64-51da-4fb3-9afd-a9f7ff70fea4
|
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
|
# 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
|
# 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
|
# 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
|
# The back/select button on the controller
|
||||||
@@ -39,7 +48,7 @@ fec_percentage = 1
|
|||||||
# FFmpeg software encoding parameters
|
# FFmpeg software encoding parameters
|
||||||
# Honestly, I have no idea what the optimal values would be.
|
# Honestly, I have no idea what the optimal values would be.
|
||||||
# Play around with this :)
|
# Play around with this :)
|
||||||
max_b_frames = 16
|
max_b_frames = 4
|
||||||
gop_size = 24
|
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
|
# 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 {
|
nvhttp_t nvhttp {
|
||||||
|
"lan", // origin_pin
|
||||||
PRIVATE_KEY_FILE,
|
PRIVATE_KEY_FILE,
|
||||||
CERTIFICATE_FILE,
|
CERTIFICATE_FILE,
|
||||||
|
|
||||||
"sunshine", // sunshine_name
|
"sunshine"s, // sunshine_name,
|
||||||
"03904e64-51da-4fb3-9afd-a9f7ff70fea4", // unique_id
|
"03904e64-51da-4fb3-9afd-a9f7ff70fea4"s, // unique_id
|
||||||
"devices.json" // file_devices
|
"devices.json"s // file_devices
|
||||||
};
|
};
|
||||||
|
|
||||||
input_t input {
|
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);
|
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) {
|
void int_f(std::unordered_map<std::string, std::string> &vars, const std::string &name, int &input) {
|
||||||
auto it = vars.find(name);
|
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, "file_devices", nvhttp.file_devices);
|
||||||
string_f(vars, "external_ip", nvhttp.external_ip);
|
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 to = -1;
|
||||||
int_f(vars, "ping_timeout", to);
|
int_f(vars, "ping_timeout", to);
|
||||||
if(to > 0) {
|
if(to > 0) {
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ struct stream_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct nvhttp_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 pkey; // must be 2048 bits
|
||||||
std::string cert; // must be signed with a key of 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 "nvhttp.h"
|
||||||
#include "platform/common.h"
|
#include "platform/common.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
|
#include "network.h"
|
||||||
|
|
||||||
|
|
||||||
namespace nvhttp {
|
namespace nvhttp {
|
||||||
@@ -37,7 +38,6 @@ namespace pt = boost::property_tree;
|
|||||||
|
|
||||||
std::string read_file(const char *path);
|
std::string read_file(const char *path);
|
||||||
|
|
||||||
std::string local_ip;
|
|
||||||
using https_server_t = SimpleWeb::Server<SimpleWeb::HTTPS>;
|
using https_server_t = SimpleWeb::Server<SimpleWeb::HTTPS>;
|
||||||
using http_server_t = SimpleWeb::Server<SimpleWeb::HTTP>;
|
using http_server_t = SimpleWeb::Server<SimpleWeb::HTTP>;
|
||||||
|
|
||||||
@@ -88,6 +88,8 @@ enum class op_e {
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::int64_t current_appid { -1 };
|
std::int64_t current_appid { -1 };
|
||||||
|
std::string local_ip;
|
||||||
|
net::net_e origin_pin_allowed;
|
||||||
|
|
||||||
void save_devices() {
|
void save_devices() {
|
||||||
pt::ptree root;
|
pt::ptree root;
|
||||||
@@ -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) {
|
void pin(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> response, std::shared_ptr<typename SimpleWeb::ServerBase<T>::Request> request) {
|
||||||
print_req<T>(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;
|
pt::ptree tree;
|
||||||
|
|
||||||
auto &sess = std::begin(map_id_sess)->second;
|
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);
|
pt::write_xml(data, tree);
|
||||||
|
|
||||||
auto &async_response = sess.async_insert_pin.response;
|
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());
|
async_response.left()->write(data.str());
|
||||||
}
|
}
|
||||||
else {
|
else if(async_response.has_right() && async_response.right()){
|
||||||
async_response.right()->write(data.str());
|
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())>();
|
async_response = std::decay_t<decltype(async_response.left())>();
|
||||||
// response to the current request
|
// response to the current request
|
||||||
response->write(""s);
|
response->write(SimpleWeb::StatusCode::success_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@@ -631,6 +649,8 @@ void appasset(resp_https_t response, req_https_t request) {
|
|||||||
|
|
||||||
void start() {
|
void start() {
|
||||||
local_ip = platf::get_local_ip();
|
local_ip = platf::get_local_ip();
|
||||||
|
origin_pin_allowed = net::from_enum_string(config::nvhttp.origin_pin_allowed);
|
||||||
|
|
||||||
if(local_ip.empty()) {
|
if(local_ip.empty()) {
|
||||||
std::cout << "Error: Could not determine the local ip-address"sv << std::endl;
|
std::cout << "Error: Could not determine the local ip-address"sv << std::endl;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user