XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

LumaTunnel

【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。

公开
关注 0 Fork 0 Star 0
UTF-8
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);
    }
}