mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-14 19:45:45 +00:00
Compare commits
9 commits
095baa7d95
...
907b55e401
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
907b55e401 | ||
|
|
2918cc92ac | ||
|
|
7329dbae11 | ||
|
|
695a073cd6 | ||
|
|
01c85adedf | ||
|
|
2caf8ea14f | ||
|
|
1090afd774 | ||
|
|
c758c5abf9 | ||
|
|
c61b023ab3 |
28 changed files with 248 additions and 40 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
<Project>
|
<Project>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Version>7.19.5</Version>
|
<Version>7.20.1</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="11.4.1" />
|
<PackageVersion Include="Avalonia.AvaloniaEdit" Version="11.4.1" />
|
||||||
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.12" />
|
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.3.13" />
|
||||||
<PackageVersion Include="Avalonia.Desktop" Version="11.3.12" />
|
<PackageVersion Include="Avalonia.Desktop" Version="11.3.13" />
|
||||||
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.12" />
|
<PackageVersion Include="Avalonia.Diagnostics" Version="11.3.13" />
|
||||||
<PackageVersion Include="ReactiveUI.Avalonia" Version="11.4.12" />
|
<PackageVersion Include="ReactiveUI.Avalonia" Version="11.4.12" />
|
||||||
<PackageVersion Include="CliWrap" Version="3.10.0" />
|
<PackageVersion Include="CliWrap" Version="3.10.1" />
|
||||||
<PackageVersion Include="Downloader" Version="5.1.0" />
|
<PackageVersion Include="Downloader" Version="5.1.0" />
|
||||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" />
|
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" />
|
||||||
<PackageVersion Include="MaterialDesignThemes" Version="5.3.1" />
|
<PackageVersion Include="MaterialDesignThemes" Version="5.3.1" />
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ public static class ConfigHandler
|
||||||
EnableTun = false,
|
EnableTun = false,
|
||||||
Mtu = 9000,
|
Mtu = 9000,
|
||||||
IcmpRouting = Global.TunIcmpRoutingPolicies.First(),
|
IcmpRouting = Global.TunIcmpRoutingPolicies.First(),
|
||||||
|
EnableLegacyProtect = false,
|
||||||
};
|
};
|
||||||
config.GuiItem ??= new();
|
config.GuiItem ??= new();
|
||||||
config.MsgUIItem ??= new();
|
config.MsgUIItem ??= new();
|
||||||
|
|
@ -1414,19 +1415,32 @@ public static class ConfigHandler
|
||||||
/// <returns>A SOCKS profile item or null if not needed</returns>
|
/// <returns>A SOCKS profile item or null if not needed</returns>
|
||||||
public static ProfileItem? GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType)
|
public static ProfileItem? GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType)
|
||||||
{
|
{
|
||||||
if (node.ConfigType != EConfigType.Custom || !(node.PreSocksPort > 0))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
ProfileItem? itemSocks = null;
|
ProfileItem? itemSocks = null;
|
||||||
var preCoreType = AppManager.Instance.RunningCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray;
|
if (node.ConfigType != EConfigType.Custom
|
||||||
itemSocks = new ProfileItem()
|
&& coreType != ECoreType.sing_box
|
||||||
|
&& config.TunModeItem.EnableTun
|
||||||
|
&& config.TunModeItem.EnableLegacyProtect)
|
||||||
{
|
{
|
||||||
CoreType = preCoreType,
|
itemSocks = new ProfileItem()
|
||||||
ConfigType = EConfigType.SOCKS,
|
{
|
||||||
Address = Global.Loopback,
|
CoreType = ECoreType.sing_box,
|
||||||
Port = node.PreSocksPort.Value,
|
ConfigType = EConfigType.SOCKS,
|
||||||
};
|
Address = Global.Loopback,
|
||||||
|
Port = AppManager.Instance.GetLocalPort(EInboundProtocol.socks)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (node.ConfigType == EConfigType.Custom
|
||||||
|
&& node.PreSocksPort is > 0 and <= 65535)
|
||||||
|
{
|
||||||
|
var preCoreType = config.TunModeItem.EnableTun ? ECoreType.sing_box : ECoreType.Xray;
|
||||||
|
itemSocks = new ProfileItem()
|
||||||
|
{
|
||||||
|
CoreType = preCoreType,
|
||||||
|
ConfigType = EConfigType.SOCKS,
|
||||||
|
Address = Global.Loopback,
|
||||||
|
Port = node.PreSocksPort.Value,
|
||||||
|
};
|
||||||
|
}
|
||||||
return itemSocks;
|
return itemSocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ public class CertPemManager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get certificate in PEM format from a server with CA pinning validation
|
/// Get certificate in PEM format from a server with CA pinning validation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<(string?, string?)> GetCertPemAsync(string target, string serverName, int timeout = 4)
|
public async Task<(string?, string?)> GetCertPemAsync(string target, string serverName, int timeout = 4, bool allowInsecure = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -215,12 +215,14 @@ public class CertPemManager
|
||||||
using var client = new TcpClient();
|
using var client = new TcpClient();
|
||||||
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
|
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
|
||||||
|
|
||||||
await using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
|
var callback = new RemoteCertificateValidationCallback((sender, certificate, chain, sslPolicyErrors) =>
|
||||||
|
ValidateServerCertificate(sender, certificate, chain, sslPolicyErrors, allowInsecure));
|
||||||
|
await using var ssl = new SslStream(client.GetStream(), false, callback);
|
||||||
|
|
||||||
var sslOptions = new SslClientAuthenticationOptions
|
var sslOptions = new SslClientAuthenticationOptions
|
||||||
{
|
{
|
||||||
TargetHost = serverName,
|
TargetHost = serverName,
|
||||||
RemoteCertificateValidationCallback = ValidateServerCertificate
|
RemoteCertificateValidationCallback = callback
|
||||||
};
|
};
|
||||||
|
|
||||||
await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token);
|
await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token);
|
||||||
|
|
@ -249,7 +251,7 @@ public class CertPemManager
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get certificate chain in PEM format from a server with CA pinning validation
|
/// Get certificate chain in PEM format from a server with CA pinning validation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<(List<string>, string?)> GetCertChainPemAsync(string target, string serverName, int timeout = 4)
|
public async Task<(List<string>, string?)> GetCertChainPemAsync(string target, string serverName, int timeout = 4, bool allowInsecure = false)
|
||||||
{
|
{
|
||||||
var pemList = new List<string>();
|
var pemList = new List<string>();
|
||||||
try
|
try
|
||||||
|
|
@ -262,12 +264,14 @@ public class CertPemManager
|
||||||
using var client = new TcpClient();
|
using var client = new TcpClient();
|
||||||
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
|
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
|
||||||
|
|
||||||
await using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
|
var callback = new RemoteCertificateValidationCallback((sender, certificate, chain, sslPolicyErrors) =>
|
||||||
|
ValidateServerCertificate(sender, certificate, chain, sslPolicyErrors, allowInsecure));
|
||||||
|
await using var ssl = new SslStream(client.GetStream(), false, callback);
|
||||||
|
|
||||||
var sslOptions = new SslClientAuthenticationOptions
|
var sslOptions = new SslClientAuthenticationOptions
|
||||||
{
|
{
|
||||||
TargetHost = serverName,
|
TargetHost = serverName,
|
||||||
RemoteCertificateValidationCallback = ValidateServerCertificate
|
RemoteCertificateValidationCallback = callback
|
||||||
};
|
};
|
||||||
|
|
||||||
await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token);
|
await ssl.AuthenticateAsClientAsync(sslOptions, cts.Token);
|
||||||
|
|
@ -300,16 +304,23 @@ public class CertPemManager
|
||||||
/// Validate server certificate with CA pinning
|
/// Validate server certificate with CA pinning
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool ValidateServerCertificate(
|
private bool ValidateServerCertificate(
|
||||||
object sender,
|
object _,
|
||||||
X509Certificate? certificate,
|
X509Certificate? certificate,
|
||||||
X509Chain? chain,
|
X509Chain? chain,
|
||||||
SslPolicyErrors sslPolicyErrors)
|
SslPolicyErrors sslPolicyErrors,
|
||||||
|
bool allowInsecure)
|
||||||
{
|
{
|
||||||
if (certificate == null)
|
if (certificate == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In insecure mode, accept any certificate so self-signed certs can be fetched.
|
||||||
|
if (allowInsecure)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check certificate name mismatch
|
// Check certificate name mismatch
|
||||||
if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch))
|
if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,9 @@ public class CoreManager
|
||||||
|
|
||||||
await CoreStart(mainContext);
|
await CoreStart(mainContext);
|
||||||
await CoreStartPreService(preContext);
|
await CoreStartPreService(preContext);
|
||||||
|
|
||||||
|
AppManager.Instance.RunningCoreType = preContext?.RunCoreType ?? mainContext.RunCoreType;
|
||||||
|
|
||||||
if (_processService != null)
|
if (_processService != null)
|
||||||
{
|
{
|
||||||
await UpdateFunc(true, $"{node.GetSummary()}");
|
await UpdateFunc(true, $"{node.GetSummary()}");
|
||||||
|
|
@ -172,7 +175,7 @@ public class CoreManager
|
||||||
private async Task CoreStart(CoreConfigContext context)
|
private async Task CoreStart(CoreConfigContext context)
|
||||||
{
|
{
|
||||||
var node = context.Node;
|
var node = context.Node;
|
||||||
var coreType = AppManager.Instance.RunningCoreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
|
var coreType = AppManager.Instance.GetCoreType(node, node.ConfigType);
|
||||||
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(coreType);
|
var coreInfo = CoreInfoManager.Instance.GetCoreInfo(coreType);
|
||||||
|
|
||||||
var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
|
var displayLog = node.ConfigType != EConfigType.Custom || node.DisplayLog;
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,7 @@ public class TunModeItem
|
||||||
public int Mtu { get; set; }
|
public int Mtu { get; set; }
|
||||||
public bool EnableIPv6Address { get; set; }
|
public bool EnableIPv6Address { get; set; }
|
||||||
public string IcmpRouting { get; set; }
|
public string IcmpRouting { get; set; }
|
||||||
|
public bool EnableLegacyProtect { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
|
|
|
||||||
27
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
27
v2rayN/ServiceLib/Resx/ResUI.Designer.cs
generated
|
|
@ -2571,6 +2571,24 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Allow insecure cert fetch (self-signed) 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbAllowInsecureCertFetch {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbAllowInsecureCertFetch", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Only for fetching self-signed certificates. This may expose you to MITM risks. 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbAllowInsecureCertFetchTips {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbAllowInsecureCertFetchTips", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 ALPN 的本地化字符串。
|
/// 查找类似 ALPN 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -3150,6 +3168,15 @@ namespace ServiceLib.Resx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找类似 Legacy TUN Protect 的本地化字符串。
|
||||||
|
/// </summary>
|
||||||
|
public static string TbLegacyProtect {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TbLegacyProtect", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查找类似 Address (IPv4, IPv6) 的本地化字符串。
|
/// 查找类似 Address (IPv4, IPv6) 的本地化字符串。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1695,4 +1695,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP routing policy</value>
|
<value>ICMP routing policy</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>Legacy TUN Protect</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>Allow insecure cert fetch (self-signed)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1692,4 +1692,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP routing policy</value>
|
<value>ICMP routing policy</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>Legacy TUN Protect</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>Allow insecure cert fetch (self-signed)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1695,4 +1695,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP routing policy</value>
|
<value>ICMP routing policy</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>Legacy TUN Protect</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>Allow insecure cert fetch (self-signed)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1695,4 +1695,13 @@ The "Get Certificate" action may fail if a self-signed certificate is used or if
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP routing policy</value>
|
<value>ICMP routing policy</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>Legacy TUN Protect</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>Allow insecure cert fetch (self-signed)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1695,4 +1695,13 @@
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP routing policy</value>
|
<value>ICMP routing policy</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>Legacy TUN Protect</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>Allow insecure cert fetch (self-signed)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>Only for fetching self-signed certificates. This may expose you to MITM risks.</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
|
|
@ -1692,4 +1692,13 @@
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP 路由策略</value>
|
<value>ICMP 路由策略</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>旧版 TUN 保护</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>允许不安全获取证书(自签名)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>仅用于抓取自签证书,存在中间人风险。</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
@ -1692,4 +1692,13 @@
|
||||||
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
<data name="TbIcmpRoutingPolicy" xml:space="preserve">
|
||||||
<value>ICMP 路由策略</value>
|
<value>ICMP 路由策略</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
<data name="TbLegacyProtect" xml:space="preserve">
|
||||||
|
<value>Legacy TUN Protect</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetch" xml:space="preserve">
|
||||||
|
<value>允許不安全獲取證書(自簽名)</value>
|
||||||
|
</data>
|
||||||
|
<data name="TbAllowInsecureCertFetchTips" xml:space="preserve">
|
||||||
|
<value>僅用於抓取自簽證書,存在中間人風險。</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
|
|
@ -61,7 +61,8 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
|
|
||||||
ret.Data = ApplyFullConfigTemplate();
|
ret.Data = ApplyFullConfigTemplate();
|
||||||
if (context.TunProtectSsPort is > 0 and <= 65535)
|
if (!context.AppConfig.TunModeItem.EnableLegacyProtect
|
||||||
|
&& context.TunProtectSsPort is > 0 and <= 65535)
|
||||||
{
|
{
|
||||||
var ssInbound = new
|
var ssInbound = new
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ public partial class CoreConfigSingboxService
|
||||||
}
|
}
|
||||||
if (withSelector)
|
if (withSelector)
|
||||||
{
|
{
|
||||||
var proxyTags = proxyOutboundList.Where(n => n.tag.StartsWith(Global.ProxyTag)).Select(n => n.tag).ToList();
|
var proxyTags = proxyOutboundList.Where(n => n.tag.StartsWith(baseTagName)).Select(n => n.tag).ToList();
|
||||||
if (proxyTags.Count > 1)
|
if (proxyTags.Count > 1)
|
||||||
{
|
{
|
||||||
proxyOutboundList.InsertRange(0, BuildSelectorOutbounds(proxyTags, baseTagName));
|
proxyOutboundList.InsertRange(0, BuildSelectorOutbounds(proxyTags, baseTagName));
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (context.IsTunEnabled && context.TunProtectSsPort > 0 && context.ProxyRelaySsPort > 0)
|
if (!context.AppConfig.TunModeItem.EnableLegacyProtect
|
||||||
|
&& context.IsTunEnabled
|
||||||
|
&& context.TunProtectSsPort is > 0 and <= 65535
|
||||||
|
&& context.ProxyRelaySsPort is > 0 and <= 65535)
|
||||||
{
|
{
|
||||||
return GenerateClientProxyRelayConfig();
|
return GenerateClientProxyRelayConfig();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,9 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public bool NaiveQuic { get; set; }
|
public bool NaiveQuic { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool AllowInsecureCertFetch { get; set; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
|
public ReactiveCommand<Unit, Unit> FetchCertCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
|
public ReactiveCommand<Unit, Unit> FetchCertChainCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
@ -272,7 +275,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
domain += $":{SelectedSource.Port}";
|
domain += $":{SelectedSource.Port}";
|
||||||
}
|
}
|
||||||
|
|
||||||
(Cert, var certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName);
|
(Cert, var certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName, allowInsecure: AllowInsecureCertFetch);
|
||||||
UpdateCertTip(certError);
|
UpdateCertTip(certError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,7 +300,7 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
domain += $":{SelectedSource.Port}";
|
domain += $":{SelectedSource.Port}";
|
||||||
}
|
}
|
||||||
|
|
||||||
var (certs, certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName);
|
var (certs, certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName, allowInsecure: AllowInsecureCertFetch);
|
||||||
Cert = CertPemManager.ConcatenatePemChain(certs);
|
Cert = CertPemManager.ConcatenatePemChain(certs);
|
||||||
UpdateCertTip(certError);
|
UpdateCertTip(certError);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||||
[Reactive] public int TunMtu { get; set; }
|
[Reactive] public int TunMtu { get; set; }
|
||||||
[Reactive] public bool TunEnableIPv6Address { get; set; }
|
[Reactive] public bool TunEnableIPv6Address { get; set; }
|
||||||
[Reactive] public string TunIcmpRouting { get; set; }
|
[Reactive] public string TunIcmpRouting { get; set; }
|
||||||
|
[Reactive] public bool TunEnableLegacyProtect { get; set; }
|
||||||
|
|
||||||
#endregion Tun mode
|
#endregion Tun mode
|
||||||
|
|
||||||
|
|
@ -220,6 +221,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||||
TunMtu = _config.TunModeItem.Mtu;
|
TunMtu = _config.TunModeItem.Mtu;
|
||||||
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
TunEnableIPv6Address = _config.TunModeItem.EnableIPv6Address;
|
||||||
TunIcmpRouting = _config.TunModeItem.IcmpRouting;
|
TunIcmpRouting = _config.TunModeItem.IcmpRouting;
|
||||||
|
TunEnableLegacyProtect = _config.TunModeItem.EnableLegacyProtect;
|
||||||
|
|
||||||
#endregion Tun mode
|
#endregion Tun mode
|
||||||
|
|
||||||
|
|
@ -379,6 +381,7 @@ public class OptionSettingViewModel : MyReactiveObject
|
||||||
_config.TunModeItem.Mtu = TunMtu;
|
_config.TunModeItem.Mtu = TunMtu;
|
||||||
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
_config.TunModeItem.EnableIPv6Address = TunEnableIPv6Address;
|
||||||
_config.TunModeItem.IcmpRouting = TunIcmpRouting;
|
_config.TunModeItem.IcmpRouting = TunIcmpRouting;
|
||||||
|
_config.TunModeItem.EnableLegacyProtect = TunEnableLegacyProtect;
|
||||||
|
|
||||||
//coreType
|
//coreType
|
||||||
await SaveCoreType();
|
await SaveCoreType();
|
||||||
|
|
|
||||||
|
|
@ -709,18 +709,22 @@ public class ProfilesViewModel : MyReactiveObject
|
||||||
|
|
||||||
public async Task ServerSpeedtest(ESpeedActionType actionType)
|
public async Task ServerSpeedtest(ESpeedActionType actionType)
|
||||||
{
|
{
|
||||||
if (actionType == ESpeedActionType.Mixedtest)
|
List<ProfileItem>? lstSelected;
|
||||||
|
if (actionType is ESpeedActionType.Mixedtest or ESpeedActionType.FastRealping)
|
||||||
{
|
{
|
||||||
SelectedProfiles = ProfileItems;
|
if (actionType == ESpeedActionType.FastRealping)
|
||||||
|
{
|
||||||
|
actionType = ESpeedActionType.Realping;
|
||||||
|
}
|
||||||
|
|
||||||
|
lstSelected = JsonUtils.Deserialize<List<ProfileItem>>(JsonUtils.Serialize(ProfileItems?.OrderBy(t => t.Sort)));
|
||||||
}
|
}
|
||||||
else if (actionType == ESpeedActionType.FastRealping)
|
else
|
||||||
{
|
{
|
||||||
SelectedProfiles = ProfileItems;
|
lstSelected = await GetProfileItems(false);
|
||||||
actionType = ESpeedActionType.Realping;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var lstSelected = await GetProfileItems(false);
|
if (lstSelected is null || lstSelected.Count <= 0)
|
||||||
if (lstSelected == null)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1008,6 +1008,25 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
Content="{x:Static resx:ResUI.TbFetchCertChain}" />
|
Content="{x:Static resx:ResUI.TbFetchCertChain}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbAllowInsecureCertFetch}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togAllowInsecureCertFetch"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock
|
||||||
|
x:Name="txtAllowInsecureCertFetchTips"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="#FFD32F2F"
|
||||||
|
IsVisible="False"
|
||||||
|
Text="{x:Static resx:ResUI.TbAllowInsecureCertFetchTips}"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
|
|
|
||||||
|
|
@ -214,6 +214,8 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
|
||||||
this.Bind(ViewModel, vm => vm.CertSha, v => v.txtCertSha256Pinning.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CertSha, v => v.txtCertSha256Pinning.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.AllowInsecureCertFetch, v => v.togAllowInsecureCertFetch.IsChecked).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.AllowInsecureCertFetch, v => v.txtAllowInsecureCertFetchTips.IsVisible).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.EchConfigList, v => v.txtEchConfigList.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.EchConfigList, v => v.txtEchConfigList.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.EchForceQuery, v => v.cmbEchForceQuery.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.EchForceQuery, v => v.cmbEchForceQuery.SelectedValue).DisposeWith(disposables);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -768,7 +768,7 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
ColumnDefinitions="Auto,Auto,Auto"
|
ColumnDefinitions="Auto,Auto,Auto"
|
||||||
DockPanel.Dock="Top"
|
DockPanel.Dock="Top"
|
||||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto">
|
||||||
|
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
|
|
@ -851,6 +851,18 @@
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{x:Static resx:ResUI.TbLegacyProtect}" />
|
||||||
|
<ToggleSwitch
|
||||||
|
x:Name="togEnableLegacyProtect"
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ public partial class OptionSettingWindow : WindowBase<OptionSettingViewModel>
|
||||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.SelectedValue).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.TunEnableLegacyProtect, v => v.togEnableLegacyProtect.IsChecked).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.SelectedValue).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.SelectedValue).DisposeWith(disposables);
|
||||||
|
|
|
||||||
|
|
@ -1269,6 +1269,27 @@
|
||||||
Content="{x:Static resx:ResUI.TbFetchCertChain}"
|
Content="{x:Static resx:ResUI.TbFetchCertChain}"
|
||||||
Style="{StaticResource DefButton}" />
|
Style="{StaticResource DefButton}" />
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbAllowInsecureCertFetch}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togAllowInsecureCertFetch"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
</StackPanel>
|
||||||
|
<TextBlock
|
||||||
|
x:Name="txtAllowInsecureCertFetchTips"
|
||||||
|
Width="400"
|
||||||
|
Margin="{StaticResource Margin4}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="#FFD32F2F"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbAllowInsecureCertFetchTips}"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
Visibility="Collapsed" />
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Width="400"
|
Width="400"
|
||||||
Margin="{StaticResource Margin4}"
|
Margin="{StaticResource Margin4}"
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,10 @@ public partial class AddServerWindow
|
||||||
this.Bind(ViewModel, vm => vm.CertSha, v => v.txtCertSha256Pinning.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CertSha, v => v.txtCertSha256Pinning.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CertTip, v => v.labCertPinning.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.AllowInsecureCertFetch, v => v.togAllowInsecureCertFetch.IsChecked).DisposeWith(disposables);
|
||||||
|
this.WhenAnyValue(x => x.ViewModel.AllowInsecureCertFetch)
|
||||||
|
.Select(b => b ? Visibility.Visible : Visibility.Collapsed)
|
||||||
|
.BindTo(this, v => v.txtAllowInsecureCertFetchTips.Visibility);
|
||||||
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.Cert, v => v.txtCert.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.EchConfigList, v => v.txtEchConfigList.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.EchConfigList, v => v.txtEchConfigList.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.SelectedSource.EchForceQuery, v => v.cmbEchForceQuery.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.SelectedSource.EchForceQuery, v => v.cmbEchForceQuery.Text).DisposeWith(disposables);
|
||||||
|
|
|
||||||
|
|
@ -1009,6 +1009,7 @@
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
<ColumnDefinition Width="Auto" />
|
||||||
|
|
@ -1105,6 +1106,20 @@
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
HorizontalAlignment="Left" />
|
HorizontalAlignment="Left" />
|
||||||
|
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Style="{StaticResource ToolbarTextBlock}"
|
||||||
|
Text="{x:Static resx:ResUI.TbLegacyProtect}" />
|
||||||
|
<ToggleButton
|
||||||
|
x:Name="togEnableLegacyProtect"
|
||||||
|
Grid.Row="8"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="{StaticResource Margin8}"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,7 @@ public partial class OptionSettingWindow
|
||||||
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunEnableIPv6Address, v => v.togEnableIPv6Address.IsChecked).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.TunIcmpRouting, v => v.cmbIcmpRoutingPolicy.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.TunEnableLegacyProtect, v => v.togEnableLegacyProtect.IsChecked).DisposeWith(disposables);
|
||||||
|
|
||||||
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);
|
||||||
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);
|
this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue