Skip to content

Commit

Permalink
Merge branch 'permission-system'
Browse files Browse the repository at this point in the history
  • Loading branch information
ClassicOldSong committed Sep 16, 2024
2 parents 80ea11b + db5790b commit a482029
Show file tree
Hide file tree
Showing 23 changed files with 1,075 additions and 245 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
branch = sdk
[submodule "third-party/Simple-Web-Server"]
path = third-party/Simple-Web-Server
url = https://gitlab.com/eidheim/Simple-Web-Server.git
url = https://github.com/ClassicOldSong/Simple-Web-Server
branch = master
[submodule "third-party/TPCircularBuffer"]
path = third-party/TPCircularBuffer
Expand Down
63 changes: 63 additions & 0 deletions src/confighttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,38 @@ namespace confighttp {
outputTree.put("status", true);
}

void
updateClient(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;

print_req(request);

std::stringstream ss;
ss << request->content.rdbuf();

pt::ptree inputTree, outputTree;

auto g = util::fail_guard([&]() {
std::ostringstream data;
pt::write_json(data, outputTree);
response->write(data.str());
});

try {
pt::read_json(ss, inputTree);
std::string uuid = inputTree.get<std::string>("uuid");
std::string name = inputTree.get<std::string>("name");
auto perm = (crypto::PERM)inputTree.get<uint32_t>("perm") & crypto::PERM::_all;
outputTree.put("status", nvhttp::update_device_info(uuid, name, perm));
}
catch (std::exception &e) {
BOOST_LOG(warning) << "Update Client: "sv << e.what();
outputTree.put("status", false);
outputTree.put("error", e.what());
return;
}
}

void
unpair(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
Expand Down Expand Up @@ -897,6 +929,35 @@ namespace confighttp {
}
}

void
disconnect(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;

print_req(request);

std::stringstream ss;
ss << request->content.rdbuf();

pt::ptree inputTree, outputTree;

auto g = util::fail_guard([&]() {
std::ostringstream data;
pt::write_json(data, outputTree);
response->write(data.str());
});

try {
pt::read_json(ss, inputTree);
std::string uuid = inputTree.get<std::string>("uuid");
outputTree.put("status", nvhttp::find_and_stop_session(uuid, true));
}
catch (std::exception &e) {
BOOST_LOG(warning) << "Disconnect: "sv << e.what();
outputTree.put("status", false);
outputTree.put("error", e.what());
}
}

void
listClients(resp_https_t response, req_https_t request) {
if (!authenticate(response, request)) return;
Expand Down Expand Up @@ -969,7 +1030,9 @@ namespace confighttp {
server.resource["^/api/apps/([0-9]+)$"]["DELETE"] = deleteApp;
server.resource["^/api/clients/unpair-all$"]["POST"] = unpairAll;
server.resource["^/api/clients/list$"]["GET"] = listClients;
server.resource["^/api/clients/update$"]["POST"] = updateClient;
server.resource["^/api/clients/unpair$"]["POST"] = unpair;
server.resource["^/api/clients/disconnect$"]["POST"] = disconnect;
server.resource["^/api/apps/close$"]["POST"] = closeApp;
server.resource["^/api/covers/upload$"]["POST"] = uploadCover;
server.resource["^/images/apollo.ico$"]["GET"] = getFaviconImage;
Expand Down
11 changes: 6 additions & 5 deletions src/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ namespace crypto {
cert_chain_t::cert_chain_t():
_certs {}, _cert_ctx { X509_STORE_CTX_new() } {}
void
cert_chain_t::add(x509_t &&cert) {
cert_chain_t::add(p_named_cert_t& named_cert_p) {
x509_store_t x509_store { X509_STORE_new() };

X509_STORE_add_cert(x509_store.get(), cert.get());
_certs.emplace_back(std::make_pair(std::move(cert), std::move(x509_store)));
X509_STORE_add_cert(x509_store.get(), x509(named_cert_p->cert).get());
_certs.emplace_back(std::make_pair(named_cert_p, std::move(x509_store)));
}
void
cert_chain_t::clear() {
Expand Down Expand Up @@ -52,9 +52,9 @@ namespace crypto {
* @return nullptr if the certificate is valid, otherwise an error string.
*/
const char *
cert_chain_t::verify(x509_t::element_type *cert) {
cert_chain_t::verify(x509_t::element_type *cert, p_named_cert_t& named_cert_out) {
int err_code = 0;
for (auto &[_, x509_store] : _certs) {
for (auto &[named_cert_p, x509_store] : _certs) {
auto fg = util::fail_guard([this]() {
X509_STORE_CTX_cleanup(_cert_ctx.get());
});
Expand All @@ -70,6 +70,7 @@ namespace crypto {
auto err = X509_verify_cert(_cert_ctx.get());

if (err == 1) {
named_cert_out = named_cert_p;
return nullptr;
}

Expand Down
58 changes: 55 additions & 3 deletions src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,58 @@ namespace crypto {
using pkey_ctx_t = util::safe_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_free>;
using bignum_t = util::safe_ptr<BIGNUM, BN_free>;

/**
* @brief The permissions of a client.
*/
enum class PERM: uint32_t {
_reserved = 1,

_input = _reserved << 8, // Input permission group
input_controller = _input << 0, // Allow controller input
input_touch = _input << 1, // Allow touch input
input_pen = _input << 2, // Allow pen input
input_kbdm = _input << 3, // Allow kbd/mouse input
_all_inputs = input_controller | input_touch | input_pen | input_kbdm,

_operation = _input << 8, // Operation permission group
clipboard_set = _operation << 0, // Allow set clipboard from client
clipboard_read = _operation << 1, // Allow read clipboard from host
file_upload = _operation << 2, // Allow upload files to host
file_dwnload = _operation << 3, // Allow download files from host
server_cmd = _operation << 4, // Allow execute server cmd
_all_opeiations = clipboard_set | clipboard_read | file_upload | file_dwnload | server_cmd,

_action = _operation << 8, // Action permission group
list = _action << 0, // Allow list apps
view = _action << 1, // Allow view streams
launch = _action << 2, // Allow launch apps
_allow_view = view | launch, // If no view permission is granted, disconnect the device upon permission update
_all_actions = list | view | launch,

_default = view | list, // Default permissions for new clients
_no = 0, // No permissions are granted
_all = _all_inputs | _all_opeiations | _all_actions, // All current permissions
};

inline constexpr PERM
operator&(PERM x, PERM y) {
return static_cast<PERM>(static_cast<uint32_t>(x) & static_cast<uint32_t>(y));
}

inline constexpr bool
operator!(PERM p) {
return static_cast<uint32_t>(p) == 0;
}

struct named_cert_t {
std::string name;
std::string uuid;
std::string cert;
PERM perm;
};

using p_named_cert_t = std::shared_ptr<named_cert_t>;

/**
* @brief Hashes the given plaintext using SHA-256.
* @param plaintext
Expand Down Expand Up @@ -76,16 +128,16 @@ namespace crypto {
KITTY_DECL_CONSTR(cert_chain_t)

void
add(x509_t &&cert);
add(p_named_cert_t& named_cert_p);

void
clear();

const char *
verify(x509_t::element_type *cert);
verify(x509_t::element_type *cert, p_named_cert_t& named_cert_out);

private:
std::vector<std::pair<x509_t, x509_store_t>> _certs;
std::vector<std::pair<p_named_cert_t, x509_store_t>> _certs;
x509_store_ctx_t _cert_ctx;
};

Expand Down
56 changes: 55 additions & 1 deletion src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,61 @@ namespace input {
* @param input_data The input message.
*/
void
passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data) {
passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data, const crypto::PERM& permission) {
// No input permissions at all
if (!(permission & crypto::PERM::_all_inputs)) {
return;
}

// Have some input permission
// Otherwise have all input permission
if ((permission & crypto::PERM::_all_inputs) != crypto::PERM::_all_inputs) {
PNV_INPUT_HEADER payload = (PNV_INPUT_HEADER)input_data.data();

// Check permission
switch (util::endian::little(payload->magic)) {
case MULTI_CONTROLLER_MAGIC_GEN5:
case SS_CONTROLLER_ARRIVAL_MAGIC:
case SS_CONTROLLER_TOUCH_MAGIC:
case SS_CONTROLLER_MOTION_MAGIC:
case SS_CONTROLLER_BATTERY_MAGIC:
if (!(permission & crypto::PERM::input_controller)) {
return;
} else {
break;
}
case MOUSE_MOVE_REL_MAGIC_GEN5:
case MOUSE_MOVE_ABS_MAGIC:
case MOUSE_BUTTON_DOWN_EVENT_MAGIC_GEN5:
case MOUSE_BUTTON_UP_EVENT_MAGIC_GEN5:
case SCROLL_MAGIC_GEN5:
case SS_HSCROLL_MAGIC:
case KEY_DOWN_EVENT_MAGIC:
case KEY_UP_EVENT_MAGIC:
case UTF8_TEXT_EVENT_MAGIC:
if (!(permission & crypto::PERM::input_kbdm)) {
return;
} else {
break;
}
case SS_TOUCH_MAGIC:
if (!(permission & crypto::PERM::input_touch)) {
return;
} else {
break;
}
case SS_PEN_MAGIC:
if (!(permission & crypto::PERM::input_pen)) {
return;
} else {
break;
}
default:
// Unknown input event
return;
}
}

{
std::lock_guard<std::mutex> lg(input->input_queue_lock);
input->input_queue.push_back(std::move(input_data));
Expand Down
3 changes: 2 additions & 1 deletion src/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "platform/common.h"
#include "thread_safe.h"
#include "crypto.h"

namespace input {
struct input_t;
Expand All @@ -17,7 +18,7 @@ namespace input {
void
reset(std::shared_ptr<input_t> &input);
void
passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data);
passthrough(std::shared_ptr<input_t> &input, std::vector<std::uint8_t> &&input_data, const crypto::PERM& permission);

[[nodiscard]] std::unique_ptr<platf::deinit_t>
init();
Expand Down
Loading

0 comments on commit a482029

Please sign in to comment.