[Add] Enforce file permissions.
This commit is contained in:
parent
d852d8449f
commit
4057e0f876
@ -27,6 +27,11 @@ std::string rm(Session& context, const std::string& filename) {
|
|||||||
return "rm: cannot remove '" + filename + "': Is a directory.";
|
return "rm: cannot remove '" + filename + "': Is a directory.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfs_node* parent_dir = it->second->parent;
|
||||||
|
if(parent_dir && !has_permission(parent_dir, context, WRITE_PERM)) {
|
||||||
|
return "rm: cannot remove '" + filename + "': Permission denied";
|
||||||
|
}
|
||||||
|
|
||||||
delete it->second; /* Free the memory for the node. */
|
delete it->second; /* Free the memory for the node. */
|
||||||
current_dir->children.erase(it); /* Remove from map. */
|
current_dir->children.erase(it); /* Remove from map. */
|
||||||
return "";
|
return "";
|
||||||
@ -65,6 +70,10 @@ std::string write_file(Session& context, const std::string& path,
|
|||||||
return "write: cannot create file in '" + get_full_path(parent_dir) + "': Not a directory";
|
return "write: cannot create file in '" + get_full_path(parent_dir) + "': Not a directory";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!has_permission(parent_dir, context, WRITE_PERM)) {
|
||||||
|
return "write: cannot create file '" + path + "': Permission denied";
|
||||||
|
}
|
||||||
|
|
||||||
auto it = parent_dir->children.find(filename);
|
auto it = parent_dir->children.find(filename);
|
||||||
if(it != parent_dir->children.end()) {
|
if(it != parent_dir->children.end()) {
|
||||||
if(it->second->type == DIR_NODE) {
|
if(it->second->type == DIR_NODE) {
|
||||||
@ -114,6 +123,10 @@ std::string create_executable(Session& context, const std::string& path,
|
|||||||
+ "': Not a directory";
|
+ "': Not a directory";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!has_permission(parent_dir, context, WRITE_PERM)) {
|
||||||
|
return "create_executable: cannot create file '" + path + "': Permission denied";
|
||||||
|
}
|
||||||
|
|
||||||
/* Overwrite if exists. */
|
/* Overwrite if exists. */
|
||||||
auto it = parent_dir->children.find(filename);
|
auto it = parent_dir->children.find(filename);
|
||||||
if(it != parent_dir->children.end()) {
|
if(it != parent_dir->children.end()) {
|
||||||
@ -129,6 +142,10 @@ std::string create_executable(Session& context, const std::string& path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string read_file(Session& context, const std::string& path) {
|
std::string read_file(Session& context, const std::string& path) {
|
||||||
|
vfs_node* node = find_node_by_path(context.get_session_machine()->vfs_root, path);
|
||||||
|
if(node && !has_permission(node, context, READ_PERM)) {
|
||||||
|
return "cat: " + path + ": Permission denied";
|
||||||
|
}
|
||||||
return context.read_file(path);
|
return context.read_file(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +159,9 @@ std::string cd(Session& context, const std::string& path) {
|
|||||||
} else {
|
} else {
|
||||||
auto it = current_dir->children.find(path);
|
auto it = current_dir->children.find(path);
|
||||||
if(it != current_dir->children.end() && it->second->type == DIR_NODE) {
|
if(it != current_dir->children.end() && it->second->type == DIR_NODE) {
|
||||||
|
if(!has_permission(it->second, context, EXEC_PERM)) {
|
||||||
|
return "cd: " + path + ": Permission denied";
|
||||||
|
}
|
||||||
context.set_current_dir(it->second);
|
context.set_current_dir(it->second);
|
||||||
} else {
|
} else {
|
||||||
return "cd: no such file or directory: " + path;
|
return "cd: no such file or directory: " + path;
|
||||||
|
|||||||
@ -70,6 +70,14 @@ void Session::set_session_machine(Machine* machine) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t Session::get_current_uid(void) {
|
||||||
|
return _home_machine->owner_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Session::get_current_gid(void) {
|
||||||
|
return _home_machine->owner_id;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Session::process_command(const std::string& command) {
|
std::string Session::process_command(const std::string& command) {
|
||||||
/*
|
/*
|
||||||
* Creating the Lua processor on-demand to ensure it exists on the same
|
* Creating the Lua processor on-demand to ensure it exists on the same
|
||||||
@ -113,6 +121,9 @@ std::string Session::process_command(const std::string& command) {
|
|||||||
|
|
||||||
if(command_node) {
|
if(command_node) {
|
||||||
if(command_node->type == EXEC_NODE) {
|
if(command_node->type == EXEC_NODE) {
|
||||||
|
if(!has_permission(command_node, *this, EXEC_PERM)) {
|
||||||
|
return "Cannot execute '" + command_name + "': Permission denied.";
|
||||||
|
}
|
||||||
bool is_remote = (_session_machine != _home_machine);
|
bool is_remote = (_session_machine != _home_machine);
|
||||||
std::string deobfuscated_content = util::xor_string(command_node->content);
|
std::string deobfuscated_content = util::xor_string(command_node->content);
|
||||||
sol::object result = lua.execute(deobfuscated_content, *this, args, is_remote);
|
sol::object result = lua.execute(deobfuscated_content, *this, args, is_remote);
|
||||||
|
|||||||
@ -29,6 +29,9 @@ public:
|
|||||||
MachineManager* get_machine_manager(void);
|
MachineManager* get_machine_manager(void);
|
||||||
INetworkBridge* get_network_bridge(void);
|
INetworkBridge* get_network_bridge(void);
|
||||||
|
|
||||||
|
uint32_t get_current_uid(void);
|
||||||
|
uint32_t get_current_gid(void);
|
||||||
|
|
||||||
void set_current_dir(vfs_node* node);
|
void set_current_dir(vfs_node* node);
|
||||||
void set_session_machine(Machine* machine);
|
void set_session_machine(Machine* machine);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,30 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
bool has_permission(vfs_node* node, Session& context, uint8_t required_perm) {
|
||||||
|
uint32_t uid = context.get_current_uid();
|
||||||
|
if(uid == 0) { /* Root user. */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t gid = context.get_current_gid();
|
||||||
|
uint16_t perms = node->permissions;
|
||||||
|
|
||||||
|
if(node->owner_id == uid) {
|
||||||
|
/* Check owner permissions. */
|
||||||
|
return ((perms >> 6) & required_perm) == required_perm;
|
||||||
|
} else if(node->group_id == gid) {
|
||||||
|
/* Check group permissions. */
|
||||||
|
return ((perms >> 3) & required_perm) == required_perm;
|
||||||
|
} else {
|
||||||
|
/* Check other permissions. */
|
||||||
|
return (perms & required_perm) == required_perm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a new node. */
|
/* Create a new node. */
|
||||||
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent,
|
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent,
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
class Session;
|
||||||
struct vfs_node;
|
struct vfs_node;
|
||||||
|
|
||||||
/* Store children for quick lookup by name. */
|
/* Store children for quick lookup by name. */
|
||||||
@ -33,6 +34,11 @@ struct vfs_node {
|
|||||||
vfs_node* parent;
|
vfs_node* parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t READ_PERM = 4;
|
||||||
|
const uint8_t WRITE_PERM = 2;
|
||||||
|
const uint8_t EXEC_PERM = 1;
|
||||||
|
|
||||||
|
bool has_permission(vfs_node* node, Session& context, uint8_t required_perm);
|
||||||
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent,
|
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent,
|
||||||
uint32_t owner_id = 0, uint32_t group_id = 0, uint16_t permissions=0755);
|
uint32_t owner_id = 0, uint32_t group_id = 0, uint16_t permissions=0755);
|
||||||
vfs_node* find_node_by_id(vfs_node* root, long long id);
|
vfs_node* find_node_by_id(vfs_node* root, long long id);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user