summaryrefslogtreecommitdiff
path: root/tests/Agent.Windows.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Agent.Windows.Tests')
-rw-r--r--tests/Agent.Windows.Tests/AdministrativeBoundaryTests.cs87
-rw-r--r--tests/Agent.Windows.Tests/Agent.Windows.Tests.csproj1
-rw-r--r--tests/Agent.Windows.Tests/CrashScenarioBootstrap.cs4
-rw-r--r--tests/Agent.Windows.Tests/DirectElevatedNetworkSession.cs75
-rw-r--r--tests/Agent.Windows.Tests/ReadmeOperationalTests.cs5
-rw-r--r--tests/Agent.Windows.Tests/SecurityPolicyTests.cs74
6 files changed, 223 insertions, 23 deletions
diff --git a/tests/Agent.Windows.Tests/AdministrativeBoundaryTests.cs b/tests/Agent.Windows.Tests/AdministrativeBoundaryTests.cs
new file mode 100644
index 0000000..b218072
--- /dev/null
+++ b/tests/Agent.Windows.Tests/AdministrativeBoundaryTests.cs
@@ -0,0 +1,87 @@
+using System.Buffers.Binary;
+using System.Text;
+using System.Text.Json;
+using Agent.Admin.Client;
+
+namespace Agent.Windows.Tests;
+
+public sealed class AdministrativeBoundaryTests
+{
+ [Fact]
+ public async Task Administrative_protocol_round_trips_only_the_fixed_network_request_shape()
+ {
+ var request = new AdminRequest(AdminProtocol.Version, "apply-network", Guid.NewGuid(), "S-1-15-2-1", "local",
+ [new("127.0.0.1", 11434)], false);
+ using var stream = new MemoryStream();
+ await AdminProtocol.WriteAsync(stream, request, TestContext.Current.CancellationToken);
+ stream.Position = 0;
+ AdminRequest actual = await AdminProtocol.ReadAsync<AdminRequest>(stream, TestContext.Current.CancellationToken);
+ Assert.Equal(request.Version, actual.Version);
+ Assert.Equal(request.Operation, actual.Operation);
+ Assert.Equal(request.TaskId, actual.TaskId);
+ Assert.Equal(request.ApplicationSid, actual.ApplicationSid);
+ Assert.Equal(request.NetworkAccess, actual.NetworkAccess);
+ Assert.Equal(request.OriginallyLoopbackExempt, actual.OriginallyLoopbackExempt);
+ Assert.Equal(request.Endpoints, actual.Endpoints);
+ string json = Encoding.UTF8.GetString(stream.ToArray());
+ Assert.DoesNotContain("executable", json, StringComparison.OrdinalIgnoreCase);
+ Assert.DoesNotContain("commandLine", json, StringComparison.OrdinalIgnoreCase);
+ Assert.DoesNotContain("securityDescriptor", json, StringComparison.OrdinalIgnoreCase);
+ Assert.DoesNotContain("layer", json, StringComparison.OrdinalIgnoreCase);
+ Assert.DoesNotContain("action", json, StringComparison.OrdinalIgnoreCase);
+ }
+
+ [Fact]
+ public async Task Administrative_protocol_rejects_oversized_messages_before_allocation()
+ {
+ byte[] header = new byte[4];
+ BinaryPrimitives.WriteInt32LittleEndian(header, AdminProtocol.MaxMessageBytes + 1);
+ using var stream = new MemoryStream(header);
+ await Assert.ThrowsAsync<InvalidDataException>(() => AdminProtocol.ReadAsync<AdminRequest>(stream,
+ TestContext.Current.CancellationToken));
+ }
+
+ [Fact]
+ public async Task Administrative_protocol_rejects_fields_outside_the_fixed_schema()
+ {
+ byte[] payload = Encoding.UTF8.GetBytes("""{"version":1,"operation":"hello","taskId":"00000000-0000-0000-0000-000000000000","command":"cmd.exe"}""");
+ byte[] framed = new byte[payload.Length + 4];
+ BinaryPrimitives.WriteInt32LittleEndian(framed, payload.Length);
+ payload.CopyTo(framed.AsSpan(4));
+ using var stream = new MemoryStream(framed);
+
+ await Assert.ThrowsAsync<JsonException>(() => AdminProtocol.ReadAsync<AdminRequest>(stream,
+ TestContext.Current.CancellationToken));
+ }
+
+ [Fact]
+ public void Manifests_and_native_call_ownership_match_the_process_boundary()
+ {
+ string root = RepositoryRoot();
+ string mainManifest = File.ReadAllText(Path.Combine(root, "src", "Agent.App", "app.manifest"));
+ string helperManifest = File.ReadAllText(Path.Combine(root, "src", "Agent.Admin", "Agent.Admin.Host", "app.manifest"));
+ Assert.Contains("level=\"asInvoker\"", mainManifest, StringComparison.Ordinal);
+ Assert.Contains("level=\"requireAdministrator\"", helperManifest, StringComparison.Ordinal);
+ Assert.Contains("uiAccess=\"false\"", helperManifest, StringComparison.Ordinal);
+ string normalNative = File.ReadAllText(Path.Combine(root, "src", "Agent.Windows", "NativeMethods.txt"));
+ Assert.DoesNotContain("FwpmTransactionBegin0", normalNative, StringComparison.Ordinal);
+ Assert.DoesNotContain("FwpmFilterAdd0", normalNative, StringComparison.Ordinal);
+ Assert.DoesNotContain("NetworkIsolationSetAppContainerConfig", normalNative, StringComparison.Ordinal);
+ string helperNative = File.ReadAllText(Path.Combine(root, "src", "Agent.Admin", "Agent.Admin.Host", "NativeMethods.txt"));
+ Assert.Contains("FwpmTransactionBegin0", helperNative, StringComparison.Ordinal);
+ Assert.Contains("NetworkIsolationSetAppContainerConfig", helperNative, StringComparison.Ordinal);
+ string client = File.ReadAllText(Path.Combine(root, "src", "Agent.Admin", "Agent.Admin.Client", "ElevatedNetworkSession.cs"));
+ Assert.Contains("PipeRejectRemoteClients", client, StringComparison.Ordinal);
+ }
+
+ private static string RepositoryRoot()
+ {
+ DirectoryInfo? current = new(AppContext.BaseDirectory);
+ while (current is not null)
+ {
+ if (File.Exists(Path.Combine(current.FullName, "AgentSandboxMcp.slnx"))) return current.FullName;
+ current = current.Parent;
+ }
+ throw new DirectoryNotFoundException("Repository root was not found.");
+ }
+}
diff --git a/tests/Agent.Windows.Tests/Agent.Windows.Tests.csproj b/tests/Agent.Windows.Tests/Agent.Windows.Tests.csproj
index 7888f53..ec4f87f 100644
--- a/tests/Agent.Windows.Tests/Agent.Windows.Tests.csproj
+++ b/tests/Agent.Windows.Tests/Agent.Windows.Tests.csproj
@@ -6,6 +6,7 @@
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
</PropertyGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\src\Agent.Admin\Agent.Admin.Host\Agent.Admin.Host.csproj" />
<ProjectReference Include="..\..\src\Agent.Windows\Agent.Windows.csproj" />
<ProjectReference Include="..\..\src\Agent.App\Agent.App.csproj" />
</ItemGroup>
diff --git a/tests/Agent.Windows.Tests/CrashScenarioBootstrap.cs b/tests/Agent.Windows.Tests/CrashScenarioBootstrap.cs
index 6686833..d3224f4 100644
--- a/tests/Agent.Windows.Tests/CrashScenarioBootstrap.cs
+++ b/tests/Agent.Windows.Tests/CrashScenarioBootstrap.cs
@@ -80,7 +80,9 @@ internal static class CrashScenarioBootstrap
edit.Rollback();
break;
case "wfp":
- _ = TaskNetworkPolicy.Apply(journal, AppContainerProfile.EnsureFixed().Sid, [], new MemorySecurityAuditSink());
+ _ = TaskNetworkPolicy.ApplyAsync(new DirectElevatedNetworkSession(), journal,
+ AppContainerProfile.EnsureFixed().Sid, "none", [], new MemorySecurityAuditSink(), null,
+ CancellationToken.None).GetAwaiter().GetResult();
break;
default:
throw new InvalidOperationException($"Unknown crash scenario '{scenario}'.");
diff --git a/tests/Agent.Windows.Tests/DirectElevatedNetworkSession.cs b/tests/Agent.Windows.Tests/DirectElevatedNetworkSession.cs
new file mode 100644
index 0000000..b194ed1
--- /dev/null
+++ b/tests/Agent.Windows.Tests/DirectElevatedNetworkSession.cs
@@ -0,0 +1,75 @@
+using System.Net;
+using System.Security.Principal;
+using Agent.Admin.Client;
+using Agent.Admin.Host;
+
+namespace Agent.Windows.Tests;
+
+internal sealed class DirectElevatedNetworkSession : IElevatedNetworkSession
+{
+ private WfpDynamicSession? _wfp;
+ private SecurityIdentifier? _sid;
+ private bool _loopbackAdded;
+
+ public Task<bool> InspectLoopbackAsync(string applicationSid, CancellationToken cancellationToken) =>
+ Task.FromResult(LoopbackExemption.Contains(new SecurityIdentifier(applicationSid)));
+
+ public Task ApplyAsync(string applicationSid, string networkAccess, IReadOnlyList<AdminNetworkEndpoint> endpoints,
+ bool originallyLoopbackExempt, CancellationToken cancellationToken)
+ {
+ _sid = new(applicationSid);
+ NetworkEndpoint[] values = endpoints.Select(static item => new NetworkEndpoint(IPAddress.Parse(item.Address), (ushort)item.Port)).ToArray();
+ _wfp = WfpDynamicSession.Open();
+ _wfp.ApplyDefaultBlock(_sid, values);
+ if (values.Any(static item => IPAddress.IsLoopback(item.Address)) && !originallyLoopbackExempt)
+ _loopbackAdded = LoopbackExemption.Ensure(_sid);
+ return Task.CompletedTask;
+ }
+
+ public Task RecoverLoopbackAsync(string applicationSid, bool originallyLoopbackExempt, CancellationToken cancellationToken)
+ {
+ var sid = new SecurityIdentifier(applicationSid);
+ if (originallyLoopbackExempt) _ = LoopbackExemption.Ensure(sid); else LoopbackExemption.Remove(sid);
+ return Task.CompletedTask;
+ }
+
+ public Task CleanupAsync(CancellationToken cancellationToken)
+ {
+ if (_loopbackAdded && _sid is not null) LoopbackExemption.Remove(_sid);
+ _loopbackAdded = false;
+ if (_wfp is not null) { _wfp.RemovePolicy(); _wfp.Dispose(); _wfp = null; }
+ return Task.CompletedTask;
+ }
+
+ public async ValueTask DisposeAsync() => await CleanupAsync(CancellationToken.None).ConfigureAwait(false);
+}
+
+internal sealed class DirectElevatedNetworkSessionFactory : IElevatedNetworkSessionFactory
+{
+ public int Starts { get; private set; }
+ public Task<IElevatedNetworkSession> StartAsync(Guid taskId, CancellationToken cancellationToken)
+ {
+ Starts++;
+ return Task.FromResult<IElevatedNetworkSession>(new DirectElevatedNetworkSession());
+ }
+}
+
+internal sealed class NoOpElevatedNetworkSessionFactory : IElevatedNetworkSessionFactory
+{
+ public int Starts { get; private set; }
+ public Task<IElevatedNetworkSession> StartAsync(Guid taskId, CancellationToken cancellationToken)
+ {
+ Starts++;
+ return Task.FromResult<IElevatedNetworkSession>(new NoOpElevatedNetworkSession());
+ }
+
+ private sealed class NoOpElevatedNetworkSession : IElevatedNetworkSession
+ {
+ public Task<bool> InspectLoopbackAsync(string applicationSid, CancellationToken cancellationToken) => Task.FromResult(false);
+ public Task ApplyAsync(string applicationSid, string networkAccess, IReadOnlyList<AdminNetworkEndpoint> endpoints,
+ bool originallyLoopbackExempt, CancellationToken cancellationToken) => Task.CompletedTask;
+ public Task RecoverLoopbackAsync(string applicationSid, bool originallyLoopbackExempt, CancellationToken cancellationToken) => Task.CompletedTask;
+ public Task CleanupAsync(CancellationToken cancellationToken) => Task.CompletedTask;
+ public ValueTask DisposeAsync() => ValueTask.CompletedTask;
+ }
+}
diff --git a/tests/Agent.Windows.Tests/ReadmeOperationalTests.cs b/tests/Agent.Windows.Tests/ReadmeOperationalTests.cs
index fd70f06..5240feb 100644
--- a/tests/Agent.Windows.Tests/ReadmeOperationalTests.cs
+++ b/tests/Agent.Windows.Tests/ReadmeOperationalTests.cs
@@ -381,11 +381,12 @@ public sealed class ReadmeOperationalTests
string journalRoot = Path.Combine(Path.GetTempPath(), "agent-mcp-readme-network", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(journalRoot);
TaskResourceJournal journal = TaskResourceJournal.Create(journalRoot, scope.TaskId);
- return new(journal, TaskNetworkPolicy.Apply(journal, scope.Profile.Sid, endpoints, scope.Audit));
+ return new(journal, TaskNetworkPolicy.ApplyAsync(new DirectElevatedNetworkSession(), journal, scope.Profile.Sid,
+ endpoints.Count == 0 ? "none" : "local", endpoints, scope.Audit, null, CancellationToken.None).GetAwaiter().GetResult());
}
public void Dispose()
{
- _policy.Dispose();
+ _policy.DisposeAsync().AsTask().GetAwaiter().GetResult();
_journal.CompleteAndDelete();
string? root = Path.GetDirectoryName(_journal.Path);
if (root is not null && Directory.Exists(root)) Directory.Delete(root, true);
diff --git a/tests/Agent.Windows.Tests/SecurityPolicyTests.cs b/tests/Agent.Windows.Tests/SecurityPolicyTests.cs
index 6dbc9ab..5b10417 100644
--- a/tests/Agent.Windows.Tests/SecurityPolicyTests.cs
+++ b/tests/Agent.Windows.Tests/SecurityPolicyTests.cs
@@ -11,6 +11,8 @@ using Agent.Core.Tools;
using System.Text.Json;
using Agent.App.Sandbox;
using Agent.App.Configuration;
+using LoopbackExemption = Agent.Admin.Host.LoopbackExemption;
+using WfpDynamicSession = Agent.Admin.Host.WfpDynamicSession;
namespace Agent.Windows.Tests;
@@ -793,7 +795,7 @@ public sealed class SecurityPolicyTests
try
{
- RecoveryResult recovered = new RecoveryManager(journals, audit).RecoverAll();
+ RecoveryResult recovered = new RecoveryManager(journals, audit, new DirectElevatedNetworkSessionFactory()).RecoverAll();
Assert.True(recovered.IsClean);
Assert.Equal(1, recovered.JournalsRecovered);
@@ -957,7 +959,8 @@ public sealed class SecurityPolicyTests
session.ProbeWriteTransaction();
IReadOnlyList<ulong> ids = session.ApplyDefaultBlock(profile.Sid,
- [new NetworkEndpoint(IPAddress.Loopback, 11434), new NetworkEndpoint(IPAddress.IPv6Loopback, 11434)]);
+ [new Agent.Admin.Host.NetworkEndpoint(IPAddress.Loopback, 11434),
+ new Agent.Admin.Host.NetworkEndpoint(IPAddress.IPv6Loopback, 11434)]);
Assert.Equal(4, ids.Count);
Assert.All(ids, id => Assert.NotEqual(0UL, id));
@@ -965,7 +968,7 @@ public sealed class SecurityPolicyTests
}
[Fact]
- public async Task Windows_backend_applies_file_effect_and_cleans_acl_wfp_temp_and_journal()
+ public async Task Windows_backend_file_only_effect_does_not_apply_acl_or_network_resources()
{
using TestDirectory directory = new();
string workspace = Path.Combine(directory.Path, "workspace");
@@ -978,7 +981,8 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write | FileCapability.Delete)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var elevated = new DirectElevatedNetworkSessionFactory();
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: elevated);
Guid taskId = Guid.NewGuid();
Guid sessionId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, sessionId, TestContext.Current.CancellationToken);
@@ -995,13 +999,13 @@ public sealed class SecurityPolicyTests
Assert.Empty(Directory.EnumerateFiles(Path.Combine(directory.Path, "journals")));
string backups = Path.Combine(directory.Path, "backups");
Assert.True(!Directory.Exists(backups) || !Directory.EnumerateFileSystemEntries(backups).Any());
- Assert.Contains(audit.Events, item => item.Event == "network.rule.remove" && item.Data["residual_filters"] == "0");
+ Assert.Equal(0, elevated.Starts);
+ Assert.DoesNotContain(audit.Events, item => item.Event is "network.rule.apply" or "network.rule.remove");
Assert.Contains(audit.Events, item => item.Event == "task.start" && item.SessionId == sessionId);
Assert.Contains(audit.Events, item => item.Event == "tool.call" && item.SessionId == sessionId);
Assert.Contains(audit.Events, item => item.Event == "file.write" && item.SessionId == sessionId);
Assert.Contains(audit.Events, item => item.Event == "task.end" && item.SessionId == sessionId);
- Assert.Single(audit.Events, item => item.Event == "acl.apply");
- Assert.Single(audit.Events, item => item.Event == "acl.restore");
+ Assert.DoesNotContain(audit.Events, item => item.Event is "acl.apply" or "acl.restore");
}
[Fact]
@@ -1023,7 +1027,7 @@ public sealed class SecurityPolicyTests
[new ApprovedEntryExecutable("cmd", cmd, EntryExecutablePolicy.ComputeSha256(cmd), true, null)], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000, BaselineCapabilities: ["registryRead", "lpacInstrumentation"]);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
@@ -1042,6 +1046,34 @@ public sealed class SecurityPolicyTests
}
[Fact]
+ public async Task File_only_task_does_not_start_the_elevated_helper()
+ {
+ using TestDirectory directory = new();
+ string workspace = Path.Combine(directory.Path, "workspace");
+ Directory.CreateDirectory(workspace);
+ string input = Path.Combine(workspace, "input.txt");
+ File.WriteAllText(input, "read-only operation");
+ var factory = new NoOpElevatedNetworkSessionFactory();
+ var settings = new EffectiveSandboxPolicy(
+ [new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write | FileCapability.Delete | FileCapability.Execute, "workspace")],
+ [], [], [workspace], new SandboxJobLimits(), "none", [],
+ Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
+ 16 * 1024 * 1024, 1024 * 1024, 1000, 10000,
+ BaselineCapabilities: ["registryRead", "lpacInstrumentation"]);
+ var backend = new WindowsToolBackend(settings, new MemorySecurityAuditSink(), elevatedNetwork: factory);
+ Guid taskId = Guid.NewGuid();
+
+ await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
+ using JsonDocument read = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(input)}},"mode":"whole"}""");
+ ToolExecutionResult result = await backend.ExecuteAsync(taskId, "file_read", read.RootElement,
+ TestContext.Current.CancellationToken);
+ await backend.EndTaskAsync(taskId, result.Success, TestContext.Current.CancellationToken);
+
+ Assert.True(result.Success);
+ Assert.Equal(0, factory.Starts);
+ }
+
+ [Fact]
public async Task Dir_mkdir_creates_directory_within_approved_root_and_cleans_up()
{
using TestDirectory directory = new();
@@ -1054,7 +1086,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write | FileCapability.Delete)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument mkdir = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(target)}},"operation":"mkdir"}""");
@@ -1085,7 +1117,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write | FileCapability.Delete)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument rmdir = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(target)}},"operation":"rmdir"}""");
@@ -1113,7 +1145,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write | FileCapability.Delete)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument rmdir = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(target)}},"operation":"rmdir"}""");
@@ -1140,7 +1172,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument list = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(workspace)}},"operation":"list"}""");
@@ -1166,7 +1198,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
string badTarget = Path.Combine(outside.Path, "escaped");
@@ -1192,7 +1224,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument tail = JsonDocument.Parse($$"""{"root":{{JsonSerializer.Serialize(binaryFile)}},"mode":"tail","query":"","tail_lines":10}""");
@@ -1231,7 +1263,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument tail = JsonDocument.Parse($$"""{"root":{{JsonSerializer.Serialize(textFile)}},"mode":"tail","query":"","tail_lines":10}""");
@@ -1256,7 +1288,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write | FileCapability.Delete)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument rename = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(source)}},"operation":"rename","new_path":{{JsonSerializer.Serialize(dest)}}}""");
@@ -1287,7 +1319,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument rename = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(source)}},"operation":"rename","new_path":{{JsonSerializer.Serialize(dest)}}}""");
@@ -1317,7 +1349,7 @@ public sealed class SecurityPolicyTests
[new FilePolicyEntry(workspace, FileCapability.Read | FileCapability.Write)], [], [], [],
new SandboxJobLimits(), "none", [], Path.Combine(directory.Path, "journals"), Path.Combine(directory.Path, "backups"),
16 * 1024 * 1024, 1024 * 1024, 1000, 10000);
- var backend = new WindowsToolBackend(settings, audit);
+ var backend = new WindowsToolBackend(settings, audit, elevatedNetwork: new DirectElevatedNetworkSessionFactory());
Guid taskId = Guid.NewGuid();
await backend.BeginTaskAsync(taskId, Guid.NewGuid(), TestContext.Current.CancellationToken);
using JsonDocument rename = JsonDocument.Parse($$"""{"path":{{JsonSerializer.Serialize(source)}},"operation":"rename","new_path":{{JsonSerializer.Serialize(dest)}}}""");
@@ -1358,7 +1390,8 @@ public sealed class SecurityPolicyTests
{
Guid taskId = Guid.NewGuid();
TaskResourceJournal journal = TaskResourceJournal.Create(Path.Combine(directory.Path, "deny-journal"), taskId);
- using (TaskNetworkPolicy.Apply(journal, profile.Sid, [], audit))
+ await using (await TaskNetworkPolicy.ApplyAsync(new DirectElevatedNetworkSession(), journal, profile.Sid,
+ "none", [], audit, null, TestContext.Current.CancellationToken))
{
RestrictedProcessResult denied = Curl(launcher, taskId, curl, deniedServer.Url, Environment.SystemDirectory);
Assert.NotEqual(0u, denied.ExitCode);
@@ -1383,7 +1416,8 @@ public sealed class SecurityPolicyTests
[
new(allowedAddress, checked((ushort)allowedV4.Port))
];
- using (TaskNetworkPolicy.Apply(allowJournal, profile.Sid, allowances, audit))
+ await using (await TaskNetworkPolicy.ApplyAsync(new DirectElevatedNetworkSession(), allowJournal, profile.Sid,
+ "local", allowances, audit, null, TestContext.Current.CancellationToken))
{
RestrictedProcessResult v4 = Curl(launcher, allowTaskId, curl, allowedV4.Url, Environment.SystemDirectory);
RestrictedProcessResult wrongPort = Curl(launcher, allowTaskId, curl, deniedPort.Url, Environment.SystemDirectory);