Feature: sub-connection auth (TOKEN_CONN_AUTH) with HMAC + clientID binding
Client first packet on every sub-connection signs (clientID || timestamp || nonce) and waits for server ack. Server verifies signature and pins clientID on the sub-connection ctx, eliminating IP-reverse-lookup unreliability for NAT/localhost scenarios. Sub-conn coverage: Win 12 sites, Linux/macOS 3-4 each. Main connection keeps existing TOKEN_LOGIN flow unchanged. Includes: - Protocol structs sized to 512/256 bytes with reserved space for future extensions (locale, OS info, session token, etc.) - 5-min timestamp tolerance (Kerberos-grade replay window) - 10-sec client wait for cross-pacific / weak-network tolerance - Fix RemoveFromHostList side-effect ordering: MarkDeviceOffline and m_ActiveWndW.erase now only fire when ctx is actually removed from m_HostList, preventing sub-conn disconnects from misreporting main as offline (regression introduced by auth-set clientID on sub ctx) - Fix latent bug: IOCPClient::m_conn was never assigned in ctor, leaving GetConnectionAddress() always NULL and FileManager V2 transfer's srcClientID always 0 Breaking change: new client cannot use sub-features against old server. New server tolerates legacy clients (no auth). Future tightening can reject unauthenticated sub-connections via IsAuthenticated() flag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -347,6 +347,8 @@ void* ShellworkingThread(void* param)
|
||||
std::unique_ptr<IOCPClient> ClientObject(new IOCPClient(g_bExit, true));
|
||||
void* clientAddr = ClientObject.get();
|
||||
Mprintf(">>> Enter ShellworkingThread [%p]\n", clientAddr);
|
||||
// 子连接:开启 auth。Linux IOCPClient 不带 m_conn,显式传入 g_myClientID。
|
||||
ClientObject->EnableSubConnAuth(true, g_myClientID);
|
||||
if (!g_bExit && ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort())) {
|
||||
std::unique_ptr<PTYHandler> handler(new PTYHandler(ClientObject.get()));
|
||||
ClientObject->setManagerCallBack(handler.get(), IOCPManager::DataProcess, IOCPManager::ReconnectProcess);
|
||||
@@ -371,6 +373,8 @@ void* ScreenworkingThread(void* param)
|
||||
std::unique_ptr<IOCPClient> ClientObject(new IOCPClient(g_bExit, true));
|
||||
void* clientAddr = ClientObject.get();
|
||||
Mprintf(">>> Enter ScreenworkingThread [%p]\n", clientAddr);
|
||||
// 子连接:开启 auth。Linux IOCPClient 不带 m_conn,显式传入 g_myClientID。
|
||||
ClientObject->EnableSubConnAuth(true, g_myClientID);
|
||||
if (!g_bExit && ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort())) {
|
||||
std::unique_ptr<ScreenHandler> handler(new ScreenHandler(ClientObject.get()));
|
||||
ClientObject->setManagerCallBack(handler.get(), IOCPManager::DataProcess, IOCPManager::ReconnectProcess);
|
||||
@@ -395,6 +399,8 @@ void* SystemManagerThread(void* param)
|
||||
std::unique_ptr<IOCPClient> ClientObject(new IOCPClient(g_bExit, true));
|
||||
void* clientAddr = ClientObject.get();
|
||||
Mprintf(">>> Enter SystemManagerThread [%p]\n", clientAddr);
|
||||
// 子连接:开启 auth。Linux IOCPClient 不带 m_conn,显式传入 g_myClientID。
|
||||
ClientObject->EnableSubConnAuth(true, g_myClientID);
|
||||
if (!g_bExit && ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort())) {
|
||||
std::unique_ptr<SystemManager> handler(new SystemManager(ClientObject.get()));
|
||||
ClientObject->setManagerCallBack(handler.get(), IOCPManager::DataProcess, IOCPManager::ReconnectProcess);
|
||||
@@ -417,6 +423,8 @@ void* FileManagerThread(void* param)
|
||||
std::unique_ptr<IOCPClient> ClientObject(new IOCPClient(g_bExit, true));
|
||||
void* clientAddr = ClientObject.get();
|
||||
Mprintf(">>> Enter FileManagerThread [%p]\n", clientAddr);
|
||||
// 子连接:开启 auth。Linux IOCPClient 不带 m_conn,显式传入 g_myClientID。
|
||||
ClientObject->EnableSubConnAuth(true, g_myClientID);
|
||||
if (!g_bExit && ClientObject->ConnectServer(g_SETTINGS.ServerIP(), g_SETTINGS.ServerPort())) {
|
||||
std::unique_ptr<FileManager> handler(new FileManager(ClientObject.get()));
|
||||
ClientObject->setManagerCallBack(handler.get(), IOCPManager::DataProcess, IOCPManager::ReconnectProcess);
|
||||
|
||||
Reference in New Issue
Block a user