@nowcrew/daemon 0.6.97-beta.13 → 0.6.97-beta.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -4,6 +4,7 @@ import { buildServiceSpec, serviceStatus, windowsCommandArg, } from "./computer-
|
|
|
4
4
|
import { daemonGlobalInstallation } from "./daemon-installation.js";
|
|
5
5
|
import { inspectLegacyServiceInstallationDetails } from "./legacy-service-installation.js";
|
|
6
6
|
import { powershellCommandArgs } from "./powershell-command.js";
|
|
7
|
+
import { windowsTaskPrincipalFields, windowsTaskPrincipalMatches, windowsTaskPrincipalScript, } from "./windows-task-principal.js";
|
|
7
8
|
function encoded(value) {
|
|
8
9
|
return Buffer.from(value, "utf16le").toString("base64");
|
|
9
10
|
}
|
|
@@ -143,8 +144,9 @@ async function discoverWindows(input, identity) {
|
|
|
143
144
|
"$n=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($args[0]));",
|
|
144
145
|
"$tasks=@(Get-ScheduledTask -ErrorAction Stop|Where-Object{$_.TaskPath -eq '\\' -and $_.TaskName -ceq $n});",
|
|
145
146
|
"if($tasks.Count -ne 1){[pscustomobject]@{count=$tasks.Count}|ConvertTo-Json -Compress;exit 0};",
|
|
146
|
-
"$task=$tasks[0];$actions=@($task.Actions)
|
|
147
|
-
|
|
147
|
+
"$task=$tasks[0];$actions=@($task.Actions);",
|
|
148
|
+
windowsTaskPrincipalScript,
|
|
149
|
+
`[pscustomobject]@{count=1;state=[int]$task.State;actionCount=$actions.Count;execute=if($actions.Count -eq 1){$actions[0].Execute}else{$null};arguments=if($actions.Count -eq 1){$actions[0].Arguments}else{$null};${windowsTaskPrincipalFields}}|ConvertTo-Json -Compress;`,
|
|
148
150
|
].join("");
|
|
149
151
|
const result = await input.runner("powershell.exe", powershellCommandArgs(script, [encoded(identity.id)]));
|
|
150
152
|
if (result.exitCode !== 0) {
|
|
@@ -164,7 +166,7 @@ async function discoverWindows(input, identity) {
|
|
|
164
166
|
: null;
|
|
165
167
|
if (definition.count !== 1
|
|
166
168
|
|| definition.actionCount !== 1
|
|
167
|
-
|| definition
|
|
169
|
+
|| !windowsTaskPrincipalMatches(definition)
|
|
168
170
|
|| !win32.isAbsolute(definition.execute ?? "")
|
|
169
171
|
|| match === null
|
|
170
172
|
|| match[2] !== input.desired.profile
|
package/dist/computer-service.js
CHANGED
|
@@ -6,6 +6,7 @@ import { promisify } from "node:util";
|
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
7
7
|
import { normalizeDaemonNpmRegistry } from "./npm-registry.js";
|
|
8
8
|
import { daemonRegistryCandidates } from "./daemon-registry.js";
|
|
9
|
+
import { windowsTaskPrincipalFields, windowsTaskPrincipalMatches, windowsTaskPrincipalScript, } from "./windows-task-principal.js";
|
|
9
10
|
import { npmInvocation } from "./npm-command.js";
|
|
10
11
|
import { powershellCommandArgs } from "./powershell-command.js";
|
|
11
12
|
const execFileAsync = promisify(execFile);
|
|
@@ -196,8 +197,9 @@ async function windowsTaskDefinitionMatches(spec, runner) {
|
|
|
196
197
|
"$n=[Text.Encoding]::Unicode.GetString([Convert]::FromBase64String($args[0]));",
|
|
197
198
|
"$tasks=@(Get-ScheduledTask -ErrorAction Stop|Where-Object{$_.TaskPath -eq '\\' -and $_.TaskName -ceq $n});",
|
|
198
199
|
"if($tasks.Count -ne 1){[pscustomobject]@{count=$tasks.Count}|ConvertTo-Json -Compress;exit 0};",
|
|
199
|
-
"$task=$tasks[0];$actions=@($task.Actions)
|
|
200
|
-
|
|
200
|
+
"$task=$tasks[0];$actions=@($task.Actions);",
|
|
201
|
+
windowsTaskPrincipalScript,
|
|
202
|
+
`[pscustomobject]@{count=1;actionCount=$actions.Count;execute=if($actions.Count -eq 1){$actions[0].Execute}else{$null};arguments=if($actions.Count -eq 1){$actions[0].Arguments}else{$null};${windowsTaskPrincipalFields}}|ConvertTo-Json -Compress;`,
|
|
201
203
|
].join("");
|
|
202
204
|
const result = await runner("powershell.exe", powershellCommandArgs(script, [encodedName]));
|
|
203
205
|
if (result.exitCode !== 0) {
|
|
@@ -213,7 +215,7 @@ async function windowsTaskDefinitionMatches(spec, runner) {
|
|
|
213
215
|
const expectedArguments = spec.daemonCommand.slice(1).map(windowsCommandArg).join(" ");
|
|
214
216
|
return definition.count === 1
|
|
215
217
|
&& definition.actionCount === 1
|
|
216
|
-
&& definition
|
|
218
|
+
&& windowsTaskPrincipalMatches(definition)
|
|
217
219
|
&& sameWindowsPath(definition.execute, spec.daemonCommand[0])
|
|
218
220
|
&& definition.arguments === expectedArguments;
|
|
219
221
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Read only: resolve the task's account with Windows, without guessing or stripping its domain. */
|
|
2
|
+
export const windowsTaskPrincipalScript = [
|
|
3
|
+
"$currentUserSid=[Security.Principal.WindowsIdentity]::GetCurrent().User.Value;",
|
|
4
|
+
"$principalSid=$null;",
|
|
5
|
+
"try{",
|
|
6
|
+
"$account=[string]$task.Principal.UserId;",
|
|
7
|
+
"if($account -match '^S-\\d-'){",
|
|
8
|
+
"$principalSid=([Security.Principal.SecurityIdentifier]::new($account)).Value;",
|
|
9
|
+
"}else{",
|
|
10
|
+
"$principalSid=([Security.Principal.NTAccount]::new($account)).Translate([Security.Principal.SecurityIdentifier]).Value;",
|
|
11
|
+
"}",
|
|
12
|
+
"}catch{$principalSid=$null};",
|
|
13
|
+
].join("");
|
|
14
|
+
export const windowsTaskPrincipalFields = [
|
|
15
|
+
"currentUserSid=$currentUserSid;",
|
|
16
|
+
"principalSid=$principalSid;",
|
|
17
|
+
"logonType=[int]$task.Principal.LogonType;",
|
|
18
|
+
"runLevel=[int]$task.Principal.RunLevel;",
|
|
19
|
+
].join("");
|
|
20
|
+
export function windowsTaskPrincipalMatches(principal) {
|
|
21
|
+
return typeof principal.currentUserSid === "string"
|
|
22
|
+
&& /^S-1-(?:\d+-)*\d+$/.test(principal.currentUserSid)
|
|
23
|
+
&& principal.principalSid === principal.currentUserSid
|
|
24
|
+
&& principal.logonType === 3 // Interactive
|
|
25
|
+
&& principal.runLevel === 0; // Limited
|
|
26
|
+
}
|