24d8701b65
Native per-endpoint identity instead of the schtasks bridge: - Service (default) keeps the existing path - hooks inherit the service account (SYSTEM by default, or whatever you installed under). - SpecificUser binds ProcessStartInfo.UserName / Password / Domain so the hook runs in a batch logon session as the named account. Useful for AD-write hooks that should NOT run as SYSTEM. - InteractiveUser uses WTSQueryUserToken(WTSGetActiveConsoleSessionId) + DuplicateTokenEx + CreateProcessAsUser to drop the child into the logged-in user's session with their environment block. This is the real fix for "calc.exe should pop up on my desktop" - no Task Scheduler bridge required. Stdio is captured via inheritable anonymous pipes so the hook still returns stdout/stderr to the caller normally. Implementation: - New RunAsMode enum + RunAsConfig model on EndpointConfig - ConfigStore round-trips RunAs.Password through DPAPI alongside bearer/HMAC/PFX secrets - AdminPipeServer's secret-merge logic preserves the encrypted blob when the GUI saves an endpoint without re-typing the password - New WebhookServer.Core.Execution.Native namespace with NativeMethods (P/Invoke) and InteractiveProcessLauncher (token-based launcher) - ProcessExecutor branches on RunAs.Mode; the Service/SpecificUser paths share .NET's Process; InteractiveUser uses the launcher - GUI editor gets a "Run as" section: dropdown + conditional username/password/load-profile fields under SpecificUser Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
48 lines
1.7 KiB
C#
48 lines
1.7 KiB
C#
namespace WebhookServer.Core.Models;
|
|
|
|
public sealed class EndpointConfig
|
|
{
|
|
public Guid Id { get; set; } = Guid.NewGuid();
|
|
public string Slug { get; set; } = "";
|
|
public string? Description { get; set; }
|
|
public bool Enabled { get; set; } = true;
|
|
|
|
public List<string> AllowedClients { get; set; } = new();
|
|
|
|
public AuthMode AuthMode { get; set; } = AuthMode.None;
|
|
public BearerOptions? Bearer { get; set; }
|
|
public HmacOptions? Hmac { get; set; }
|
|
|
|
public ExecutorType ExecutorType { get; set; } = ExecutorType.WindowsPowerShell;
|
|
|
|
/// <summary>Path to a script file (.ps1, .bat, .cmd) when applicable.</summary>
|
|
public string? ScriptPath { get; set; }
|
|
|
|
/// <summary>Inline command body when no script file is used (PowerShell -Command, cmd /c).</summary>
|
|
public string? InlineCommand { get; set; }
|
|
|
|
/// <summary>Path to the executable when ExecutorType = Executable.</summary>
|
|
public string? ExecutablePath { get; set; }
|
|
|
|
/// <summary>Static argv prefix for Executable mode; the rendered ArgTemplate appends after.</summary>
|
|
public List<string> ExecutableArgs { get; set; } = new();
|
|
|
|
public string? WorkingDirectory { get; set; }
|
|
|
|
public DataPassingOptions DataPassing { get; set; } = new();
|
|
|
|
public ResponseMode ResponseMode { get; set; } = ResponseMode.Sync;
|
|
|
|
public int TimeoutSeconds { get; set; } = 60;
|
|
|
|
/// <summary>If true, a non-zero process exit produces 502 in sync mode (default true).</summary>
|
|
public bool FailOnNonZeroExit { get; set; } = true;
|
|
|
|
/// <summary>If true, requests are processed one at a time per endpoint.</summary>
|
|
public bool Serialize { get; set; }
|
|
|
|
public CallbackConfig? Callback { get; set; }
|
|
|
|
public RunAsConfig? RunAs { get; set; }
|
|
}
|