summaryrefslogtreecommitdiff
path: root/src/Agent.Admin/Agent.Admin.Client
diff options
context:
space:
mode:
Diffstat (limited to 'src/Agent.Admin/Agent.Admin.Client')
-rw-r--r--src/Agent.Admin/Agent.Admin.Client/ElevatedNetworkSession.cs35
1 files changed, 23 insertions, 12 deletions
diff --git a/src/Agent.Admin/Agent.Admin.Client/ElevatedNetworkSession.cs b/src/Agent.Admin/Agent.Admin.Client/ElevatedNetworkSession.cs
index 57339dc..6caa29b 100644
--- a/src/Agent.Admin/Agent.Admin.Client/ElevatedNetworkSession.cs
+++ b/src/Agent.Admin/Agent.Admin.Client/ElevatedNetworkSession.cs
@@ -41,17 +41,7 @@ public sealed partial class ElevatedNetworkSessionFactory(string helperPath) : I
throw new AdminOperationException("sandbox.helper_incompatible", $"Elevated helper does not exist at the fixed Bundle path '{canonicalHelper}'.");
string pipeName = $"AgentSandboxMcp-{Environment.ProcessId}-{Guid.NewGuid():N}";
- using WindowsIdentity identity = WindowsIdentity.GetCurrent();
- SecurityIdentifier logon = GetLogonSid(identity);
- var security = new PipeSecurity();
- security.SetAccessRuleProtection(isProtected: true, preserveInheritance: false);
- security.AddAccessRule(new PipeAccessRule(logon, PipeAccessRights.ReadWrite, AccessControlType.Allow));
- security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
- PipeAccessRights.ReadWrite, AccessControlType.Allow));
- security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.NetworkSid, null),
- PipeAccessRights.FullControl, AccessControlType.Deny));
-
- NamedPipeServerStream pipe = CreateLocalPipe(pipeName, security);
+ NamedPipeServerStream pipe = CreateLocalPipeForCurrentLogon(pipeName);
Process? helper = null;
try
{
@@ -86,7 +76,7 @@ public sealed partial class ElevatedNetworkSessionFactory(string helperPath) : I
await connection.ConfigureAwait(false);
linked.Cancel();
- if (!Native.GetNamedPipeClientProcessId(pipe.SafePipeHandle, out uint clientPid) || clientPid != helper.Id || helper.HasExited)
+ if (!TryGetClientProcessId(pipe, out uint clientPid) || clientPid != helper.Id || helper.HasExited)
throw new AdminOperationException("sandbox.ipc_rejected", "The Named Pipe peer does not match the elevated Process started for this Task.");
await AdminProtocol.WriteAsync(pipe, new AdminRequest(AdminProtocol.Version, "hello", taskId), cancellationToken).ConfigureAwait(false);
AdminResponse hello = await AdminProtocol.ReadAsync<AdminResponse>(pipe, cancellationToken).ConfigureAwait(false);
@@ -101,6 +91,24 @@ public sealed partial class ElevatedNetworkSessionFactory(string helperPath) : I
}
}
+ internal static NamedPipeServerStream CreateLocalPipeForCurrentLogon(string pipeName)
+ {
+ using WindowsIdentity identity = WindowsIdentity.GetCurrent();
+ SecurityIdentifier logon = GetLogonSid(identity);
+ var security = new PipeSecurity();
+ security.SetAccessRuleProtection(isProtected: true, preserveInheritance: false);
+ security.AddAccessRule(new PipeAccessRule(logon, PipeAccessRights.ReadWrite, AccessControlType.Allow));
+ security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null),
+ PipeAccessRights.ReadWrite, AccessControlType.Allow));
+ security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.NetworkSid, null),
+ PipeAccessRights.FullControl, AccessControlType.Deny));
+
+ return CreateLocalPipe(pipeName, security);
+ }
+
+ internal static bool TryGetClientProcessId(NamedPipeServerStream pipe, out uint clientPid) =>
+ Native.GetNamedPipeClientProcessId(pipe.SafePipeHandle, out clientPid);
+
private static string Quote(string value) => '"' + value.Replace("\"", "\\\"") + '"';
private static SecurityIdentifier GetLogonSid(WindowsIdentity identity)
@@ -186,6 +194,9 @@ internal sealed class ElevatedNetworkSession(NamedPipeServerStream pipe, Process
{
private bool _cleaned;
+ internal NamedPipeServerStream Pipe => pipe;
+ internal Process HelperProcess => helper;
+
public async Task<bool> InspectLoopbackAsync(string applicationSid, CancellationToken cancellationToken)
{
AdminResponse response = await SendAsync(new(AdminProtocol.Version, "inspect-loopback", taskId, applicationSid), cancellationToken).ConfigureAwait(false);