Revert #242 and improve security when sending files to client

This commit is contained in:
yuanyuanxiang
2025-12-28 14:39:52 +01:00
parent 2d274aab4d
commit 473af822cc
10 changed files with 111 additions and 40 deletions

View File

@@ -2424,16 +2424,19 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject)
// 发送文件
std::string dir = (char*)(szBuffer + 1);
char* ptr = (char*)szBuffer + 1 + dir.length() + 1;
auto specified = *ptr ? ParseMultiStringPath(ptr, len - 2 - dir.length()) : std::vector<std::string>{};
int result = 0;
auto files = specified.empty() ? GetClipboardFiles(result): specified;
auto md5 = CalcMD5FromBytes((BYTE*)ptr, len - 2 - dir.length());
if (!m_CmdList.PopCmd(md5)) {
Mprintf("【警告】文件传输指令非法或已过期: %s\n", md5.c_str());
ContextObject->CancelIO();
break;
}
auto files = *ptr ? ParseMultiStringPath(ptr, len - 2 - dir.length()) : std::vector<std::string>{};
if (!files.empty()) {
std::string hash = GetPwdHash(), hmac = GetHMAC(100);
std::thread(FileBatchTransferWorker, files, dir, ContextObject, SendData, FinishSend,
hash, hmac).detach();
} else {
ContextObject->CancelIO();
Mprintf("GetClipboardFiles failed: %d\n", result);
}
break;
}
@@ -4332,12 +4335,17 @@ LRESULT CALLBACK CMy2015RemoteDlg::LowLevelKeyboardProc(int nCode, WPARAM wParam
auto files = GetClipboardFiles(result);
if (!files.empty()) {
// 获取远程目录
BYTE szBuffer[100] = { COMMAND_GET_FOLDER };
auto str = BuildMultiStringPath(files);
BYTE* szBuffer = new BYTE[81 + str.size()];
szBuffer[0] = { COMMAND_GET_FOLDER };
std::string masterId = GetPwdHash(), hmac = GetHMAC(100);
memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length());
memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length());
dlg->m_ContextObject->Send2Client(szBuffer, sizeof(szBuffer));
Mprintf("【Ctrl+V】 从本地拷贝文件到远程 \n");
memcpy(szBuffer + 1 + 80, str.data(), str.size());
auto md5 = CalcMD5FromBytes((BYTE*)str.data(), str.size());
g_2015RemoteDlg->m_CmdList.PutCmd(md5);
dlg->m_ContextObject->Send2Client(szBuffer, 81 + str.size());
Mprintf("【Ctrl+V】 从本地拷贝文件到远程: %s \n", md5.c_str());
} else {
CString strText = GetClipboardText();
if (!strText.IsEmpty()) {

View File

@@ -6,6 +6,7 @@
#include "TrueColorToolBar.h"
#include "IOCPServer.h"
#include <common/location.h>
#include <map>
//////////////////////////////////////////////////////////////////////////
// 以下为特殊需求使用
@@ -14,7 +15,7 @@
#define CLIENT_EXIT_WITH_SERVER 0
// 是否使用同步事件处理消息
#define USING_EVENT 0
#define USING_EVENT 1
typedef struct DllInfo {
std::string Name;
@@ -25,6 +26,23 @@ typedef struct DllInfo {
}
} DllInfo;
typedef struct FileTransformCmd {
CLock Lock;
std::map<std::string, uint64_t> CmdTime;
void PutCmd(const std::string& str) {
Lock.Lock();
CmdTime[str] = time(0);
Lock.Unlock();
}
bool PopCmd(const std::string& str, int timeoutSec = 10) {
Lock.Lock();
bool valid = CmdTime.find(str) != CmdTime.end() && time(0) - CmdTime[str] < timeoutSec;
CmdTime.erase(str);
Lock.Unlock();
return valid;
}
} FileTransformCmd;
#define ID_DYNAMIC_MENU_BASE 36500
//////////////////////////////////////////////////////////////////////////
@@ -254,6 +272,7 @@ public:
CBitmap m_bmOnline[20];
uint64_t m_superID;
std::map<HWND, CDialogBase *> m_RemoteWnds;
FileTransformCmd m_CmdList;
CDialogBase* GetRemoteWindow(HWND hWnd);
CDialogBase* GetRemoteWindow(CDialogBase* dlg);
void RemoveRemoteWindow(HWND wnd);

View File

@@ -73,6 +73,22 @@ public:
{
return md5;
}
BYTE GetBYTE(int idx=0) const {
return idx >= len ? 0 : buf[idx];
}
LPBYTE GetBuffer(int idx=0) const {
return idx >= len ? 0 : buf + idx;
}
int GetBufferLength() const {
return len;
}
BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos=0) {
if (len - ulPos < nLen) {
return FALSE;
}
memcpy(pDst, buf + ulPos, nLen);
return TRUE;
}
};
class CBuffer
@@ -98,7 +114,7 @@ public:
return WriteBuffer(buf.GetBuffer(), buf.GetBufferLen());
}
LPBYTE GetBuffer(ULONG ulPos=0);
Buffer GetMyBuffer(ULONG ulPos);
Buffer GetMyBuffer(ULONG ulPos=0);
BYTE GetBYTE(ULONG ulPos);
BOOL CopyBuffer(PVOID pDst, ULONG nLen, ULONG ulPos);
ULONG RemoveCompletedBuffer(ULONG ulLength);

View File

@@ -10,6 +10,7 @@
#include "CGridDialog.h"
#include "2015RemoteDlg.h"
#include <file_upload.h>
#include <md5.h>
// CScreenSpyDlg 对话框
@@ -63,9 +64,10 @@ extern "C" char* __imp_strtok(char* str, const char* delim)
return strtok(str, delim);
}
CScreenSpyDlg::CScreenSpyDlg(CWnd* Parent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject)
CScreenSpyDlg::CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer, CONTEXT_OBJECT* ContextObject)
: DialogBase(CScreenSpyDlg::IDD, Parent, IOCPServer, ContextObject, 0)
{
m_pParent = Parent;
m_hFullDC = NULL;
m_hFullMemDC = NULL;
m_BitmapHandle = NULL;
@@ -1134,7 +1136,6 @@ void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo)
}
std::string GetPwdHash();
std::string GetHMAC(int offset);
std::vector<std::string> PreprocessFilesSimple(const std::vector<std::string>&inputFiles);
auto files = PreprocessFilesSimple(list);
auto str = BuildMultiStringPath(files);
BYTE* szBuffer = new BYTE[1 + 80 + str.size()];
@@ -1143,8 +1144,10 @@ void CScreenSpyDlg::OnDropFiles(HDROP hDropInfo)
memcpy((char*)szBuffer + 1, masterId.c_str(), masterId.length());
memcpy((char*)szBuffer + 1 + masterId.length(), hmac.c_str(), hmac.length());
memcpy(szBuffer + 1 + 80, str.data(), str.size());
auto md5 = CalcMD5FromBytes((BYTE*)str.data(), str.size());
m_pParent->m_CmdList.PutCmd(md5);
m_ContextObject->Send2Client(szBuffer, 81 + str.size());
Mprintf("【Ctrl+V】 从本地拖拽文件到远程 \n");
Mprintf("【Ctrl+V】 从本地拖拽文件到远程: %s \n", md5.c_str());
SAFE_DELETE_ARRAY(szBuffer);
}

View File

@@ -3,6 +3,7 @@
#include "..\..\client\CursorInfo.h"
#include "VideoDlg.h"
#include "ToolbarDlg.h"
#include "2015RemoteDlg.h"
extern "C"
{
@@ -44,9 +45,10 @@ class CScreenSpyDlg : public DialogBase
{
DECLARE_DYNAMIC(CScreenSpyDlg)
CToolbarDlg* m_pToolbar = nullptr;
CMy2015RemoteDlg* m_pParent = nullptr;
public:
CScreenSpyDlg(CWnd* Parent, Server* IOCPServer=NULL, CONTEXT_OBJECT *ContextObject=NULL);
CScreenSpyDlg(CMy2015RemoteDlg* Parent, Server* IOCPServer=NULL, CONTEXT_OBJECT *ContextObject=NULL);
virtual ~CScreenSpyDlg();
virtual BOOL ShouldReconnect()
{

View File

@@ -70,6 +70,7 @@ class HeaderParser
protected:
HeaderParser()
{
m_bShouldUnmask = -1;
m_Masker = nullptr;
m_Encoder = nullptr;
m_Encoder2 = nullptr;
@@ -104,13 +105,17 @@ protected:
// UnMask
char* src = (char*)buf.GetBuffer();
ULONG srcSize = buf.GetBufferLength();
PkgMaskType maskType = MaskTypeUnknown;
ULONG ret = TryUnMask(src, srcSize, maskType);
PkgMaskType maskType = m_bShouldUnmask ? MaskTypeUnknown : MaskTypeNone;
ULONG ret = m_bShouldUnmask ? TryUnMask(src, srcSize, maskType) : 0;
std::string str = buf.Skip(ret);
if (maskType == MaskTypeHTTP) {
m_bShouldUnmask = TRUE;
std::string clientIP = getXForwardedFor(str);
if (!clientIP.empty()) peer = clientIP;
}
else {
m_bShouldUnmask = FALSE;
}
if (nullptr == m_Masker) {
m_Masker = maskType ? new HttpMask(peer) : new PkgMask();
}
@@ -200,6 +205,7 @@ protected:
}
HeaderParser& Reset()
{
m_bShouldUnmask = -1;
if (m_Masker) {
m_Masker->Destroy();
m_Masker = nullptr;
@@ -250,6 +256,7 @@ private:
Encoder* m_Encoder; // 编码器
Encoder* m_Encoder2; // 编码器2
PkgMask* m_Masker;
int m_bShouldUnmask;
};
enum IOType {