文件访问控制与保护
文件访问控制与保护是文件系统安全性的核心组成部分。通过合理的访问控制机制,可以确保文件的安全性、完整性和可用性,防止未授权的访问和恶意操作。
访问控制的基本概念
什么是访问控制
**访问控制(Access Control)**是指系统对用户访问文件资源的权限进行管理和控制,确保只有授权用户才能访问相应的文件。
访问控制的目标
- 机密性(Confidentiality):确保敏感信息不被未授权用户访问
- 完整性(Integrity):防止文件内容被未授权修改
- 可用性(Availability):确保授权用户能够正常访问文件
- 审计性(Accountability):记录和追踪文件访问行为
访问控制的基本要素
- 主体(Subject):请求访问的用户或进程
- 客体(Object):被访问的文件或目录
- 权限(Permission):允许执行的操作类型
- 策略(Policy):决定访问权限的规则
访问控制模型
1. 自主访问控制(DAC)
自主访问控制是最常见的访问控制模型,文件所有者可以自主决定其他用户的访问权限。
基本概念
// DAC权限结构
struct dac_permissions {
int owner_read; // 所有者读权限
int owner_write; // 所有者写权限
int owner_execute; // 所有者执行权限
int group_read; // 组读权限
int group_write; // 组写权限
int group_execute; // 组执行权限
int other_read; // 其他用户读权限
int other_write; // 其他用户写权限
int other_execute; // 其他用户执行权限
};
struct file_dac {
int owner_id; // 所有者ID
int group_id; // 组ID
struct dac_permissions permissions;
};
权限检查实现
// DAC权限检查函数
int check_dac_permission(const char* file_path, int user_id, int operation) {
struct file_dac* dac = get_file_dac(file_path);
if (dac == NULL) return 0;
// 获取用户信息
struct user_info* user = get_user_info(user_id);
if (user == NULL) return 0;
// 检查是否为所有者
if (user_id == dac->owner_id) {
switch (operation) {
case READ_OP:
return dac->permissions.owner_read;
case WRITE_OP:
return dac->permissions.owner_write;
case EXECUTE_OP:
return dac->permissions.owner_execute;
default:
return 0;
}
}
// 检查是否为组成员
if (is_user_in_group(user_id, dac->group_id)) {
switch (operation) {
case READ_OP:
return dac->permissions.group_read;
case WRITE_OP:
return dac->permissions.group_write;
case EXECUTE_OP:
return dac->permissions.group_execute;
default:
return 0;
}
}
// 其他用户权限
switch (operation) {
case READ_OP:
return dac->permissions.other_read;
case WRITE_OP:
return dac->permissions.other_write;
case EXECUTE_OP:
return dac->permissions.other_execute;
default:
return 0;
}
}
权限修改
// 修改文件权限
int chmod_file(const char* file_path, int user_id, struct dac_permissions* new_permissions) {
struct file_dac* dac = get_file_dac(file_path);
if (dac == NULL) return -1;
// 只有所有者或超级用户可以修改权限
if (user_id != dac->owner_id && !is_superuser(user_id)) {
return -1;
}
// 更新权限
dac->permissions = *new_permissions;
update_file_dac(file_path, dac);
return 0;
}
// 修改文件所有者
int chown_file(const char* file_path, int user_id, int new_owner_id, int new_group_id) {
// 只有超级用户可以修改所有者
if (!is_superuser(user_id)) {
return -1;
}
struct file_dac* dac = get_file_dac(file_path);
if (dac == NULL) return -1;
dac->owner_id = new_owner_id;
dac->group_id = new_group_id;
update_file_dac(file_path, dac);
return 0;
}
2. 强制访问控制(MAC)
强制访问控制基于系统安全策略,用户无法自主修改访问权限。
安全标签系统
// 安全标签结构
struct security_label {
int classification; // 安全级别
char categories[64]; // 安全类别
int integrity_level; // 完整性级别
};
struct file_mac {
struct security_label label;
int mandatory_flags;
};
访问控制实现
// MAC访问控制检查
int check_mac_permission(const char* file_path, int user_id, int operation) {
struct file_mac* mac = get_file_mac(file_path);
struct user_security* user_sec = get_user_security(user_id);
if (mac == NULL || user_sec == NULL) return 0;
// 检查安全级别
if (user_sec->classification < mac->label.classification) {
return 0; // 用户安全级别不足
}
// 检查安全类别
if (!has_category_access(user_sec, mac->label.categories)) {
return 0; // 用户没有相应类别权限
}
// 检查完整性级别
if (operation == WRITE_OP && user_sec->integrity_level < mac->label.integrity_level) {
return 0; // 写操作需要更高的完整性级别
}
return 1;
}
3. 基于角色的访问控制(RBAC)
基于角色的访问控制通过角色来管理权限,用户通过分配角色获得相应权限。
角色权限结构
// 角色权限结构
struct role_permission {
char role_name[64];
int permissions[MAX_PERMISSIONS];
int permission_count;
};
struct user_role {
int user_id;
char roles[MAX_ROLES][64];
int role_count;
};
// RBAC权限检查
int check_rbac_permission(const char* file_path, int user_id, int operation) {
struct user_role* user_roles = get_user_roles(user_id);
if (user_roles == NULL) return 0;
// 检查用户的所有角色
for (int i = 0; i < user_roles->role_count; i++) {
struct role_permission* role = get_role_permission(user_roles->roles[i]);
if (role == NULL) continue;
// 检查角色是否有相应权限
for (int j = 0; j < role->permission_count; j++) {
if (role->permissions[j] == operation) {
return 1;
}
}
}
return 0;
}
访问控制表(ACL)
访问控制表为每个文件维护详细的用户和组权限列表。
ACL 结构
// ACL条目结构
struct acl_entry {
int entry_type; // 用户、组或其他
int id; // 用户ID或组ID
int permissions; // 权限位
int inheritance; // 继承标志
};
struct file_acl {
int entry_count;
struct acl_entry entries[MAX_ACL_ENTRIES];
};
ACL 操作
// 添加ACL条目
int add_acl_entry(const char* file_path, struct acl_entry* entry) {
struct file_acl* acl = get_file_acl(file_path);
if (acl == NULL) return -1;
if (acl->entry_count >= MAX_ACL_ENTRIES) {
return -1; // ACL已满
}
// 检查是否已存在相同条目
for (int i = 0; i < acl->entry_count; i++) {
if (acl->entries[i].entry_type == entry->entry_type &&
acl->entries[i].id == entry->id) {
// 更新现有条目
acl->entries[i] = *entry;
update_file_acl(file_path, acl);
return 0;
}
}
// 添加新条目
acl->entries[acl->entry_count] = *entry;
acl->entry_count++;
update_file_acl(file_path, acl);
return 0;
}
// 删除ACL条目
int remove_acl_entry(const char* file_path, int entry_type, int id) {
struct file_acl* acl = get_file_acl(file_path);
if (acl == NULL) return -1;
for (int i = 0; i < acl->entry_count; i++) {
if (acl->entries[i].entry_type == entry_type &&
acl->entries[i].id == id) {
// 移除条目
for (int j = i; j < acl->entry_count - 1; j++) {
acl->entries[j] = acl->entries[j + 1];
}
acl->entry_count--;
update_file_acl(file_path, acl);
return 0;
}
}
return -1; // 条目不存在
}
文件保护机制
1. 文件加密
对称加密
// 文件加密结构
struct file_encryption {
int algorithm; // 加密算法
char key_hash[64]; // 密钥哈希
int key_length; // 密钥长度
char iv[16]; // 初始化向量
};
// 文件加密函数
int encrypt_file(const char* file_path, const char* password) {
// 生成密钥
unsigned char key[32];
generate_key_from_password(password, key, 32);
// 生成初始化向量
unsigned char iv[16];
generate_random_iv(iv, 16);
// 读取文件内容
char* file_content = read_file_content(file_path);
int content_length = strlen(file_content);
// 加密文件内容
char* encrypted_content = malloc(content_length + 16);
int encrypted_length = encrypt_aes256(file_content, content_length, key, iv, encrypted_content);
// 保存加密信息
struct file_encryption* enc_info = malloc(sizeof(struct file_encryption));
enc_info->algorithm = AES256;
hash_key(key, 32, enc_info->key_hash);
enc_info->key_length = 32;
memcpy(enc_info->iv, iv, 16);
// 写入加密文件
write_encrypted_file(file_path, encrypted_content, encrypted_length, enc_info);
free(file_content);
free(encrypted_content);
free(enc_info);
return 0;
}
非对称加密
// 非对称加密文件保护
struct asymmetric_encryption {
char public_key[256];
char encrypted_key[256];
int algorithm;
};
// 使用公钥加密文件
int encrypt_file_with_public_key(const char* file_path, const char* public_key) {
// 生成对称密钥
unsigned char session_key[32];
generate_random_key(session_key, 32);
// 使用公钥加密会话密钥
char encrypted_session_key[256];
rsa_encrypt(session_key, 32, public_key, encrypted_session_key);
// 使用会话密钥加密文件
encrypt_file_with_session_key(file_path, session_key);
// 保存加密信息
struct asymmetric_encryption* enc_info = malloc(sizeof(struct asymmetric_encryption));
strcpy(enc_info->public_key, public_key);
strcpy(enc_info->encrypted_key, encrypted_session_key);
enc_info->algorithm = RSA_AES;
save_encryption_info(file_path, enc_info);
free(enc_info);
return 0;
}
2. 数字签名
// 文件数字签名
struct file_signature {
char algorithm[32]; // 签名算法
char signature[256]; // 数字签名
char certificate[1024]; // 证书信息
int timestamp; // 签名时间戳
};
// 对文件进行数字签名
int sign_file(const char* file_path, const char* private_key) {
// 计算文件哈希
char file_hash[64];
calculate_file_hash(file_path, file_hash);
// 使用私钥签名
char signature[256];
rsa_sign(file_hash, 64, private_key, signature);
// 保存签名信息
struct file_signature* sig_info = malloc(sizeof(struct file_signature));
strcpy(sig_info->algorithm, "RSA-SHA256");
strcpy(sig_info->signature, signature);
sig_info->timestamp = time(NULL);
save_signature_info(file_path, sig_info);
free(sig_info);
return 0;
}
// 验证文件签名
int verify_file_signature(const char* file_path, const char* public_key) {
// 计算文件哈希
char file_hash[64];
calculate_file_hash(file_path, file_hash);
// 获取签名信息
struct file_signature* sig_info = get_signature_info(file_path);
if (sig_info == NULL) return -1;
// 验证签名
int result = rsa_verify(file_hash, 64, sig_info->signature, public_key);
free(sig_info);
return result;
}
3. 文件完整性检查
// 文件完整性检查
struct file_integrity {
char hash_algorithm[32];
char file_hash[64];
int last_modified;
int check_frequency;
};
// 计算文件完整性哈希
int calculate_file_integrity(const char* file_path) {
struct file_integrity* integrity = malloc(sizeof(struct file_integrity));
// 计算文件哈希
calculate_sha256_hash(file_path, integrity->file_hash);
strcpy(integrity->hash_algorithm, "SHA256");
integrity->last_modified = get_file_modification_time(file_path);
integrity->check_frequency = 3600; // 每小时检查一次
save_integrity_info(file_path, integrity);
free(integrity);
return 0;
}
// 检查文件完整性
int check_file_integrity(const char* file_path) {
struct file_integrity* stored_integrity = get_integrity_info(file_path);
if (stored_integrity == NULL) return -1;
// 计算当前文件哈希
char current_hash[64];
calculate_sha256_hash(file_path, current_hash);
// 比较哈希值
int result = strcmp(stored_integrity->file_hash, current_hash);
free(stored_integrity);
return result == 0 ? 0 : -1;
}
审计和日志
访问日志记录
// 文件访问日志
struct file_access_log {
int user_id;
char file_path[256];
int operation;
int result;
int timestamp;
char ip_address[16];
char user_agent[256];
};
// 记录文件访问
int log_file_access(const char* file_path, int user_id, int operation, int result) {
struct file_access_log* log_entry = malloc(sizeof(struct file_access_log));
log_entry->user_id = user_id;
strcpy(log_entry->file_path, file_path);
log_entry->operation = operation;
log_entry->result = result;
log_entry->timestamp = time(NULL);
// 获取用户IP地址
get_user_ip_address(user_id, log_entry->ip_address);
// 获取用户代理信息
get_user_agent(user_id, log_entry->user_agent);
// 写入日志
write_access_log(log_entry);
free(log_entry);
return 0;
}
审计报告生成
// 生成访问审计报告
int generate_audit_report(const char* output_file, int start_time, int end_time) {
FILE* report = fopen(output_file, "w");
if (report == NULL) return -1;
fprintf(report, "文件访问审计报告\n");
fprintf(report, "时间范围: %d - %d\n\n", start_time, end_time);
// 统计访问次数
int total_access = 0;
int successful_access = 0;
int failed_access = 0;
// 读取日志条目
struct file_access_log* log_entries = read_access_logs(start_time, end_time);
int entry_count = get_log_entry_count();
for (int i = 0; i < entry_count; i++) {
total_access++;
if (log_entries[i].result == 0) {
successful_access++;
} else {
failed_access++;
}
// 输出详细日志
fprintf(report, "时间: %s", ctime(&log_entries[i].timestamp));
fprintf(report, "用户: %d\n", log_entries[i].user_id);
fprintf(report, "文件: %s\n", log_entries[i].file_path);
fprintf(report, "操作: %s\n", get_operation_name(log_entries[i].operation));
fprintf(report, "结果: %s\n", log_entries[i].result == 0 ? "成功" : "失败");
fprintf(report, "IP地址: %s\n", log_entries[i].ip_address);
fprintf(report, "---\n");
}
// 输出统计信息
fprintf(report, "\n统计信息:\n");
fprintf(report, "总访问次数: %d\n", total_access);
fprintf(report, "成功访问: %d\n", successful_access);
fprintf(report, "失败访问: %d\n", failed_access);
fprintf(report, "成功率: %.2f%%\n", (float)successful_access / total_access * 100);
fclose(report);
free(log_entries);
return 0;
}
总结
文件访问控制与保护是文件系统安全性的重要组成部分。通过合理的访问控制模型、加密保护、数字签名和审计机制,可以确保文件的安全性、完整性和可用性。
现代文件系统通常采用多种保护机制的组合,以提供全面的安全保护。理解这些机制对于设计安全的文件系统和进行系统安全评估具有重要意义。
在后续章节中,我们将学习常见文件系统类型、文件系统性能优化等更高级的概念。