mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-26 19:39:14 +00:00
feat: initial plugin auditing workflow
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#define slic3r_PluginAuditManager_hpp_
|
||||
|
||||
#include <Python.h>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -53,8 +54,8 @@ public:
|
||||
void add_scoped_allowed_root(const boost::filesystem::path& root);
|
||||
|
||||
// --- denied-filenames registry ---
|
||||
// Filenames a plugin may never touch, in any directory, regardless of audit mode or
|
||||
// enclosing allowed root. A candidate is denied when its filename starts with a
|
||||
// Filenames a plugin may never touch, in any directory, regardless of the enclosing allowed
|
||||
// root. A candidate is denied when its filename starts with a
|
||||
// registered name, so .bak/.tmp companions are covered by the same entry.
|
||||
//
|
||||
// The comparison is case-insensitive on every platform, unlike the _WIN32-only iequals
|
||||
@@ -73,30 +74,23 @@ public:
|
||||
// 8.3 short name is out of scope (see the design doc). This blocks direct access only.
|
||||
bool is_denied_filename(const boost::filesystem::path& candidate) const;
|
||||
|
||||
// --- enforcement mode ---
|
||||
enum class AuditMode {
|
||||
// Import/loading phase: allow reads anywhere, only block writes
|
||||
// outside allowed roots. Python needs to read stdlib modules
|
||||
// during import and those are not inside plugin directories.
|
||||
Loading,
|
||||
|
||||
// Execution phase: block both reads and writes outside allowed
|
||||
// roots, plus subprocess/socket/ctypes.
|
||||
Enforcing,
|
||||
};
|
||||
|
||||
void set_audit_mode(AuditMode mode);
|
||||
AuditMode audit_mode() const;
|
||||
|
||||
// --- policy checks ---
|
||||
// Shared core for every audited filesystem event. The deny list is consulted above the
|
||||
// Loading-mode read exemption and above the allowed roots, so a denied filename is
|
||||
// blocked even though every scope currently runs in Loading and the files in question
|
||||
// sit inside data_dir(), which is itself a global allowed root.
|
||||
// allowed roots, so a denied filename is blocked even when the file sits inside data_dir(),
|
||||
// which is itself a global allowed root.
|
||||
AuditDecision check_path_access(const boost::filesystem::path& candidate, bool is_write);
|
||||
AuditDecision check_open(const std::string& path, const std::string& mode);
|
||||
|
||||
// Ask the user to grant the requested filesystem-read paths. The request may originate on a
|
||||
// plugin load worker, so the implementation marshals the modal dialog to the wx main thread.
|
||||
// Returns true only when every missing path was granted and persisted; denial aborts the plugin
|
||||
// load without adding a permission.
|
||||
bool request_filesystem_read_permissions(const std::string& plugin_key,
|
||||
const std::vector<std::string>& paths);
|
||||
|
||||
void report_violation(const AuditViolation& violation);
|
||||
bool audit_denial_pending() const;
|
||||
void clear_audit_denial();
|
||||
void clear_last_violation();
|
||||
bool last_violation(AuditViolation& violation) const;
|
||||
|
||||
@@ -109,12 +103,12 @@ private:
|
||||
|
||||
static int audit_hook(const char* event, PyObject* args, void* user_data);
|
||||
|
||||
static thread_local std::string m_current_plugin_key;
|
||||
static thread_local std::string m_current_capability_name;
|
||||
static thread_local AuditMode m_audit_mode;
|
||||
static thread_local std::string m_current_plugin_key;
|
||||
static thread_local std::string m_current_capability_name;
|
||||
static thread_local std::vector<boost::filesystem::path> m_scoped_allowed_roots;
|
||||
static thread_local bool m_has_last_violation;
|
||||
static thread_local AuditViolation m_last_violation;
|
||||
static thread_local bool m_audit_denial_pending;
|
||||
static thread_local bool m_has_last_violation;
|
||||
static thread_local AuditViolation m_last_violation;
|
||||
|
||||
// mutable: is_denied_filename() is a const query that must lock.
|
||||
mutable std::mutex m_mutex;
|
||||
@@ -130,8 +124,7 @@ class ScopedPluginAuditContext
|
||||
public:
|
||||
explicit ScopedPluginAuditContext(
|
||||
const std::string& plugin_key,
|
||||
const std::string& capability_name = {},
|
||||
PluginAuditManager::AuditMode mode = PluginAuditManager::AuditMode::Loading);
|
||||
const std::string& capability_name = {});
|
||||
|
||||
~ScopedPluginAuditContext();
|
||||
|
||||
@@ -141,7 +134,6 @@ public:
|
||||
private:
|
||||
std::string m_previous_id;
|
||||
std::string m_previous_capability;
|
||||
PluginAuditManager::AuditMode m_previous_mode;
|
||||
std::vector<boost::filesystem::path> m_previous_scoped_roots;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user