Skip to content

Commit 3e4c54a

Browse files
authored
Merge branch 'multitheftauto:master' into feature/remove-all-domains
2 parents 56eedca + 3455837 commit 3e4c54a

File tree

137 files changed

+29071
-27246
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

137 files changed

+29071
-27246
lines changed

Client/ceflauncher_DLL/CCefApp.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
*****************************************************************************/
1010
#include <cef3/cef/include/cef_app.h>
1111
#include <string>
12-
#include <sstream>
1312
#include "V8Helpers.h"
13+
#include "CCefAppAuth.h" // IPC message append helpers
1414
using V8Helpers::CV8Handler;
1515

1616
class CCefApp : public CefApp, public CefRenderProcessHandler
1717
{
1818
public:
19-
CCefApp() {}
19+
CCefApp() = default;
2020
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler() override { return this; };
2121

2222
// https://magpcss.org/ceforum/apidocs3/projects/(default)/CefRenderProcessHandler.html#OnFocusedNodeChanged(CefRefPtr%3CCefBrowser%3E,CefRefPtr%3CCefFrame%3E,CefRefPtr%3CCefDOMNode%3E)
@@ -73,13 +73,24 @@ class CCefApp : public CefApp, public CefRenderProcessHandler
7373

7474
static void Javascript_triggerEvent(CefRefPtr<CefFrame> frame, const CefV8ValueList& arguments)
7575
{
76-
if (arguments.size() == 0)
76+
if (arguments.empty()) [[unlikely]]
7777
return;
7878

7979
CefRefPtr<CefProcessMessage> message = V8Helpers::SerialiseV8Arguments("TriggerLuaEvent", arguments);
80+
if (!CefAppAuth::AppendAuthCodeToMessage(message)) [[unlikely]] // AUTH: race condition check
81+
return;
8082
frame->GetBrowser()->GetMainFrame()->SendProcessMessage(PID_BROWSER, message);
8183
}
8284

85+
void OnBeforeCommandLineProcessing(const CefString& process_type, CefRefPtr<CefCommandLine> command_line) override
86+
{
87+
const auto authCode = command_line->GetSwitchValue("kgfiv8n");
88+
if (!authCode.empty())
89+
{
90+
CefAppAuth::AuthCodeStorage() = authCode;
91+
}
92+
}
93+
8394
public:
8495
IMPLEMENT_REFCOUNTING(CCefApp);
8596

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: ceflauncher_DLL/CCefAppAuth.h
6+
* PURPOSE: IPC authentication helpers for render process
7+
*
8+
*****************************************************************************/
9+
#pragma once
10+
11+
#include <cef3/cef/include/cef_process_message.h>
12+
#include <cef3/cef/include/cef_values.h>
13+
#include <string>
14+
15+
namespace CefAppAuth
16+
{
17+
// Thread-local storage for auth code in render process
18+
inline std::string& AuthCodeStorage()
19+
{
20+
static std::string value;
21+
return value;
22+
}
23+
24+
// Appends auth code to TriggerLuaEvent IPC message
25+
// Returns true if code was appended, false if message should be blocked
26+
[[nodiscard]] inline bool AppendAuthCodeToMessage(CefRefPtr<CefProcessMessage> message)
27+
{
28+
if (!message) [[unlikely]]
29+
return false;
30+
31+
auto& authCode = AuthCodeStorage();
32+
33+
// Block messages until initialized (prevents race condition)
34+
if (authCode.empty()) [[unlikely]]
35+
return false;
36+
37+
CefRefPtr<CefListValue> args = message->GetArgumentList();
38+
const auto size = args->GetSize();
39+
args->SetSize(size + 1);
40+
args->SetString(size, authCode.c_str());
41+
return true;
42+
}
43+
}

Client/ceflauncher_DLL/Main.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
#include <delayimp.h>
2424

2525
#include "CCefApp.h"
26-
#include "SharedUtil.h"
26+
#include <string>
27+
#include <string_view>
28+
#include <algorithm>
29+
#include <iterator>
30+
#include <SharedUtil.h>
2731

2832
#ifdef CEF_ENABLE_SANDBOX
2933
#include <cef3/cef/include/cef_sandbox_win.h>
@@ -122,6 +126,23 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, [[maybe_unused]] LPVOID l
122126

123127
extern "C" [[nodiscard]] __declspec(dllexport) auto InitCEF() noexcept -> int
124128
{
129+
// Parse command line for auth code in render processes (BEFORE CefExecuteProcess)
130+
const std::wstring_view cmdLine{GetCommandLineW()};
131+
if (const auto pos = cmdLine.find(L"--kgfiv8n="); pos != std::wstring_view::npos)
132+
{
133+
const auto valueStart = pos + 11; // Skip "--kgfiv8n="
134+
const auto valueEnd = cmdLine.find_first_of(L" \t\"", valueStart);
135+
const auto authCodeW = cmdLine.substr(valueStart,
136+
valueEnd == std::wstring_view::npos ? 30 : std::min<size_t>(30, valueEnd - valueStart));
137+
138+
std::string authCode;
139+
authCode.reserve(30);
140+
std::transform(authCodeW.begin(), authCodeW.end(), std::back_inserter(authCode),
141+
[](const wchar_t wc) { return static_cast<char>(wc); });
142+
143+
CefAppAuth::AuthCodeStorage() = std::move(authCode);
144+
}
145+
125146
const auto baseDir = SharedUtil::GetMTAProcessBaseDir();
126147
if (baseDir.empty())
127148
return CEF_INIT_ERROR_NO_BASE_DIR;

Client/ceflauncher_DLL/V8Helpers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*
99
*****************************************************************************/
1010
#include <string>
11+
#include <sstream>
12+
#include <map>
1113
#include <cef3/cef/include/cef_app.h>
1214
typedef void (*JavascriptCallback)(CefRefPtr<CefFrame> frame, const CefV8ValueList& arguments);
1315

Client/cefweb/CAjaxResourceHandler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ void CAjaxResourceHandler::SetResponse(std::string data)
3636
m_strResponse = std::move(data);
3737
m_bHasData = true;
3838

39+
// Clear request data to free memory as it's no longer needed
40+
m_vecGetData.clear();
41+
m_vecGetData.shrink_to_fit();
42+
m_vecPostData.clear();
43+
m_vecPostData.shrink_to_fit();
44+
3945
if (!m_callback)
4046
return;
4147

Client/cefweb/CWebApp.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cef3/cef/include/cef_stream.h>
1717
#include <cef3/cef/include/wrapper/cef_stream_resource_handler.h>
1818
#include "CAjaxResourceHandler.h"
19+
#include "CWebAppAuth.h" // IPC code generation
1920
#include <cstdlib>
2021

2122
namespace
@@ -130,6 +131,11 @@ void CWebApp::OnBeforeChildProcessLaunch(CefRefPtr<CefCommandLine> command_line)
130131

131132
const CefString processType = command_line->GetSwitchValue("type");
132133
ConfigureCommandLineSwitches(command_line, processType);
134+
135+
// Attach IPC validation code for render processes
136+
// This runs in browser process context where g_pCore and webCore are valid
137+
// The auth code is generated in CWebCore constructor and passed to subprocesses
138+
WebAppAuth::AttachAuthCodeToCommandLine(command_line);
133139
}
134140

135141
CefRefPtr<CefBrowserProcessHandler> CWebApp::GetBrowserProcessHandler()

Client/cefweb/CWebAppAuth.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: cefweb/CWebAppAuth.h
6+
* PURPOSE: IPC authentication code generation for browser process
7+
*
8+
*****************************************************************************/
9+
#pragma once
10+
11+
#include <cef3/cef/include/cef_command_line.h>
12+
#include <array>
13+
#include <chrono>
14+
#include <mutex>
15+
#include <random>
16+
#include <string>
17+
18+
// Forward declarations
19+
class CWebCore;
20+
class CCoreInterface;
21+
extern CCoreInterface* g_pCore;
22+
23+
// Note: IsReadablePointer is available via StdInc.h which includes SharedUtil.h
24+
25+
namespace WebAppAuth
26+
{
27+
// Shared auth code storage (used by both generation and validation)
28+
inline std::string& GetSharedAuthCode()
29+
{
30+
static std::string sharedAuthCode;
31+
return sharedAuthCode;
32+
}
33+
34+
inline std::mutex& GetSharedAuthMutex()
35+
{
36+
static std::mutex sharedMutex;
37+
return sharedMutex;
38+
}
39+
40+
inline bool& GetSyncedToWebCoreFlag()
41+
{
42+
static bool syncedToWebCore = false;
43+
return syncedToWebCore;
44+
}
45+
46+
// Thread-safe auth code generation
47+
inline std::mutex& GetAuthCodeMutex()
48+
{
49+
static std::mutex mutex;
50+
return mutex;
51+
}
52+
53+
// Auth code configuration
54+
inline constexpr std::size_t AUTH_CODE_LENGTH = 30;
55+
inline constexpr char AUTH_CODE_MIN_CHAR = 'A';
56+
inline constexpr char AUTH_CODE_MAX_CHAR = 'Z';
57+
58+
// Generates random 30-character auth code (A-Z)
59+
[[nodiscard]] inline std::string GenerateAuthCode()
60+
{
61+
std::array<char, AUTH_CODE_LENGTH> buffer{};
62+
63+
// Use mt19937 with time-based seed (fast, cryptographic strength not needed for DoS prevention)
64+
static std::mt19937 rng(static_cast<unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count()));
65+
std::uniform_int_distribution<int> dist(0, AUTH_CODE_MAX_CHAR - AUTH_CODE_MIN_CHAR);
66+
67+
for (auto& ch : buffer)
68+
ch = static_cast<char>(AUTH_CODE_MIN_CHAR + dist(rng));
69+
70+
return std::string(buffer.data(), buffer.size());
71+
}
72+
73+
// Generates and attaches auth code to child process command line
74+
inline void AttachAuthCodeToCommandLine(CefRefPtr<CefCommandLine> commandLine)
75+
{
76+
if (!commandLine) [[unlikely]]
77+
return;
78+
79+
const std::lock_guard<std::mutex> lock{GetSharedAuthMutex()};
80+
81+
// Always use webCore->m_AuthCode (already populated in CWebCore constructor)
82+
// No need for fallback - webCore is guaranteed to exist before this is called
83+
if (!::g_pCore || !IsReadablePointer(::g_pCore, sizeof(void*))) [[unlikely]]
84+
return;
85+
86+
auto* const webCore = static_cast<CWebCore*>(::g_pCore->GetWebCore());
87+
if (!webCore || !IsReadablePointer(webCore, sizeof(void*))) [[unlikely]]
88+
return;
89+
90+
// webCore->m_AuthCode already populated in CWebCore::CWebCore()
91+
if (webCore->m_AuthCode.empty()) [[unlikely]]
92+
return;
93+
94+
commandLine->AppendSwitchWithValue("kgfiv8n", webCore->m_AuthCode);
95+
}
96+
}

0 commit comments

Comments
 (0)