using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Net; using System.Net.Sockets; using System.Security.Principal; using Microsoft.CodeAnalysis.CSharp; using PureCrack.Panel; using PureCrack.Setup; using PureCrack.Util; namespace PureCrack; public static class Preflight { public sealed class Result { public List Problems { get; } = new List(); public string? PanelExePath { get; set; } public bool Ok => Problems.Count == 0; } public static Result Run() { Result result = new Result(); if (!IsAdmin()) { result.Problems.Add("not running as administrator (need admin to bind :443 + write hosts + install root cert)"); } if (!IsTcpPortFree(443)) { string text = LookupTcpListenerHolder(443); string arg = text ?? "another process"; string arg2 = ((text != null && text.StartsWith("PID ")) ? (" (taskkill /F /PID " + text.Substring(4).Split(new char[1] { ' ' })[0] + " to stop it)") : ""); result.Problems.Add($":{443} is already bound by {arg}{arg2}"); } try { if (!HostsManager.IsWritable()) { result.Problems.Add(HostsManager.Path + " is not writable (file marked read-only? AV blocking?)"); } } catch (Exception ex) { result.Problems.Add("hosts file check threw: " + ex.Message); } try { result.PanelExePath = PanelLauncher.FindExe(); } catch (FileNotFoundException ex2) { result.Problems.Add(ex2.Message); } try { _ = typeof(CSharpCompilation).Assembly.FullName; } catch (Exception ex3) { result.Problems.Add("Roslyn (Microsoft.CodeAnalysis.CSharp) not loadable: " + ex3.Message); } return result; } public static void Report(Result r) { if (r.Ok) { Log.Ok("preflight passed (panel at " + r.PanelExePath + ")"); return; } Log.Err($"preflight: {r.Problems.Count} problem(s) — fix all then re-launch:"); foreach (string problem in r.Problems) { Log.Bullet(" - " + problem); } } private static bool IsAdmin() { try { using WindowsIdentity ntIdentity = WindowsIdentity.GetCurrent(); return new WindowsPrincipal(ntIdentity).IsInRole(WindowsBuiltInRole.Administrator); } catch { return false; } } private static bool IsTcpPortFree(int port) { TcpListener tcpListener = null; try { tcpListener = new TcpListener(IPAddress.Any, port); tcpListener.Start(); return true; } catch (SocketException) { return false; } finally { try { tcpListener?.Stop(); } catch { } } } private static string? LookupTcpListenerHolder(int port) { try { using Process process = Process.Start(new ProcessStartInfo("netstat", "-ano") { UseShellExecute = false, RedirectStandardOutput = true, CreateNoWindow = true }); if (process == null) { return null; } string text = process.StandardOutput.ReadToEnd(); process.WaitForExit(5000); string[] array = text.Split(new char[1] { '\n' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (!text2.StartsWith("TCP", StringComparison.Ordinal)) { continue; } string[] array2 = text2.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length >= 5 && !(array2[3] != "LISTENING") && array2[1].EndsWith(":" + port, StringComparison.Ordinal) && int.TryParse(array2[4], out var result)) { try { Process processById = Process.GetProcessById(result); return $"PID {result} ({processById.ProcessName})"; } catch { return $"PID {result}"; } } } } catch { } return null; } }