mirror of
https://github.com/2dust/v2rayN.git
synced 2026-03-05 23:53:22 +00:00
Compare commits
2 commits
6de5a5215d
...
753e7b81b6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
753e7b81b6 | ||
|
|
725b094fb1 |
3 changed files with 41 additions and 23 deletions
|
|
@ -14,7 +14,7 @@
|
||||||
<PackageVersion Include="Downloader" Version="4.0.3" />
|
<PackageVersion Include="Downloader" Version="4.0.3" />
|
||||||
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.2" />
|
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.3.2" />
|
||||||
<PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
|
<PackageVersion Include="MaterialDesignThemes" Version="5.3.0" />
|
||||||
<PackageVersion Include="MessageBox.Avalonia" Version="3.2.0" />
|
<PackageVersion Include="MessageBox.Avalonia" Version="3.3.0" />
|
||||||
<PackageVersion Include="QRCoder" Version="1.7.0" />
|
<PackageVersion Include="QRCoder" Version="1.7.0" />
|
||||||
<PackageVersion Include="ReactiveUI" Version="22.2.1" />
|
<PackageVersion Include="ReactiveUI" Version="22.2.1" />
|
||||||
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
<PackageVersion Include="ReactiveUI.Fody" Version="19.5.41" />
|
||||||
|
|
|
||||||
|
|
@ -202,14 +202,17 @@ 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?> GetCertPemAsync(string target, string serverName)
|
public async Task<(string?, string?)> GetCertPemAsync(string target, string serverName, int timeout = 10)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var (domain, _, port, _) = Utils.ParseUrl(target);
|
var (domain, _, port, _) = Utils.ParseUrl(target);
|
||||||
|
|
||||||
|
using var cts = new CancellationTokenSource();
|
||||||
|
cts.CancelAfter(TimeSpan.FromSeconds(timeout));
|
||||||
|
|
||||||
using var client = new TcpClient();
|
using var client = new TcpClient();
|
||||||
await client.ConnectAsync(domain, port > 0 ? port : 443);
|
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
|
||||||
|
|
||||||
using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
|
using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
|
||||||
|
|
||||||
|
|
@ -218,31 +221,39 @@ public class CertPemManager
|
||||||
var remote = ssl.RemoteCertificate;
|
var remote = ssl.RemoteCertificate;
|
||||||
if (remote == null)
|
if (remote == null)
|
||||||
{
|
{
|
||||||
return null;
|
return (null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var leaf = new X509Certificate2(remote);
|
var leaf = new X509Certificate2(remote);
|
||||||
return ExportCertToPem(leaf);
|
return (ExportCertToPem(leaf), null);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, new TimeoutException($"Connection timeout after {timeout} seconds"));
|
||||||
|
return (null, $"Connection timeout after {timeout} seconds");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(_tag, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return null;
|
return (null, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <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>> GetCertChainPemAsync(string target, string serverName)
|
public async Task<(List<string>, string?)> GetCertChainPemAsync(string target, string serverName, int timeout = 10)
|
||||||
{
|
{
|
||||||
|
var pemList = new List<string>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var pemList = new List<string>();
|
|
||||||
var (domain, _, port, _) = Utils.ParseUrl(target);
|
var (domain, _, port, _) = Utils.ParseUrl(target);
|
||||||
|
|
||||||
|
using var cts = new CancellationTokenSource();
|
||||||
|
cts.CancelAfter(TimeSpan.FromSeconds(timeout));
|
||||||
|
|
||||||
using var client = new TcpClient();
|
using var client = new TcpClient();
|
||||||
await client.ConnectAsync(domain, port > 0 ? port : 443);
|
await client.ConnectAsync(domain, port > 0 ? port : 443, cts.Token);
|
||||||
|
|
||||||
using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
|
using var ssl = new SslStream(client.GetStream(), false, ValidateServerCertificate);
|
||||||
|
|
||||||
|
|
@ -250,7 +261,7 @@ public class CertPemManager
|
||||||
|
|
||||||
if (ssl.RemoteCertificate is not X509Certificate2 certChain)
|
if (ssl.RemoteCertificate is not X509Certificate2 certChain)
|
||||||
{
|
{
|
||||||
return pemList;
|
return (pemList, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var chain = new X509Chain();
|
var chain = new X509Chain();
|
||||||
|
|
@ -262,12 +273,17 @@ public class CertPemManager
|
||||||
pemList.Add(pem);
|
pemList.Add(pem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pemList;
|
return (pemList, null);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
Logging.SaveLog(_tag, new TimeoutException($"Connection timeout after {timeout} seconds"));
|
||||||
|
return (pemList, $"Connection timeout after {timeout} seconds");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(_tag, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
return new List<string>();
|
return (pemList, ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,8 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
domain += $":{SelectedSource.Port}";
|
domain += $":{SelectedSource.Port}";
|
||||||
}
|
}
|
||||||
Cert = await CertPemManager.Instance.GetCertPemAsync(domain, serverName);
|
(Cert, _certError) = await CertPemManager.Instance.GetCertPemAsync(domain, serverName);
|
||||||
|
UpdateCertTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task FetchCertChain()
|
private async Task FetchCertChain()
|
||||||
|
|
@ -176,7 +177,8 @@ public class AddServerViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
domain += $":{SelectedSource.Port}";
|
domain += $":{SelectedSource.Port}";
|
||||||
}
|
}
|
||||||
var certs = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName);
|
(var certs, _certError) = await CertPemManager.Instance.GetCertChainPemAsync(domain, serverName);
|
||||||
|
UpdateCertTip();
|
||||||
Cert = string.Join("\n", certs);
|
Cert = string.Join("\n", certs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue