[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.";
|
||||
}
|
||||
|
||||
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. */
|
||||
current_dir->children.erase(it); /* Remove from map. */
|
||||
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";
|
||||
}
|
||||
|
||||
if(!has_permission(parent_dir, context, WRITE_PERM)) {
|
||||
return "write: cannot create file '" + path + "': Permission denied";
|
||||
}
|
||||
|
||||
auto it = parent_dir->children.find(filename);
|
||||
if(it != parent_dir->children.end()) {
|
||||
if(it->second->type == DIR_NODE) {
|
||||
@ -114,6 +123,10 @@ std::string create_executable(Session& context, const std::string& path,
|
||||
+ "': Not a directory";
|
||||
}
|
||||
|
||||
if(!has_permission(parent_dir, context, WRITE_PERM)) {
|
||||
return "create_executable: cannot create file '" + path + "': Permission denied";
|
||||
}
|
||||
|
||||
/* Overwrite if exists. */
|
||||
auto it = parent_dir->children.find(filename);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -142,6 +159,9 @@ std::string cd(Session& context, const std::string& path) {
|
||||
} else {
|
||||
auto it = current_dir->children.find(path);
|
||||
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);
|
||||
} else {
|
||||
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) {
|
||||
/*
|
||||
* 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->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);
|
||||
std::string deobfuscated_content = util::xor_string(command_node->content);
|
||||
sol::object result = lua.execute(deobfuscated_content, *this, args, is_remote);
|
||||
|
||||
@ -28,6 +28,9 @@ public:
|
||||
DatabaseManager* get_db_manager(void);
|
||||
MachineManager* get_machine_manager(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_session_machine(Machine* machine);
|
||||
|
||||
@ -1,6 +1,30 @@
|
||||
#include <sstream>
|
||||
|
||||
#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. */
|
||||
vfs_node* new_node(std::string name, vfs_node_type type, vfs_node* parent,
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class Session;
|
||||
struct vfs_node;
|
||||
|
||||
/* Store children for quick lookup by name. */
|
||||
@ -33,6 +34,11 @@ struct vfs_node {
|
||||
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,
|
||||
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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user