Files
SimpleRemoter/docs/FILE_TRANSFER_V2.md
2026-04-19 22:55:21 +02:00

9.5 KiB
Raw Blame History

V2 文件/文本传输功能清单

一、文件传输

方向 触发方式 断点续传 进度显示 备注
服务端 → 客户端 文件管理器拖放/Ctrl+V 支持大文件(>4GB)
客户端 → 服务端 文件管理器下载 支持大文件(>4GB)
客户端A → 客户端B (C2C) 远程桌面 Ctrl+C/Ctrl+V 自动捕获目标目录

二、文本传输

方向 触发方式 说明
服务端 → 客户端 远程桌面剪贴板同步 COMMAND_SCREEN_SET_CLIPBOARD
客户端 → 服务端 远程桌面剪贴板同步 COMMAND_SCREEN_GET_CLIPBOARD
客户端A → 客户端B (C2C) 远程桌面 Ctrl+C/Ctrl+V 自动粘贴

三、C2C 传输流程

┌─────────────┐     Ctrl+V      ┌─────────────┐    CLIPBOARD_V2    ┌─────────────┐
│  远程桌面B  │ ───────────────>│   服务端    │ ──────────────────>│  远程桌面A  │
│  (目标)     │                 │             │                    │  (源)       │
└─────────────┘                 └─────────────┘                    └─────────────┘
      ▲                               │                                   │
      │                               │ C2C_PREPARE                       │
      │<──────────────────────────────┘                                   │
      │                                                                   │
      │                         ┌─────────────┐                           │
      │   SEND_FILE_V2/C2C_TEXT │   服务端    │  SEND_FILE_V2/C2C_TEXT   │
      │<────────────────────────│   (转发)    │<──────────────────────────┘
      │                         └─────────────┘

四、协议命令

命令 用途
COMMAND_SEND_FILE_V2 85 V2文件数据包
COMMAND_FILE_RESUME 86 断点续传响应
COMMAND_CLIPBOARD_V2 87 C2C剪贴板请求
COMMAND_FILE_QUERY_RESUME 88 断点续传查询
COMMAND_C2C_PREPARE 89 C2C准备接收通知
COMMAND_C2C_TEXT 90 C2C文本传输
COMMAND_FILE_COMPLETE_V2 91 V2文件完成校验包
COMMAND_C2C_PREPARE_RESP 92 C2C准备响应返回目标目录

五、核心特性

  • 断点续传: 基于 transferID + 文件特征匹配,支持传输中断后恢复
  • 大文件支持: 使用 uint64_t 存储文件大小和偏移突破4GB限制
  • 自动目标目录: C2C传输自动捕获目标客户端当前焦点窗口的目录
  • 自动粘贴: C2C文本传输完成后自动模拟 Ctrl+V 完成粘贴
  • 版本协商: 能力位 CLIENT_CAP_V2 + 版本日期双重检测
  • 文件完整性校验: 传输完成后发送 SHA-256 校验包,接收端自动验证
  • 服务端开关: 参数菜单可控制是否启用 V2默认关闭
  • 自动清理: 状态文件超过 7 天自动删除

5.1 文件完整性校验

每个文件传输完成后,发送端计算并发送 COMMAND_FILE_COMPLETE_V2 校验包:

struct FileCompletePacketV2 {
    uint8_t     cmd;            // = 91
    uint64_t    transferID;
    uint64_t    srcClientID;
    uint64_t    dstClientID;
    uint32_t    fileIndex;
    uint64_t    fileSize;
    uint8_t     sha256[32];     // SHA-256 哈希
};  // 69 bytes

工作流程:

  1. 发送端在发送文件数据同时计算 SHA-256
  2. 文件最后一个块发送完成后,发送 FILE_COMPLETE_V2 校验包
  3. 接收端在接收数据时同步计算 SHA-256流式计算无需重读文件
  4. 收到校验包后对比哈希值,输出校验结果

支持的传输方向:

方向 校验位置
客户端 → 服务端 服务端校验
服务端 → 客户端 客户端校验
客户端A → 客户端B (C2C) 服务端转发客户端B校验

校验失败处理:

  • 校验失败时自动删除损坏文件
  • 日志输出期望和实际的 SHA-256 哈希值

断点续传与校验:

  • 断点续传时无法使用流式 SHA-256缺少历史数据
  • 自动切换为从文件重新计算完整 SHA-256

六、相关文件

文件 说明
common/commands.h 协议命令定义
common/file_upload.h/cpp V2传输核心实现
client/KernelManager.cpp 客户端主连接处理
client/ScreenManager.cpp 客户端远程桌面会话处理
server/2015Remote/2015RemoteDlg.cpp 服务端主逻辑
server/2015Remote/ScreenSpyDlg.cpp 服务端远程桌面会话处理
server/2015Remote/CDlgFileSend.cpp 文件传输进度对话框

七、使用说明

C2C 文件传输

  1. 打开两个远程桌面窗口源A和目标B
  2. 在源A上选中文件按 Ctrl+C
  3. 按 X 切换到目标B
  4. 按 Ctrl+V文件自动传输到B当前目录

C2C 文本传输

  1. 在源A上复制文本Ctrl+C
  2. 按 X 切换到目标B
  3. 在目标B的应用中按 Ctrl+V文本自动粘贴

断点续传

  • 传输中断后,重新执行相同操作
  • 系统自动检测已传输部分,从断点继续
  • 状态文件保存在 %TEMP%\FileTransfer\
  • 状态文件超过 7 天自动删除

状态文件说明

后缀 用途 说明
.resume 断点续传状态 记录 transferID、文件列表、已接收字节数
.recv C2C 接收方目录 记录目标客户端当前焦点窗口目录
.send C2C 发送方目录 记录源客户端剪贴板文件路径

所有状态文件统一存放在 %TEMP%\FileTransfer\ 目录,文件名格式为 {transferID}.{后缀}


八、代码审查报告

8.1 审查范围

文件 改动行数 审查结果
common/commands.h +16
common/file_upload.h +288
SimplePlugins/file_upload.cpp 核心实现
client/KernelManager.cpp +294
client/ScreenManager.cpp +360
server/2015Remote/2015RemoteDlg.cpp +698
server/2015Remote/CDlgFileSend.cpp +116
server/2015Remote/context.h +34

8.2 代码质量评估

优点

  1. 协议设计清晰 - 结构体使用 #pragma pack(push, 1) 确保跨平台对齐,注释详尽
  2. 版本兼容性 - V1/V2 协议共存,旧客户端仍可使用
  3. 能力协商机制完善 - CLIENT_CAP_V2 能力位 + 版本日期双重检测
  4. 断点续传设计 - transferID + fileIndex 组合键唯一标识,状态持久化
  5. 线程安全 - 使用 std::mutex 保护共享状态(g_fileStatesV2Mtx 等)
  6. 智能指针 - std::unique_ptr 管理内存RAII 处理文件句柄
  7. SHA-256 校验 - 使用 Windows bcrypt API流式计算

待改进项

优先级 问题 位置 建议
🟠 路径穿越未验证 file_upload.cpp:712 GetRelativePath 添加 .. 检查
🟠 变量命名误导 file_upload.cpp:2463 utf8Name 实际是 ANSI应改名
🟡 重复代码 KernelManager.cpp / ScreenManager.cpp C2C_TEXT 处理逻辑可提取公共函数

8.3 安全审查

检查项 状态 说明
缓冲区溢出 有长度校验 if (len < sizeof(...) + nameLength + dataLength)
认证校验 使用 hash + hmac 验证
路径穿越 ⚠️ GetRelativePath 未检查 .. 序列(实际风险低)
客户端ID伪造 通过 FindHost 验证客户端存在
文件句柄泄漏 RAII 析构函数处理
整数溢出 使用 uint64_t 支持大文件

路径穿越风险分析:

  • GetRelativePath 未过滤 .. 序列
  • 实际风险较低C2C 由服务端键盘钩子触发,非任意用户输入
  • 建议后续版本加固

8.4 边界条件测试建议

场景 测试点
大文件 >4GB 文件传输和断点续传
网络抖动 传输中断后恢复
并发传输 多个 C2C 同时进行
客户端重启 .resume 文件恢复 + SHA-256 重算
目录结构 深层嵌套目录创建
空文件 0 字节文件传输和校验

九、提交评估

9.1 总体评估: 可发布

指标 状态 说明
功能完整性 C2C/断点续传/SHA-256 校验均已实现
编译通过 无编译错误
向后兼容 V1 协议仍可用,能力协商正确
崩溃风险 无明显崩溃点
数据安全 HMAC 认证、长度校验完善

9.2 问题分类

严重程度 数量 是否阻塞提交
🔴 致命 0 -
🟠 中等 2
🟡 低危 1

9.3 后续改进建议

  1. 路径安全加固 - 在 GetRelativePath 添加 .. 过滤
  2. 重复代码重构 - 提取 C2C_TEXT 处理为公共函数
  3. 变量命名修正 - utf8NameansiName
  4. 日志级别控制 - 添加 verbose 模式开关

审查日期: 2026-02-27