LumaTunnel
【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。
关注
0
Fork
0
Star
0
using System.Net;
using LumaTunnel.Server.Core.Configuration;
using LumaTunnel.Server.Core.Persistence;
using LumaTunnel.Server.Core.Security;
using LumaTunnel.Shared.Protocol;
namespace LumaTunnel.Server.Tests;
public sealed class SecurityTests
{
[Fact]
public void DeviceTokenIs256BitsAndFixedTimeHashValidationWorks()
{
var token = TokenUtilities.CreateDeviceToken();
var hash = TokenUtilities.Hash(token);
Assert.Equal(43, token.Length);
Assert.True(TokenUtilities.FixedTimeHashEquals(token, hash));
Assert.False(TokenUtilities.FixedTimeHashEquals(token + "x", hash));
Assert.False(TokenUtilities.FixedTimeHashEquals(token, new string('z', 64)));
}
[Theory]
[InlineData("127.0.0.1")]
[InlineData("10.1.2.3")]
[InlineData("169.254.1.1")]
[InlineData("192.168.10.20")]
[InlineData("::1")]
[InlineData("fe80::1")]
public void PrivateTargetsAreBlocked(string value)
{
var policy = new TargetPolicy(new ServerSettings());
Assert.False(policy.IsAllowed(IPAddress.Parse(value)));
}
[Fact]
public async Task PairingCodeCanOnlyBeConsumedOnce()
{
var root = Path.Combine(Path.GetTempPath(), "LumaTunnel.Tests", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(root);
try
{
var service = new PairingCodeService(new AtomicJsonStore<PairingCodeDatabase>(Path.Combine(root, "pairing.json")));
await service.InitializeAsync();
var created = await service.CreateAsync(TimeSpan.FromMinutes(10));
Assert.True(await service.ConsumeAsync(created.Code));
Assert.False(await service.ConsumeAsync(created.Code));
}
finally
{
Directory.Delete(root, true);
}
}
[Fact]
public async Task Port25IsBlockedBeforeDnsResolution()
{
var policy = new TargetPolicy(new ServerSettings());
var exception = await Assert.ThrowsAsync<TunnelProtocolException>(() => policy.ResolveAndValidateAsync("example.invalid", 25));
Assert.Equal(TunnelErrorCode.TargetBlocked, exception.Code);
}
}
using System.Net;
using LumaTunnel.Server.Core.Configuration;
using LumaTunnel.Server.Core.Persistence;
using LumaTunnel.Server.Core.Security;
using LumaTunnel.Shared.Protocol;
namespace LumaTunnel.Server.Tests;
public sealed class SecurityTests
{
[Fact]
public void DeviceTokenIs256BitsAndFixedTimeHashValidationWorks()
{
var token = TokenUtilities.CreateDeviceToken();
var hash = TokenUtilities.Hash(token);
Assert.Equal(43, token.Length);
Assert.True(TokenUtilities.FixedTimeHashEquals(token, hash));
Assert.False(TokenUtilities.FixedTimeHashEquals(token + "x", hash));
Assert.False(TokenUtilities.FixedTimeHashEquals(token, new string('z', 64)));
}
[Theory]
[InlineData("127.0.0.1")]
[InlineData("10.1.2.3")]
[InlineData("169.254.1.1")]
[InlineData("192.168.10.20")]
[InlineData("::1")]
[InlineData("fe80::1")]
public void PrivateTargetsAreBlocked(string value)
{
var policy = new TargetPolicy(new ServerSettings());
Assert.False(policy.IsAllowed(IPAddress.Parse(value)));
}
[Fact]
public async Task PairingCodeCanOnlyBeConsumedOnce()
{
var root = Path.Combine(Path.GetTempPath(), "LumaTunnel.Tests", Guid.NewGuid().ToString("N"));
Directory.CreateDirectory(root);
try
{
var service = new PairingCodeService(new AtomicJsonStore<PairingCodeDatabase>(Path.Combine(root, "pairing.json")));
await service.InitializeAsync();
var created = await service.CreateAsync(TimeSpan.FromMinutes(10));
Assert.True(await service.ConsumeAsync(created.Code));
Assert.False(await service.ConsumeAsync(created.Code));
}
finally
{
Directory.Delete(root, true);
}
}
[Fact]
public async Task Port25IsBlockedBeforeDnsResolution()
{
var policy = new TargetPolicy(new ServerSettings());
var exception = await Assert.ThrowsAsync<TunnelProtocolException>(() => policy.ResolveAndValidateAsync("example.invalid", 25));
Assert.Equal(TunnelErrorCode.TargetBlocked, exception.Code);
}
}