From ec5d3893fbf57174b6058c639e3bdbe4c95579ca Mon Sep 17 00:00:00 2001 From: Space Time Date: Fri, 20 Dec 2024 15:58:05 +0800 Subject: [PATCH] =?UTF-8?q?1.1.3=20->=201.1.4=20=E7=AC=AC86=E6=AC=A1?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Utils/NginxCleaner.cs | 6 +- Wins/MainWin.xaml.cs | 200 ++++++++++++++++++++++-------------------- 2 files changed, 108 insertions(+), 98 deletions(-) diff --git a/Utils/NginxCleaner.cs b/Utils/NginxCleaner.cs index 4fa3bf8..06eb996 100644 --- a/Utils/NginxCleaner.cs +++ b/Utils/NginxCleaner.cs @@ -9,11 +9,11 @@ namespace Sheas_Cealer.Utils; internal static class NginxCleaner { - private static readonly SemaphoreSlim IsCleaningSemaphore = new(1); + internal static readonly SemaphoreSlim IsNginxCleaningSemaphore = new(1); internal static async Task Clean() { - if (!await IsCleaningSemaphore.WaitAsync(0)) + if (!await IsNginxCleaningSemaphore.WaitAsync(0)) return; try @@ -40,6 +40,6 @@ internal static class NginxCleaner certStore.Close(); } - finally { IsCleaningSemaphore.Release(); } + finally { IsNginxCleaningSemaphore.Release(); } } } \ No newline at end of file diff --git a/Wins/MainWin.xaml.cs b/Wins/MainWin.xaml.cs index c1a556e..1a814b6 100644 --- a/Wins/MainWin.xaml.cs +++ b/Wins/MainWin.xaml.cs @@ -19,6 +19,7 @@ using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Text.Json; +using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -55,6 +56,8 @@ public partial class MainWin : Window private int GameClickTime = 0; private int GameFlashInterval = 1000; + private static readonly SemaphoreSlim IsNginxLaunchingSemaphore = new(1); + internal MainWin() { InitializeComponent(); @@ -203,114 +206,121 @@ public partial class MainWin : Window if (!MainPres.IsNginxRunning) { - if ((CealHostRulesDict.ContainsValue(null!) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || - (NginxHttpsPort != 443 && MessageBox.Show(string.Format(MainConst._NginxHttpsPortOccupiedPrompt, NginxHttpsPort), string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || - (NginxHttpPort != 80 && MessageBox.Show(string.Format(MainConst._NginxHttpPortOccupiedPrompt, NginxHttpPort), string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || - (MessageBox.Show(MainConst._LaunchProxyPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || - (MainPres.IsFlashing && MessageBox.Show(MainConst._LaunchNginxFlashingPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes)) + if (NginxCleaner.IsNginxCleaningSemaphore.CurrentCount == 0 || !await IsNginxLaunchingSemaphore.WaitAsync(0)) return; - if (!File.Exists(MainConst.NginxConfPath)) - await File.Create(MainConst.NginxConfPath).DisposeAsync(); - if (!Directory.Exists(MainConst.NginxLogsPath)) - Directory.CreateDirectory(MainConst.NginxLogsPath); - if (!Directory.Exists(MainConst.NginxTempPath)) - Directory.CreateDirectory(MainConst.NginxTempPath); - - RSA certKey = RSA.Create(2048); - - #region Root Cert - CertificateRequest rootCertRequest = new(MainConst.NginxRootCertSubjectName, certKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - - rootCertRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, false)); - - using X509Certificate2 rootCert = rootCertRequest.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(100)); - using X509Store certStore = new(StoreName.Root, StoreLocation.CurrentUser, OpenFlags.ReadWrite); - - certStore.Add(rootCert); - certStore.Close(); - #endregion Root Cert - - #region Child Cert & Hosts - CertificateRequest childCertRequest = new(MainConst.NginxChildCertSubjectName, certKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - SubjectAlternativeNameBuilder childCertSanBuilder = new(); - string hostsConfAppendContent = MainConst.HostsConfStartMarker; - - foreach (List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>? cealHostRules in CealHostRulesDict.Values) - foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, _, _) in cealHostRules ?? []) - foreach ((string cealHostIncludeDomain, _) in cealHostDomainPairs) - { - string cealHostIncludeDomainWithoutWildcard = cealHostIncludeDomain.TrimStart('$').TrimStart('*').TrimStart('.'); - - if (cealHostIncludeDomain.StartsWith('#') || cealHostIncludeDomainWithoutWildcard.Contains('*') || string.IsNullOrWhiteSpace(cealHostIncludeDomainWithoutWildcard)) - continue; - - if (cealHostIncludeDomain.TrimStart('$').StartsWith('*')) - { - childCertSanBuilder.AddDnsName($"*.{cealHostIncludeDomainWithoutWildcard}"); - hostsConfAppendContent += $"127.0.0.1 www.{cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; - - if (cealHostIncludeDomain.TrimStart('$').StartsWith("*.")) - continue; - } - - childCertSanBuilder.AddDnsName(cealHostIncludeDomainWithoutWildcard); - hostsConfAppendContent += $"127.0.0.1 {cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; - } - - childCertRequest.CertificateExtensions.Add(childCertSanBuilder.Build()); - - using X509Certificate2 childCert = childCertRequest.Create(rootCert, rootCert.NotBefore, rootCert.NotAfter, Guid.NewGuid().ToByteArray()); - - await File.WriteAllTextAsync(MainConst.NginxCertPath, childCert.ExportCertificatePem()); - await File.WriteAllTextAsync(MainConst.NginxKeyPath, certKey.ExportPkcs8PrivateKeyPem()); - - hostsConfAppendContent += MainConst.HostsConfEndMarker; - - File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly); - await File.AppendAllTextAsync(MainConst.HostsConfPath, hostsConfAppendContent); - #endregion Child Cert & Hosts - try { - MainPres.IsNginxIniting = true; - NginxConfWatcher.EnableRaisingEvents = false; - NginxConfs!.Save(MainConst.NginxConfPath); + if ((CealHostRulesDict.ContainsValue(null!) && MessageBox.Show(MainConst._CealHostErrorPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || + (NginxHttpsPort != 443 && MessageBox.Show(string.Format(MainConst._NginxHttpsPortOccupiedPrompt, NginxHttpsPort), string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || + (NginxHttpPort != 80 && MessageBox.Show(string.Format(MainConst._NginxHttpPortOccupiedPrompt, NginxHttpPort), string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || + (MessageBox.Show(MainConst._LaunchProxyPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes) || + (MainPres.IsFlashing && MessageBox.Show(MainConst._LaunchNginxFlashingPrompt, string.Empty, MessageBoxButton.YesNo) != MessageBoxResult.Yes)) + return; - await Task.Run(() => - { - new NginxProc().Run(Path.GetDirectoryName(MainConst.NginxPath), @$"-c ""{Path.GetRelativePath(Path.GetDirectoryName(MainConst.NginxPath)!, MainConst.NginxConfPath)}"""); - }); + if (!File.Exists(MainConst.NginxConfPath)) + await File.Create(MainConst.NginxConfPath).DisposeAsync(); + if (!Directory.Exists(MainConst.NginxLogsPath)) + Directory.CreateDirectory(MainConst.NginxLogsPath); + if (!Directory.Exists(MainConst.NginxTempPath)) + Directory.CreateDirectory(MainConst.NginxTempPath); - while (true) + RSA certKey = RSA.Create(2048); + + #region Root Cert + CertificateRequest rootCertRequest = new(MainConst.NginxRootCertSubjectName, certKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + rootCertRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, false)); + + using X509Certificate2 rootCert = rootCertRequest.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(100)); + using X509Store certStore = new(StoreName.Root, StoreLocation.CurrentUser, OpenFlags.ReadWrite); + + certStore.Add(rootCert); + certStore.Close(); + #endregion Root Cert + + #region Child Cert & Hosts + CertificateRequest childCertRequest = new(MainConst.NginxChildCertSubjectName, certKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + SubjectAlternativeNameBuilder childCertSanBuilder = new(); + string hostsConfAppendContent = MainConst.HostsConfStartMarker; + + foreach (List<(List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, string? cealHostSni, string cealHostIp)>? cealHostRules in CealHostRulesDict.Values) + foreach ((List<(string cealHostIncludeDomain, string cealHostExcludeDomain)> cealHostDomainPairs, _, _) in cealHostRules ?? []) + foreach ((string cealHostIncludeDomain, _) in cealHostDomainPairs) + { + string cealHostIncludeDomainWithoutWildcard = cealHostIncludeDomain.TrimStart('$').TrimStart('*').TrimStart('.'); + + if (cealHostIncludeDomain.StartsWith('#') || cealHostIncludeDomainWithoutWildcard.Contains('*') || string.IsNullOrWhiteSpace(cealHostIncludeDomainWithoutWildcard)) + continue; + + if (cealHostIncludeDomain.TrimStart('$').StartsWith('*')) + { + childCertSanBuilder.AddDnsName($"*.{cealHostIncludeDomainWithoutWildcard}"); + hostsConfAppendContent += $"127.0.0.1 www.{cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; + + if (cealHostIncludeDomain.TrimStart('$').StartsWith("*.")) + continue; + } + + childCertSanBuilder.AddDnsName(cealHostIncludeDomainWithoutWildcard); + hostsConfAppendContent += $"127.0.0.1 {cealHostIncludeDomainWithoutWildcard}{Environment.NewLine}"; + } + + childCertRequest.CertificateExtensions.Add(childCertSanBuilder.Build()); + + using X509Certificate2 childCert = childCertRequest.Create(rootCert, rootCert.NotBefore, rootCert.NotAfter, Guid.NewGuid().ToByteArray()); + + await File.WriteAllTextAsync(MainConst.NginxCertPath, childCert.ExportCertificatePem()); + await File.WriteAllTextAsync(MainConst.NginxKeyPath, certKey.ExportPkcs8PrivateKeyPem()); + + hostsConfAppendContent += MainConst.HostsConfEndMarker; + + File.SetAttributes(MainConst.HostsConfPath, File.GetAttributes(MainConst.HostsConfPath) & ~FileAttributes.ReadOnly); + await File.AppendAllTextAsync(MainConst.HostsConfPath, hostsConfAppendContent); + #endregion Child Cert & Hosts + + try { - try + MainPres.IsNginxIniting = true; + NginxConfWatcher.EnableRaisingEvents = false; + NginxConfs!.Save(MainConst.NginxConfPath); + + await Task.Run(() => { - await Http.GetAsync($"https://localhost:{NginxHttpsPort}", MainClient); + new NginxProc().Run(Path.GetDirectoryName(MainConst.NginxPath), @$"-c ""{Path.GetRelativePath(Path.GetDirectoryName(MainConst.NginxPath)!, MainConst.NginxConfPath)}"""); + }); + + while (true) + { + try + { + await Http.GetAsync($"https://localhost:{NginxHttpsPort}", MainClient); + + break; + } + catch (HttpRequestException ex) + { + if (ex.InnerException is SocketException innerEx && innerEx.SocketErrorCode != SocketError.ConnectionRefused) + break; + } + + if (MainPres.IsNginxRunning) + continue; + + if (MessageBox.Show(MainConst._LaunchNginxErrorPrompt, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) + Process.Start(new ProcessStartInfo(MainConst.NginxErrorLogsPath) { UseShellExecute = true }); break; } - catch (HttpRequestException ex) - { - if (ex.InnerException is SocketException innerEx && innerEx.SocketErrorCode != SocketError.ConnectionRefused) - break; - } - - if (MainPres.IsNginxRunning) - continue; - - if (MessageBox.Show(MainConst._LaunchNginxErrorPrompt, string.Empty, MessageBoxButton.YesNo) == MessageBoxResult.Yes) - Process.Start(new ProcessStartInfo(MainConst.NginxErrorLogsPath) { UseShellExecute = true }); - - break; + } + finally + { + await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs); + NginxConfWatcher.EnableRaisingEvents = true; + MainPres.IsNginxIniting = false; } } - finally - { - await File.WriteAllTextAsync(MainConst.NginxConfPath, ExtraNginxConfs); - NginxConfWatcher.EnableRaisingEvents = true; - MainPres.IsNginxIniting = false; - } + finally { IsNginxLaunchingSemaphore.Release(); } } else foreach (Process nginxProcess in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(MainConst.NginxPath)))