84 lines
2.4 KiB
C#
84 lines
2.4 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Threading;
|
|
using PureCrack.Util;
|
|
|
|
namespace PureCrack.Panel;
|
|
|
|
public static class PanelLauncher
|
|
{
|
|
public static string BundledPanelPath => Path.Combine(Workspace.Root, "panel", "PureRAT.exe");
|
|
|
|
public static string DevPanelPath => Path.GetFullPath(Path.Combine(new string[5]
|
|
{
|
|
Workspace.Root,
|
|
"..",
|
|
"..",
|
|
"panel",
|
|
"PureRAT.exe"
|
|
}));
|
|
|
|
public static string FindExe()
|
|
{
|
|
string environmentVariable = Environment.GetEnvironmentVariable("PURE_PANEL_EXE");
|
|
if (!string.IsNullOrEmpty(environmentVariable))
|
|
{
|
|
if (File.Exists(environmentVariable))
|
|
{
|
|
return environmentVariable;
|
|
}
|
|
Log.Warn("PURE_PANEL_EXE points at " + environmentVariable + " but file doesn't exist — falling back to bundled");
|
|
}
|
|
if (File.Exists(BundledPanelPath))
|
|
{
|
|
return BundledPanelPath;
|
|
}
|
|
if (File.Exists(DevPanelPath))
|
|
{
|
|
return DevPanelPath;
|
|
}
|
|
throw new FileNotFoundException("PureRAT.exe not found. Looked at:\n - " + BundledPanelPath + " (deployed layout)\n - " + DevPanelPath + " (running from bin\\Release\\ in source tree)\nEither copy PureRAT.exe to one of those, or set PURE_PANEL_EXE env var.\nSee " + Path.Combine(Path.GetDirectoryName(BundledPanelPath), "README.md") + " for bundling instructions.");
|
|
}
|
|
|
|
public static Process Launch(string panelExe)
|
|
{
|
|
Log.Info("launching panel: " + panelExe);
|
|
Process process = Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = panelExe,
|
|
UseShellExecute = true,
|
|
WorkingDirectory = (Path.GetDirectoryName(panelExe) ?? Workspace.Root)
|
|
}) ?? throw new InvalidOperationException("Process.Start returned null");
|
|
Log.Ok($"panel started (PID {process.Id})");
|
|
return process;
|
|
}
|
|
|
|
public static bool WaitForListener(int port, TimeSpan timeout, CancellationToken ct = default(CancellationToken))
|
|
{
|
|
DateTime dateTime = DateTime.UtcNow + timeout;
|
|
Log.Info($"waiting for panel to bind :{port} (timeout {timeout.TotalSeconds:0}s)");
|
|
int num = 0;
|
|
while (DateTime.UtcNow < dateTime && !ct.IsCancellationRequested)
|
|
{
|
|
num++;
|
|
try
|
|
{
|
|
using TcpClient tcpClient = new TcpClient();
|
|
if (tcpClient.ConnectAsync(IPAddress.Loopback, port).Wait(500, ct) && tcpClient.Connected)
|
|
{
|
|
Log.Ok($":{port} is up (after {num} probes)");
|
|
return true;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
}
|
|
Thread.Sleep(500);
|
|
}
|
|
return false;
|
|
}
|
|
}
|