This commit is contained in:
2025-10-28 10:27:49 +08:00
parent c98e7e61b3
commit 2003c5992f
122 changed files with 46814 additions and 249 deletions

View File

@@ -0,0 +1,528 @@
// ================================================================================================
// Audio Backend - 沙盒安全测试
// ================================================================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include "plugin_host/sandbox/sandbox_interface.h"
#include "tests/common/test_fixtures.h"
#include <thread>
#include <chrono>
#include <atomic>
using namespace audio_backend;
using namespace audio_backend::plugin_host;
using namespace std::chrono_literals;
// 创建安全测试用的沙盒实现
class SecurityTestingSandbox : public SandboxBase {
public:
explicit SecurityTestingSandbox() : SandboxBase(SandboxType::ProcessLevelIsolation) {}
~SecurityTestingSandbox() override = default;
// 基本方法实现
common::ErrorCode do_initialize() override { return common::ErrorCode::Success; }
common::ErrorCode do_shutdown() override { return common::ErrorCode::Success; }
common::ErrorCode do_start_process(
const std::string& executable_path,
const std::vector<std::string>& arguments,
ProcessId& out_process_id) override {
out_process_id = next_pid_++;
register_process(out_process_id, executable_path);
return common::ErrorCode::Success;
}
common::ErrorCode do_stop_process(ProcessId process_id, bool force) override {
auto* process_info = find_process_info(process_id);
if (process_info) {
unregister_process(process_id);
return common::ErrorCode::Success;
}
return common::ErrorCode::InvalidArgument;
}
// 接口方法实现
common::ErrorCode start_process(
const std::string& executable_path,
const std::vector<std::string>& arguments,
ProcessId& out_process_id) override {
return SandboxBase::start_process(executable_path, arguments, out_process_id);
}
common::ErrorCode suspend_process(ProcessId process_id) override {
return common::ErrorCode::Success;
}
common::ErrorCode resume_process(ProcessId process_id) override {
return common::ErrorCode::Success;
}
common::ErrorCode restart_process(ProcessId process_id) override {
return common::ErrorCode::Success;
}
common::ErrorCode wait_for_process(
ProcessId process_id,
std::chrono::milliseconds timeout,
int& exit_code) override {
exit_code = 0;
return common::ErrorCode::Success;
}
common::ErrorCode set_resource_limits(
ProcessId process_id,
const ResourceLimits& limits) override {
return common::ErrorCode::Success;
}
common::ErrorCode get_resource_usage(
ProcessId process_id,
PerformanceMetrics& metrics) override {
return common::ErrorCode::Success;
}
common::ErrorCode enforce_resource_limits(ProcessId process_id) override {
return common::ErrorCode::Success;
}
// 安全管理重点方法
common::ErrorCode apply_security_settings(
ProcessId process_id,
const SecuritySettings& settings) override {
auto* process_info = find_process_info(process_id);
if (process_info) {
security_settings_[process_id] = settings;
return common::ErrorCode::Success;
}
return common::ErrorCode::InvalidArgument;
}
bool is_path_accessible(
ProcessId process_id,
const std::string& path) const override {
auto* process_info = find_process_info(process_id);
if (!process_info) {
return false;
}
// 获取安全设置
auto it = security_settings_.find(process_id);
if (it == security_settings_.end()) {
// 如果没有特定设置,默认不允许访问
return false;
}
const SecuritySettings& settings = it->second;
// 全局文件访问设置
if (!settings.allow_file_access) {
notify_security_violation(process_id, "FileAccess");
return false;
}
// 检查允许的路径
for (const auto& allowed_path : settings.allowed_paths) {
if (path.find(allowed_path) == 0) {
return true;
}
}
// 检查禁止的路径
for (const auto& denied_path : settings.denied_paths) {
if (path.find(denied_path) == 0) {
notify_security_violation(process_id, "PathAccess:" + denied_path);
return false;
}
}
// 如果允许列表不为空,但路径不在允许列表中,则拒绝访问
if (!settings.allowed_paths.empty()) {
notify_security_violation(process_id, "PathNotAllowed:" + path);
return false;
}
// 默认允许访问
return true;
}
bool is_network_accessible(ProcessId process_id) const override {
auto* process_info = find_process_info(process_id);
if (!process_info) {
return false;
}
// 获取安全设置
auto it = security_settings_.find(process_id);
if (it == security_settings_.end()) {
// 如果没有特定设置,默认不允许访问
return false;
}
const SecuritySettings& settings = it->second;
// 全局网络访问设置
if (!settings.allow_network_access) {
notify_security_violation(process_id, "NetworkAccess");
return false;
}
return true;
}
common::ErrorCode execute_platform_specific_operation(
const std::string& operation_name,
const std::vector<std::string>& parameters,
std::string& result) override {
// 检查是否是安全敏感操作
if (operation_name == "AccessRegistry" ||
operation_name == "ModifySystemFiles" ||
operation_name == "AccessDevices") {
// 获取当前进程ID假设是从调用上下文中获取的
ProcessId current_pid = current_operation_pid_;
auto* process_info = find_process_info(current_pid);
if (process_info) {
auto it = security_settings_.find(current_pid);
if (it != security_settings_.end()) {
const SecuritySettings& settings = it->second;
// 检查是否允许系统操作
if (!settings.allow_system_operations) {
notify_security_violation(current_pid, "SystemOperation:" + operation_name);
return common::ErrorCode::SecurityViolation;
}
}
}
}
// 默认实现
result = "操作执行成功";
return common::ErrorCode::Success;
}
// 添加测试辅助方法
const SecuritySettings& get_security_settings(ProcessId process_id) const {
static SecuritySettings empty_settings;
auto it = security_settings_.find(process_id);
if (it != security_settings_.end()) {
return it->second;
}
return empty_settings;
}
void set_current_operation_pid(ProcessId pid) {
current_operation_pid_ = pid;
}
// 获取安全统计信息
size_t get_security_violations_count() const {
return stats_.total_security_violations.load();
}
private:
std::atomic<ProcessId> next_pid_{1000};
mutable std::map<ProcessId, SecuritySettings> security_settings_;
ProcessId current_operation_pid_ = 0; // 当前操作的进程ID
};
// 沙盒安全测试固定装置
class SandboxSecurityTest : public test::PluginSandboxTest {
protected:
void SetUp() override {
test::PluginSandboxTest::SetUp();
// 创建沙盒
sandbox_ = std::make_unique<SecurityTestingSandbox>();
// 创建事件回调
callback_ = std::make_shared<::testing::NiceMock<MockSandboxEventCallback>>();
// 初始化沙盒
SandboxConfig config;
config.sandbox_type = SandboxType::ProcessLevelIsolation;
config.enable_security_monitoring = true;
ASSERT_EQ(sandbox_->initialize(config), common::ErrorCode::Success);
// 设置事件回调
sandbox_->set_event_callback(callback_);
}
void TearDown() override {
if (sandbox_->is_initialized()) {
sandbox_->shutdown();
}
sandbox_.reset();
callback_.reset();
test::PluginSandboxTest::TearDown();
}
// 创建默认安全设置
SecuritySettings create_default_settings() {
SecuritySettings settings;
settings.allow_file_access = true;
settings.allow_network_access = true;
settings.allow_system_operations = false;
settings.allow_registry_access = false;
settings.allow_process_creation = false;
settings.allow_device_access = false;
settings.allowed_paths = {"/app", "./data"};
settings.denied_paths = {"/system", "./config"};
return settings;
}
protected:
std::unique_ptr<SecurityTestingSandbox> sandbox_;
std::shared_ptr<MockSandboxEventCallback> callback_;
};
// 测试应用安全设置
TEST_F(SandboxSecurityTest, ApplySecuritySettings) {
// 启动进程
ProcessId pid = 0;
ASSERT_EQ(sandbox_->start_process("test.exe", {}, pid), common::ErrorCode::Success);
// 创建安全设置
SecuritySettings settings = create_default_settings();
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 验证安全设置
const SecuritySettings& applied_settings = sandbox_->get_security_settings(pid);
EXPECT_EQ(applied_settings.allow_file_access, settings.allow_file_access);
EXPECT_EQ(applied_settings.allow_network_access, settings.allow_network_access);
EXPECT_EQ(applied_settings.allow_system_operations, settings.allow_system_operations);
EXPECT_EQ(applied_settings.allowed_paths, settings.allowed_paths);
EXPECT_EQ(applied_settings.denied_paths, settings.denied_paths);
// 测试无效的进程ID
EXPECT_NE(sandbox_->apply_security_settings(999999, settings), common::ErrorCode::Success);
}
// 测试文件访问控制
TEST_F(SandboxSecurityTest, FileAccessControl) {
// 启动进程
ProcessId pid = 0;
ASSERT_EQ(sandbox_->start_process("test.exe", {}, pid), common::ErrorCode::Success);
// 创建安全设置
SecuritySettings settings = create_default_settings();
settings.allow_file_access = true;
settings.allowed_paths = {"/app", "./data"};
settings.denied_paths = {"/system", "./config"};
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 测试允许的路径
EXPECT_TRUE(sandbox_->is_path_accessible(pid, "/app/resources"));
EXPECT_TRUE(sandbox_->is_path_accessible(pid, "./data/user"));
// 设置安全事件调用期望
EXPECT_CALL(*callback_, on_security_violation(pid, ::testing::_))
.Times(2);
// 测试禁止的路径
EXPECT_FALSE(sandbox_->is_path_accessible(pid, "/system/bin"));
EXPECT_FALSE(sandbox_->is_path_accessible(pid, "./config/secrets"));
// 测试未指定的路径
EXPECT_TRUE(sandbox_->is_path_accessible(pid, "/tmp/cache"));
// 测试完全禁止文件访问
SecuritySettings no_file_access = settings;
no_file_access.allow_file_access = false;
ASSERT_EQ(sandbox_->apply_security_settings(pid, no_file_access), common::ErrorCode::Success);
// 设置安全事件调用期望
EXPECT_CALL(*callback_, on_security_violation(pid, "FileAccess"))
.Times(1);
// 即使是允许的路径,现在也应该被拒绝
EXPECT_FALSE(sandbox_->is_path_accessible(pid, "/app/resources"));
}
// 测试网络访问控制
TEST_F(SandboxSecurityTest, NetworkAccessControl) {
// 启动进程
ProcessId pid = 0;
ASSERT_EQ(sandbox_->start_process("test.exe", {}, pid), common::ErrorCode::Success);
// 创建安全设置,默认允许网络访问
SecuritySettings settings = create_default_settings();
settings.allow_network_access = true;
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 测试网络访问
EXPECT_TRUE(sandbox_->is_network_accessible(pid));
// 禁用网络访问
settings.allow_network_access = false;
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 设置安全事件调用期望
EXPECT_CALL(*callback_, on_security_violation(pid, "NetworkAccess"))
.Times(1);
// 测试网络访问被拒绝
EXPECT_FALSE(sandbox_->is_network_accessible(pid));
}
// 测试系统操作访问控制
TEST_F(SandboxSecurityTest, SystemOperationsControl) {
// 启动进程
ProcessId pid = 0;
ASSERT_EQ(sandbox_->start_process("test.exe", {}, pid), common::ErrorCode::Success);
// 创建安全设置,默认禁止系统操作
SecuritySettings settings = create_default_settings();
settings.allow_system_operations = false;
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 设置当前操作进程ID
sandbox_->set_current_operation_pid(pid);
// 设置安全事件调用期望
EXPECT_CALL(*callback_, on_security_violation(pid, ::testing::StartsWith("SystemOperation:")))
.Times(1);
// 尝试执行系统操作
std::string result;
auto err = sandbox_->execute_platform_specific_operation("AccessRegistry", {}, result);
// 应该被拒绝
EXPECT_EQ(err, common::ErrorCode::SecurityViolation);
// 允许系统操作
settings.allow_system_operations = true;
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 再次尝试执行系统操作
err = sandbox_->execute_platform_specific_operation("AccessRegistry", {}, result);
// 现在应该成功
EXPECT_EQ(err, common::ErrorCode::Success);
EXPECT_FALSE(result.empty());
}
// 测试安全违规计数
TEST_F(SandboxSecurityTest, SecurityViolationCounting) {
// 启动进程
ProcessId pid = 0;
ASSERT_EQ(sandbox_->start_process("test.exe", {}, pid), common::ErrorCode::Success);
// 创建安全设置
SecuritySettings settings = create_default_settings();
settings.allow_file_access = true;
settings.allow_network_access = false;
settings.allow_system_operations = false;
settings.allowed_paths = {"/app"};
settings.denied_paths = {"/system"};
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 初始违规计数应为0
EXPECT_EQ(sandbox_->get_security_violations_count(), 0);
// 触发网络访问违规
sandbox_->is_network_accessible(pid);
// 违规计数应增加
EXPECT_EQ(sandbox_->get_security_violations_count(), 1);
// 触发文件访问违规
sandbox_->is_path_accessible(pid, "/system/bin");
// 违规计数应再次增加
EXPECT_EQ(sandbox_->get_security_violations_count(), 2);
// 设置当前操作进程ID
sandbox_->set_current_operation_pid(pid);
// 触发系统操作违规
std::string result;
sandbox_->execute_platform_specific_operation("AccessRegistry", {}, result);
// 违规计数应再次增加
EXPECT_EQ(sandbox_->get_security_violations_count(), 3);
}
// 测试多进程安全设置
TEST_F(SandboxSecurityTest, MultiProcessSecuritySettings) {
// 启动多个进程
ProcessId pid1 = 0, pid2 = 0;
ASSERT_EQ(sandbox_->start_process("process1.exe", {}, pid1), common::ErrorCode::Success);
ASSERT_EQ(sandbox_->start_process("process2.exe", {}, pid2), common::ErrorCode::Success);
// 创建不同的安全设置
SecuritySettings settings1 = create_default_settings();
settings1.allow_file_access = true;
settings1.allow_network_access = false;
SecuritySettings settings2 = create_default_settings();
settings2.allow_file_access = false;
settings2.allow_network_access = true;
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid1, settings1), common::ErrorCode::Success);
ASSERT_EQ(sandbox_->apply_security_settings(pid2, settings2), common::ErrorCode::Success);
// 测试文件访问
EXPECT_TRUE(sandbox_->is_path_accessible(pid1, "/app/resources"));
EXPECT_FALSE(sandbox_->is_path_accessible(pid2, "/app/resources"));
// 测试网络访问
EXPECT_FALSE(sandbox_->is_network_accessible(pid1));
EXPECT_TRUE(sandbox_->is_network_accessible(pid2));
}
// 测试安全设置更新
TEST_F(SandboxSecurityTest, UpdateSecuritySettings) {
// 启动进程
ProcessId pid = 0;
ASSERT_EQ(sandbox_->start_process("test.exe", {}, pid), common::ErrorCode::Success);
// 创建初始安全设置
SecuritySettings settings = create_default_settings();
settings.allow_file_access = true;
settings.allow_network_access = true;
// 应用安全设置
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 测试初始设置
EXPECT_TRUE(sandbox_->is_path_accessible(pid, "/app/resources"));
EXPECT_TRUE(sandbox_->is_network_accessible(pid));
// 更新安全设置
settings.allow_file_access = false;
settings.allow_network_access = false;
ASSERT_EQ(sandbox_->apply_security_settings(pid, settings), common::ErrorCode::Success);
// 设置安全事件调用期望
EXPECT_CALL(*callback_, on_security_violation(pid, ::testing::_))
.Times(2);
// 测试更新后的设置
EXPECT_FALSE(sandbox_->is_path_accessible(pid, "/app/resources"));
EXPECT_FALSE(sandbox_->is_network_accessible(pid));
}
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}