diff --git a/WattToolkit.slnx b/WattToolkit.slnx index eadbf6d81..c6054a907 100644 --- a/WattToolkit.slnx +++ b/WattToolkit.slnx @@ -111,6 +111,10 @@ + + + + diff --git a/ref/dotnetCampus.Ipc b/ref/dotnetCampus.Ipc index c728ca3f0..f95e3481d 160000 --- a/ref/dotnetCampus.Ipc +++ b/ref/dotnetCampus.Ipc @@ -1 +1 @@ -Subproject commit c728ca3f03f59189323aefc9a41ee41ee75272ce +Subproject commit f95e3481dc8edf62a68d8816b2d2e9a7e498b386 diff --git a/src/BD.WTTS.Client.IPC/BD.WTTS.Client.IPC.csproj b/src/BD.WTTS.Client.IPC/BD.WTTS.Client.IPC.csproj index 45b22d7c3..06a1457be 100644 --- a/src/BD.WTTS.Client.IPC/BD.WTTS.Client.IPC.csproj +++ b/src/BD.WTTS.Client.IPC/BD.WTTS.Client.IPC.csproj @@ -49,7 +49,8 @@ - + + diff --git a/src/BD.WTTS.Client.IPC/Services.Implementation/IPCSubProcessServiceImpl.cs b/src/BD.WTTS.Client.IPC/Services.Implementation/IPCSubProcessServiceImpl.cs index 42a43c439..b9da650d5 100644 --- a/src/BD.WTTS.Client.IPC/Services.Implementation/IPCSubProcessServiceImpl.cs +++ b/src/BD.WTTS.Client.IPC/Services.Implementation/IPCSubProcessServiceImpl.cs @@ -46,16 +46,95 @@ public sealed class IPCSubProcessServiceImpl : IPCSubProcessService } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + static bool TryGetProcessById(int pid, [NotNullWhen(true)] out Process? process) + { + try + { + process = Process.GetProcessById(pid); + return true; + } + catch + { + // 异常不记录日志 + process = null; + return false; + } + } + + internal static bool CheckBePid(Process proc) + { + var procPath = Environment.ProcessPath; + ArgumentNullException.ThrowIfNullOrWhiteSpace(procPath); + procPath = Path.GetFullPath(procPath); + + var fn = proc.TryGetMainModule()?.FileName; + var fnPath = fn == null ? null : Path.GetFullPath(fn); + + if (procPath == fnPath) + { + return true; + } + + var accProPath = Path.GetFullPath(Path.Combine(procPath, "..", "modules", "Accelerator", +#if WINDOWS + "Steam++.Accelerator.exe" +#else + "Steam++.Accelerator" +#endif + + )); + if (procPath == accProPath) + { + return true; + } + + return false; + } + + internal static bool CheckBePid(int pid) + { + if (!TryGetProcessById(pid, out var proc)) + { + return false; + } + return CheckBePid(proc); + } + + internal static void ValidateNamedPipeClientConnection(object? s, NamedPipeClientConnectingEventArgs e) + { +#if WINDOWS +#if DEBUG + Log.Info(nameof(IPCSubProcessServiceImpl), "服务端正在校验命名管道客户端进程,{ClientProcessId}", e.ClientProcessId); +#endif + try + { + // 验证连接的客户端进程必须是自己的程序 + if (!e.ClientProcessId.HasValue || + !CheckBePid(e.ClientProcessId.Value)) + { + e.AllowConnection = false; + return; + } + } + catch (Exception ex) + { + Log.Error(nameof(IPCSubProcessServiceImpl), ex, "IpcConfiguration.NamedPipeClientConnecting fail"); + e.AllowConnection = false; + } +#endif + } + public async Task RunAsync(string moduleName, TaskCompletionSource tcs, string pipeName, Action? configureIpcProvider = null) { this.tcs = tcs; - ipcProvider = new IpcProvider( - IPCSubProcessModuleService.Constants.GetClientPipeName(moduleName, pipeName), - new IpcConfiguration - { - IpcLoggerProvider = _ => new IpcLogger_(loggerFactory, nameof(IPCSubProcessServiceImpl)), - }); + var ipcCfg = new IpcConfiguration + { + IpcLoggerProvider = _ => new IpcLogger_(loggerFactory, nameof(IPCSubProcessServiceImpl)), + }; + ipcCfg.NamedPipeClientConnecting += ValidateNamedPipeClientConnection; + ipcProvider = new IpcProvider(IPCSubProcessModuleService.Constants.GetClientPipeName(moduleName, pipeName), ipcCfg); ipcProvider.CreateIpcJoint(new IPCSubProcessModuleServiceImpl(this)); configureIpcProvider?.Invoke(ipcProvider); ipcProvider.StartServer(); diff --git a/src/BD.WTTS.Client.IPC/Services/IPCSubProcessService.cs b/src/BD.WTTS.Client.IPC/Services/IPCSubProcessService.cs index 9b8c1e57b..521b33788 100644 --- a/src/BD.WTTS.Client.IPC/Services/IPCSubProcessService.cs +++ b/src/BD.WTTS.Client.IPC/Services/IPCSubProcessService.cs @@ -89,6 +89,14 @@ public interface IPCSubProcessService : IDisposable if (!TryGetProcessById(pid, out var mainProcess)) return (int)CommandExitCode.NotFoundMainProcessId; +#if DEBUG + Log.Info(nameof(IPCSubProcessServiceImpl), "客户端正在校验服务端进程,{pid}", pid); +#endif + // 验证要连接的服务端进程是否为自己的程序 + var ckPid = IPCSubProcessServiceImpl.CheckBePid(mainProcess); + if (!ckPid) + return (int)CommandExitCode.MainProcessIdIncorrect; + #if LIB_CLIENT_IPC var nativeLibraryPath = Environment.GetEnvironmentVariable(EnvKey_NativeLibraryPath); if (!string.IsNullOrWhiteSpace(nativeLibraryPath)) diff --git a/src/BD.WTTS.Client/BD.WTTS.Client.csproj b/src/BD.WTTS.Client/BD.WTTS.Client.csproj index cd985eec4..1af8b86c0 100644 --- a/src/BD.WTTS.Client/BD.WTTS.Client.csproj +++ b/src/BD.WTTS.Client/BD.WTTS.Client.csproj @@ -126,7 +126,6 @@ - @@ -140,6 +139,8 @@ --> + + diff --git a/src/BD.WTTS.Client/Enums/CommandExitCode.cs b/src/BD.WTTS.Client/Enums/CommandExitCode.cs index 3a3a41325..8c6f7bc3a 100644 --- a/src/BD.WTTS.Client/Enums/CommandExitCode.cs +++ b/src/BD.WTTS.Client/Enums/CommandExitCode.cs @@ -57,5 +57,10 @@ public enum CommandExitCode /// GetSubProcessBootConfigurationFail = 4042, + /// + /// 主进程 Id 不正确 + /// + MainProcessIdIncorrect = 4043, + #endregion } \ No newline at end of file diff --git a/src/BD.WTTS.Client/Services.Implementation/IPC/IPCMainProcessServiceImpl.cs b/src/BD.WTTS.Client/Services.Implementation/IPC/IPCMainProcessServiceImpl.cs index 7191997fd..beeaac3a6 100644 --- a/src/BD.WTTS.Client/Services.Implementation/IPC/IPCMainProcessServiceImpl.cs +++ b/src/BD.WTTS.Client/Services.Implementation/IPC/IPCMainProcessServiceImpl.cs @@ -241,13 +241,13 @@ public sealed partial class IPCMainProcessServiceImpl : IPCMainProcessService { var tickCount64 = Environment.TickCount64; var pid = Environment.ProcessId; - ipcProvider = new IpcProvider( - $"ipc_{_()}{tickCount64}{pid / 3}{pid % 3}", - new IpcConfiguration - { - AutoReconnectPeers = true, // 允许重连 - IpcLoggerProvider = _ => new IpcLogger_(loggerFactory, nameof(IPCMainProcessServiceImpl)), - }); + var ipcCfg = new IpcConfiguration + { + AutoReconnectPeers = true, // 允许重连 + IpcLoggerProvider = _ => new IpcLogger_(loggerFactory, nameof(IPCMainProcessServiceImpl)), + }; + ipcCfg.NamedPipeClientConnecting += IPCSubProcessServiceImpl.ValidateNamedPipeClientConnection; + ipcProvider = new IpcProvider($"ipc_{_()}{tickCount64}{pid / 3}{pid % 3}", ipcCfg); ConfigureServices(); ipcProvider.StartServer(); ipcProvider.PeerConnected += IpcProvider_PeerConnected; diff --git a/src/BD.WTTS.Client/Startup/Startup.Commands.cs b/src/BD.WTTS.Client/Startup/Startup.Commands.cs index 0a9ab8c40..7df0b0173 100644 --- a/src/BD.WTTS.Client/Startup/Startup.Commands.cs +++ b/src/BD.WTTS.Client/Startup/Startup.Commands.cs @@ -449,6 +449,18 @@ partial class Startup // 自定义控制台命令参数 if (ModuleName != IPlatformService.IPCRoot.moduleName) return 402; + if (!int.TryParse(p, out var pid) || pid <= 0) + return (int)CommandExitCode.NotFoundMainProcessId; + +#if DEBUG + Log.Info(nameof(IPCSubProcessServiceImpl), "客户端正在校验服务端进程,{pid}", pid); +#endif + // 验证要连接的服务端进程是否为自己的程序 + var ckPid = IPCSubProcessServiceImpl.CheckBePid(pid); + if (!ckPid) + return (int)CommandExitCode.MainProcessIdIncorrect; + + RunUIApplication(AppServicesLevel.IPCRoot | AppServicesLevel.Hosts); await WaitConfiguredServices;