Per-endpoint RunAs: Service / InteractiveUser / SpecificUser
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>
This commit is contained in:
@@ -55,6 +55,7 @@ public sealed class ConfigStore
|
||||
{
|
||||
ClearOne(ep.Bearer?.Secret);
|
||||
ClearOne(ep.Hmac?.Secret);
|
||||
ClearOne(ep.RunAs?.Password);
|
||||
if (ep.Callback is { } cb)
|
||||
{
|
||||
ClearOne(cb.Bearer?.Secret);
|
||||
@@ -76,6 +77,7 @@ public sealed class ConfigStore
|
||||
{
|
||||
DecryptOne(ep.Bearer?.Secret);
|
||||
DecryptOne(ep.Hmac?.Secret);
|
||||
DecryptOne(ep.RunAs?.Password);
|
||||
if (ep.Callback is { } cb)
|
||||
{
|
||||
DecryptOne(cb.Bearer?.Secret);
|
||||
@@ -91,6 +93,7 @@ public sealed class ConfigStore
|
||||
{
|
||||
EncryptOne(ep.Bearer?.Secret);
|
||||
EncryptOne(ep.Hmac?.Secret);
|
||||
EncryptOne(ep.RunAs?.Password);
|
||||
if (ep.Callback is { } cb)
|
||||
{
|
||||
EncryptOne(cb.Bearer?.Secret);
|
||||
|
||||
Reference in New Issue
Block a user