@push.rocks/smartdaemon 2.7.1 → 2.7.2
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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.systemdunit.d.ts +10 -7
- package/dist_ts/classes.systemdunit.js +29 -30
- package/dist_ts/classes.systemdunitfile.d.ts +13 -2
- package/dist_ts/classes.systemdunitfile.js +62 -35
- package/dist_ts/systemd.userenvironment.d.ts +33 -0
- package/dist_ts/systemd.userenvironment.js +33 -0
- package/package.json +1 -1
- package/readme.md +33 -14
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.systemdunit.ts +38 -35
- package/ts/classes.systemdunitfile.ts +76 -43
- package/ts/systemd.userenvironment.ts +63 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartdaemon',
|
|
6
|
-
version: '2.7.
|
|
6
|
+
version: '2.7.2',
|
|
7
7
|
description: 'Start scripts as long running daemons and manage them.'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHdEQUF3RDtDQUN0RSxDQUFBIn0=
|
|
@@ -3,8 +3,9 @@ export interface ISystemdUnitOptions {
|
|
|
3
3
|
/** Defaults to the system manager. User scope addresses the calling user's manager only. */
|
|
4
4
|
scope?: 'system' | 'user';
|
|
5
5
|
/**
|
|
6
|
-
* User-manager socket directory. Defaults to a non-empty XDG_RUNTIME_DIR.
|
|
7
|
-
* construction
|
|
6
|
+
* User-manager socket directory. Defaults to a non-empty XDG_RUNTIME_DIR. A supplied option must
|
|
7
|
+
* be well formed at construction. The process default may be absent or malformed there; every
|
|
8
|
+
* call that contacts the user manager then refuses with `invalid_options`.
|
|
8
9
|
*/
|
|
9
10
|
runtimeDirectory?: string;
|
|
10
11
|
/** Absolute executable path supplied by trusted owning code. */
|
|
@@ -52,10 +53,8 @@ export declare class SystemdUnit {
|
|
|
52
53
|
private readonly executable;
|
|
53
54
|
private readonly timeout;
|
|
54
55
|
private readonly scope;
|
|
55
|
-
|
|
56
|
-
private readonly
|
|
57
|
-
private readonly configDirectory?;
|
|
58
|
-
private readonly dataDirectory?;
|
|
56
|
+
/** Present exactly for user scope. */
|
|
57
|
+
private readonly userEnvironment?;
|
|
59
58
|
constructor(optionsArg: ISystemdUnitOptions);
|
|
60
59
|
/** Snapshot only. Callers own application-specific admission and restart policy. */
|
|
61
60
|
inspect(): Promise<ISystemdUnitState>;
|
|
@@ -72,6 +71,10 @@ export declare class SystemdUnit {
|
|
|
72
71
|
inspectConfiguration(): Promise<ISystemdUnitConfigurationState>;
|
|
73
72
|
/** Reloads unit definitions globally; does not enable, unmask, start or stop a unit. */
|
|
74
73
|
reloadConfiguration(): Promise<ISystemdUnitConfigurationState>;
|
|
75
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Runs before every systemctl invocation, so an absent or malformed user environment and a
|
|
76
|
+
* missing or unsafe runtime directory refuse without side effects. Undefined for system scope.
|
|
77
|
+
*/
|
|
78
|
+
private userManagerEnvironment;
|
|
76
79
|
private command;
|
|
77
80
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as plugins from './smartdaemon.plugins.js';
|
|
2
|
+
import { captureUserEnvironment, isSafeDirectory, isUserManagerEnvironment, } from './systemd.userenvironment.js';
|
|
2
3
|
export class SystemdUnitError extends Error {
|
|
3
4
|
constructor(code) {
|
|
4
5
|
super(`Systemd unit operation failed: ${code}.`);
|
|
@@ -25,19 +26,13 @@ export class SystemdUnit {
|
|
|
25
26
|
this.executable = optionsArg?.systemctlPath ?? '/usr/bin/systemctl';
|
|
26
27
|
this.timeout = optionsArg?.commandTimeoutMs ?? 120000;
|
|
27
28
|
this.scope = optionsArg?.scope ?? 'system';
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const safeDirectory = (value) => typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
|
|
36
|
-
plugins.path.normalize(value) === value && !value.endsWith('/') &&
|
|
37
|
-
value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
|
|
38
|
-
// Only a supplied runtime directory is validated here. Its absence matters solely to calls that
|
|
39
|
-
// reach the user manager, and those refuse it in validateUserRuntime(). Admitting absence lets
|
|
40
|
-
// owners read protected unit files from contexts without a login session (cron, plain ssh).
|
|
29
|
+
this.userEnvironment = this.scope === 'user'
|
|
30
|
+
? captureUserEnvironment(optionsArg?.runtimeDirectory) : undefined;
|
|
31
|
+
// Construction validates only the options it is given. The process-derived user environment
|
|
32
|
+
// (home, XDG config/data/runtime roots) is validated by userManagerEnvironment() before every
|
|
33
|
+
// systemctl call, because only those calls read it. SystemdUnitFile builds its unit at
|
|
34
|
+
// construction, so refusing that environment here would also refuse SystemdUnitFile.inspect(),
|
|
35
|
+
// which never contacts the manager.
|
|
41
36
|
if (typeof this.unitName !== 'string' ||
|
|
42
37
|
!/^[a-zA-Z0-9][a-zA-Z0-9_.:@-]{0,230}\.service$/.test(this.unitName) ||
|
|
43
38
|
typeof this.executable !== 'string' || !plugins.path.isAbsolute(this.executable) ||
|
|
@@ -45,11 +40,8 @@ export class SystemdUnit {
|
|
|
45
40
|
this.timeout < 1 || this.timeout > 600000 ||
|
|
46
41
|
!['system', 'user'].includes(this.scope) ||
|
|
47
42
|
(this.scope === 'system' && optionsArg?.runtimeDirectory !== undefined) ||
|
|
48
|
-
(this.scope === 'user' &&
|
|
49
|
-
|
|
50
|
-
!safeDirectory(this.homeDirectory) ||
|
|
51
|
-
this.configDirectory !== undefined && !safeDirectory(this.configDirectory) ||
|
|
52
|
-
this.dataDirectory !== undefined && !safeDirectory(this.dataDirectory))))
|
|
43
|
+
(this.scope === 'user' && optionsArg?.runtimeDirectory !== undefined &&
|
|
44
|
+
!isSafeDirectory(optionsArg.runtimeDirectory)))
|
|
53
45
|
throw new SystemdUnitError('invalid_options');
|
|
54
46
|
}
|
|
55
47
|
/** Snapshot only. Callers own application-specific admission and restart policy. */
|
|
@@ -158,13 +150,17 @@ export class SystemdUnit {
|
|
|
158
150
|
await this.command(['daemon-reload']);
|
|
159
151
|
return this.inspectConfiguration();
|
|
160
152
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Runs before every systemctl invocation, so an absent or malformed user environment and a
|
|
155
|
+
* missing or unsafe runtime directory refuse without side effects. Undefined for system scope.
|
|
156
|
+
*/
|
|
157
|
+
async userManagerEnvironment() {
|
|
158
|
+
const environment = this.userEnvironment;
|
|
159
|
+
if (environment === undefined)
|
|
160
|
+
return undefined;
|
|
161
|
+
if (!isUserManagerEnvironment(environment))
|
|
167
162
|
throw new SystemdUnitError('invalid_options');
|
|
163
|
+
const runtimeDirectory = environment.runtimeDirectory;
|
|
168
164
|
try {
|
|
169
165
|
const uid = process.getuid?.();
|
|
170
166
|
if (process.platform !== 'linux' || uid === undefined || process.geteuid?.() !== uid ||
|
|
@@ -179,9 +175,10 @@ export class SystemdUnit {
|
|
|
179
175
|
catch {
|
|
180
176
|
throw new SystemdUnitError('invalid_options');
|
|
181
177
|
}
|
|
178
|
+
return environment;
|
|
182
179
|
}
|
|
183
180
|
async command(argsArg) {
|
|
184
|
-
await this.
|
|
181
|
+
const userEnvironment = await this.userManagerEnvironment();
|
|
185
182
|
return new Promise((resolve, reject) => {
|
|
186
183
|
plugins.childProcess.execFile(this.executable, [this.scope === 'user' ? '--user' : '--system', '--no-ask-password', '--no-pager', ...argsArg], {
|
|
187
184
|
encoding: 'utf8',
|
|
@@ -189,11 +186,13 @@ export class SystemdUnit {
|
|
|
189
186
|
killSignal: 'SIGKILL',
|
|
190
187
|
maxBuffer: 16384,
|
|
191
188
|
windowsHide: true,
|
|
192
|
-
env:
|
|
189
|
+
env: userEnvironment
|
|
193
190
|
? { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C',
|
|
194
|
-
HOME:
|
|
195
|
-
...(
|
|
196
|
-
|
|
191
|
+
HOME: userEnvironment.homeDirectory, XDG_RUNTIME_DIR: userEnvironment.runtimeDirectory,
|
|
192
|
+
...(userEnvironment.configDirectory
|
|
193
|
+
? { XDG_CONFIG_HOME: userEnvironment.configDirectory } : {}),
|
|
194
|
+
...(userEnvironment.dataDirectory
|
|
195
|
+
? { XDG_DATA_HOME: userEnvironment.dataDirectory } : {}) }
|
|
197
196
|
: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
|
|
198
197
|
}, (error, stdout) => {
|
|
199
198
|
// execFile settles after the client closes. A timed-out client's remote job may continue.
|
|
@@ -205,4 +204,4 @@ export class SystemdUnit {
|
|
|
205
204
|
});
|
|
206
205
|
}
|
|
207
206
|
}
|
|
208
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3lzdGVtZHVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQWtEcEQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLEtBQUs7SUFDekMsWUFBNEIsSUFBNEQ7UUFDdEYsS0FBSyxDQUFDLGtDQUFrQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBRHZCLFNBQUksR0FBSixJQUFJLENBQXdEO1FBRXRGLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7SUFDakMsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLEdBQUc7SUFDakIsSUFBSTtJQUNKLFdBQVc7SUFDWCxhQUFhO0lBQ2IsVUFBVTtJQUNWLGVBQWU7SUFDZixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxVQUFVO0lBQ1YsS0FBSztDQUNHLENBQUM7QUFFWCxrR0FBa0c7QUFDbEcsTUFBTSxPQUFPLFdBQVc7SUFVdEIsWUFBWSxVQUErQjtRQUN6QyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsRUFBRSxRQUFRLENBQUM7UUFDckMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLEVBQUUsYUFBYSxJQUFJLG9CQUFvQixDQUFDO1FBQ3BFLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxFQUFFLGdCQUFnQixJQUFJLE1BQU0sQ0FBQztRQUN0RCxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDO1FBQzNDLDhGQUE4RjtRQUM5RixpRkFBaUY7UUFDakYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxLQUFLLEtBQUssTUFBTTtZQUMzQyxDQUFDLENBQUMsVUFBVSxFQUFFLGdCQUFnQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLElBQUksU0FBUyxDQUFD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
|
|
207
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3lzdGVtZHVuaXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSwwQkFBMEIsQ0FBQztBQUNwRCxPQUFPLEVBR0wsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZix3QkFBd0IsR0FDekIsTUFBTSw4QkFBOEIsQ0FBQztBQW1EdEMsTUFBTSxPQUFPLGdCQUFpQixTQUFRLEtBQUs7SUFDekMsWUFBNEIsSUFBNEQ7UUFDdEYsS0FBSyxDQUFDLGtDQUFrQyxJQUFJLEdBQUcsQ0FBQyxDQUFDO1FBRHZCLFNBQUksR0FBSixJQUFJLENBQXdEO1FBRXRGLElBQUksQ0FBQyxJQUFJLEdBQUcsa0JBQWtCLENBQUM7SUFDakMsQ0FBQztDQUNGO0FBRUQsTUFBTSxVQUFVLEdBQUc7SUFDakIsSUFBSTtJQUNKLFdBQVc7SUFDWCxhQUFhO0lBQ2IsVUFBVTtJQUNWLGVBQWU7SUFDZixTQUFTO0lBQ1QsWUFBWTtJQUNaLGNBQWM7SUFDZCxVQUFVO0lBQ1YsS0FBSztDQUNHLENBQUM7QUFFWCxrR0FBa0c7QUFDbEcsTUFBTSxPQUFPLFdBQVc7SUFRdEIsWUFBWSxVQUErQjtRQUN6QyxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsRUFBRSxRQUFRLENBQUM7UUFDckMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLEVBQUUsYUFBYSxJQUFJLG9CQUFvQixDQUFDO1FBQ3BFLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxFQUFFLGdCQUFnQixJQUFJLE1BQU0sQ0FBQztRQUN0RCxJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsRUFBRSxLQUFLLElBQUksUUFBUSxDQUFDO1FBQzNDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssS0FBSyxNQUFNO1lBQzFDLENBQUMsQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLEVBQUUsZ0JB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
|
|
@@ -23,12 +23,23 @@ export declare class SystemdUnitFile {
|
|
|
23
23
|
private readonly directory;
|
|
24
24
|
private readonly uid;
|
|
25
25
|
private readonly scope;
|
|
26
|
-
|
|
27
|
-
private readonly
|
|
26
|
+
/** Present exactly for user scope; read only by the default path and by install(). */
|
|
27
|
+
private readonly userEnvironment?;
|
|
28
28
|
private readonly unit;
|
|
29
29
|
private readonly name;
|
|
30
30
|
private busy;
|
|
31
31
|
constructor(options: ISystemdUnitFileOptions);
|
|
32
|
+
/**
|
|
33
|
+
* Only the default location reads XDG_DATA_HOME, or the home directory when that is unset. The
|
|
34
|
+
* public path exists from construction, so a malformed source refuses there: joining would
|
|
35
|
+
* otherwise normalize a value such as `/data/../elsewhere` into a plausible directory.
|
|
36
|
+
*/
|
|
37
|
+
private defaultDirectory;
|
|
38
|
+
/**
|
|
39
|
+
* Directories whose entry for this unit is a mask the manager may report. Only install() reads
|
|
40
|
+
* them. Null when the user environment cannot drive the manager or name the config root.
|
|
41
|
+
*/
|
|
42
|
+
private maskDirectories;
|
|
32
43
|
/**
|
|
33
44
|
* Reads only the exact protected definition; no systemd or filesystem mutation.
|
|
34
45
|
* Needs no user-manager runtime directory.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from './smartdaemon.plugins.js';
|
|
2
2
|
import { SystemdServiceDefinition } from './classes.systemdservicedefinition.js';
|
|
3
3
|
import { SystemdUnit, } from './classes.systemdunit.js';
|
|
4
|
+
import { captureUserEnvironment, isSafeDirectory, isUserManagerEnvironment, } from './systemd.userenvironment.js';
|
|
4
5
|
export class SystemdUnitFileError extends Error {
|
|
5
6
|
constructor(code) {
|
|
6
7
|
super(`Systemd unit definition installation failed: ${code}.`);
|
|
@@ -27,31 +28,56 @@ const sameFile = (left, right) => left.dev === right.dev && left.ino === right.i
|
|
|
27
28
|
export class SystemdUnitFile {
|
|
28
29
|
constructor(options) {
|
|
29
30
|
this.busy = false;
|
|
31
|
+
// Validates the unit's explicit options, including a supplied runtime directory. Like this
|
|
32
|
+
// class, it captures but does not validate the process-derived user environment.
|
|
30
33
|
this.unit = new SystemdUnit(options);
|
|
31
34
|
this.name = options.unitName;
|
|
32
35
|
this.scope = options.scope ?? 'system';
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
?
|
|
36
|
-
|
|
37
|
-
? process.env.XDG_CONFIG_HOME || plugins.path.join(home, '.config') : undefined;
|
|
38
|
-
// Resolved exactly as SystemdUnit resolves it, so both agree on presence.
|
|
39
|
-
this.runtimeDirectory = this.scope === 'user'
|
|
40
|
-
? options.runtimeDirectory ?? (process.env.XDG_RUNTIME_DIR || undefined) : undefined;
|
|
41
|
-
this.directory = options.unitDirectory ?? (this.scope === 'user'
|
|
42
|
-
? plugins.path.join(dataDirectory, 'systemd/user') : '/usr/local/lib/systemd/system');
|
|
36
|
+
// Captured in the same synchronous step as the unit's own snapshot, so both read equal values.
|
|
37
|
+
this.userEnvironment = this.scope === 'user'
|
|
38
|
+
? captureUserEnvironment(options.runtimeDirectory) : undefined;
|
|
39
|
+
const directory = options.unitDirectory ?? this.defaultDirectory();
|
|
43
40
|
this.uid = options.expectedUid ?? (this.scope === 'user' ? process.getuid?.() ?? -1 : 0);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
// inspect() reads the unit directory as this uid and nothing else. The config and runtime
|
|
42
|
+
// roots and the manager environment are refused later, by install(), before any effect.
|
|
43
|
+
if (!isSafeDirectory(directory) || !Number.isSafeInteger(this.uid) || this.uid < 0 ||
|
|
44
|
+
this.scope === 'user' && this.uid !== process.getuid?.())
|
|
45
|
+
throw new SystemdUnitFileError('invalid_options');
|
|
46
|
+
this.directory = directory;
|
|
47
|
+
this.path = plugins.path.join(directory, this.name);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Only the default location reads XDG_DATA_HOME, or the home directory when that is unset. The
|
|
51
|
+
* public path exists from construction, so a malformed source refuses there: joining would
|
|
52
|
+
* otherwise normalize a value such as `/data/../elsewhere` into a plausible directory.
|
|
53
|
+
*/
|
|
54
|
+
defaultDirectory() {
|
|
55
|
+
const environment = this.userEnvironment;
|
|
56
|
+
if (environment === undefined)
|
|
57
|
+
return '/usr/local/lib/systemd/system';
|
|
58
|
+
const dataDirectory = environment.dataDirectory ?? (isSafeDirectory(environment.homeDirectory)
|
|
59
|
+
? plugins.path.join(environment.homeDirectory, '.local/share') : undefined);
|
|
60
|
+
return isSafeDirectory(dataDirectory) ? plugins.path.join(dataDirectory, 'systemd/user') : undefined;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Directories whose entry for this unit is a mask the manager may report. Only install() reads
|
|
64
|
+
* them. Null when the user environment cannot drive the manager or name the config root.
|
|
65
|
+
*/
|
|
66
|
+
maskDirectories() {
|
|
67
|
+
const environment = this.userEnvironment;
|
|
68
|
+
if (environment === undefined) {
|
|
69
|
+
return { persistent: ['/etc/systemd/system'], runtime: ['/run/systemd/system'] };
|
|
70
|
+
}
|
|
71
|
+
const configDirectory = environment.configDirectory ??
|
|
72
|
+
(isSafeDirectory(environment.homeDirectory)
|
|
73
|
+
? plugins.path.join(environment.homeDirectory, '.config') : undefined);
|
|
74
|
+
if (!isUserManagerEnvironment(environment) || !isSafeDirectory(configDirectory))
|
|
75
|
+
return null;
|
|
76
|
+
const userDirectories = (roots) => roots.map(root => plugins.path.join(root, 'systemd/user'));
|
|
77
|
+
return {
|
|
78
|
+
persistent: userDirectories([configDirectory, '/etc']),
|
|
79
|
+
runtime: userDirectories([environment.runtimeDirectory, '/run']),
|
|
80
|
+
};
|
|
55
81
|
}
|
|
56
82
|
/**
|
|
57
83
|
* Reads only the exact protected definition; no systemd or filesystem mutation.
|
|
@@ -71,18 +97,21 @@ export class SystemdUnitFile {
|
|
|
71
97
|
requireValue(definition instanceof SystemdServiceDefinition && definition.unitName === this.name &&
|
|
72
98
|
definition.scope === this.scope &&
|
|
73
99
|
(expectedSha256 === null ||
|
|
74
|
-
typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256))
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
100
|
+
typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256)), 'invalid_options');
|
|
101
|
+
// Installation admits, reloads and verifies through the user manager and recognizes its
|
|
102
|
+
// persistent and runtime mask paths, so it needs the whole user environment. Refusing here,
|
|
103
|
+
// before the busy latch and any directory or systemctl effect, keeps the local error code
|
|
104
|
+
// instead of a wrapped write_failed.
|
|
105
|
+
const maskDirectories = this.maskDirectories();
|
|
106
|
+
if (maskDirectories === null)
|
|
107
|
+
throw new SystemdUnitFileError('invalid_options');
|
|
79
108
|
requireValue(!this.busy, 'busy');
|
|
80
109
|
this.busy = true;
|
|
81
110
|
let temporary;
|
|
82
111
|
let temporaryInfo;
|
|
83
112
|
try {
|
|
84
113
|
const before = await this.unit.inspect();
|
|
85
|
-
const beforeConfiguration = await this.admit(before);
|
|
114
|
+
const beforeConfiguration = await this.admit(before, maskDirectories);
|
|
86
115
|
await this.directories(true);
|
|
87
116
|
const parent = await plugins.fs.lstat(this.directory);
|
|
88
117
|
const previous = await this.read(this.path);
|
|
@@ -111,7 +140,7 @@ export class SystemdUnitFile {
|
|
|
111
140
|
requireValue(sameFile(parent, await plugins.fs.lstat(this.directory)), 'unsafe_path');
|
|
112
141
|
const rechecked = await this.unit.inspect();
|
|
113
142
|
requireValue(JSON.stringify(rechecked) === JSON.stringify(before), 'changed');
|
|
114
|
-
const recheckedConfiguration = await this.admit(rechecked);
|
|
143
|
+
const recheckedConfiguration = await this.admit(rechecked, maskDirectories);
|
|
115
144
|
requireValue(recheckedConfiguration.fragmentPath === beforeConfiguration.fragmentPath, 'changed');
|
|
116
145
|
await plugins.fs.rename(temporary, this.path);
|
|
117
146
|
temporary = undefined;
|
|
@@ -155,17 +184,15 @@ export class SystemdUnitFile {
|
|
|
155
184
|
}
|
|
156
185
|
}
|
|
157
186
|
}
|
|
158
|
-
async admit(state) {
|
|
187
|
+
async admit(state, maskDirectories) {
|
|
159
188
|
requireValue(quiet(state) && (masked(state) ||
|
|
160
189
|
state.loadState === 'loaded' &&
|
|
161
190
|
['enabled', 'enabled-runtime', 'disabled'].includes(state.unitFileState) ||
|
|
162
191
|
state.loadState === 'not-found' && state.unitFileState === ''), 'unsafe_unit');
|
|
163
192
|
const configuration = await this.unit.inspectConfiguration();
|
|
164
|
-
const maskPaths =
|
|
165
|
-
?
|
|
166
|
-
|
|
167
|
-
? [this.runtimeDirectory, '/run'].map(root => plugins.path.join(root, 'systemd/user', this.name))
|
|
168
|
-
: [this.configDirectory, '/etc'].map(root => plugins.path.join(root, 'systemd/user', this.name)));
|
|
193
|
+
const maskPaths = (state.unitFileState === 'masked-runtime'
|
|
194
|
+
? maskDirectories.runtime : maskDirectories.persistent)
|
|
195
|
+
.map(directory => plugins.path.join(directory, this.name));
|
|
169
196
|
requireValue(!configuration.needsReload && configuration.dropInPaths === '' &&
|
|
170
197
|
(masked(state)
|
|
171
198
|
? configuration.fragmentPath !== this.path &&
|
|
@@ -273,4 +300,4 @@ export class SystemdUnitFile {
|
|
|
273
300
|
}
|
|
274
301
|
}
|
|
275
302
|
}
|
|
276
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdGZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN5c3RlbWR1bml0ZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2pGLE9BQU8sRUFJTCxXQUFXLEdBQ1osTUFBTSwwQkFBMEIsQ0FBQztBQVlsQyxNQUFNLE9BQU8sb0JBQXFCLFNBQVEsS0FBSztJQUM3QyxZQUNrQixJQU9HO1FBRW5CLEtBQUssQ0FBQyxnREFBZ0QsSUFBSSxHQUFHLENBQUMsQ0FBQztRQVQvQyxTQUFJLEdBQUosSUFBSSxDQU9EO1FBR25CLElBQUksQ0FBQyxJQUFJLEdBQUcsc0JBQXNCLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBQ0QsTUFBTSxZQUFZLEdBQUcsQ0FBQyxLQUFjLEVBQUUsSUFBa0MsRUFBUSxFQUFFO0lBQ2hGLElBQUksQ0FBQyxLQUFLO1FBQUUsTUFBTSxJQUFJLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25ELENBQUMsQ0FBQztBQUNGLE1BQU0sTUFBTSxHQUFHLENBQUMsS0FBaUIsRUFBRSxFQUFFLENBQ25DLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbEUsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUF3QixFQUFFLEVBQUUsQ0FDekMsS0FBSyxDQUFDLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLFVBQVUsS0FBSyxDQUFDO0lBQzdDLEtBQUssQ0FBQyxZQUFZLEtBQUssRUFBRSxJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssRUFBRTtJQUM3QyxDQUFDLEtBQUssQ0FBQyxXQUFXLEtBQUss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
|
|
303
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zeXN0ZW1kdW5pdGZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnN5c3RlbWR1bml0ZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQ2pGLE9BQU8sRUFJTCxXQUFXLEdBQ1osTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBRUwsc0JBQXNCLEVBQ3RCLGVBQWUsRUFDZix3QkFBd0IsR0FDekIsTUFBTSw4QkFBOEIsQ0FBQztBQWdCdEMsTUFBTSxPQUFPLG9CQUFxQixTQUFRLEtBQUs7SUFDN0MsWUFDa0IsSUFPRztRQUVuQixLQUFLLENBQUMsZ0RBQWdELElBQUksR0FBRyxDQUFDLENBQUM7UUFUL0MsU0FBSSxHQUFKLElBQUksQ0FPRDtRQUduQixJQUFJLENBQUMsSUFBSSxHQUFHLHNCQUFzQixDQUFDO0lBQ3JDLENBQUM7Q0FDRjtBQUNELE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBYyxFQUFFLElBQWtDLEVBQVEsRUFBRTtJQUNoRixJQUFJLENBQUMsS0FBSztRQUFFLE1BQU0sSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUNuRCxDQUFDLENBQUM7QUFDRixNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQWlCLEVBQUUsRUFBRSxDQUNuQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2xFLE1BQU0sS0FBSyxHQUFHLENBQUMsS0FBd0IsRUFBRSxFQUFFLENBQ3pDLEtBQUssQ0FBQyxPQUFPLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxVQUFVLEtBQUssQ0FBQztJQUM3QyxLQUFLLENBQUMsWUFBWSxL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
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The calling process's user-manager environment, captured once at construction so a unit file
|
|
3
|
+
* and the unit it drives read the same values. Nothing here is validated at capture: each value
|
|
4
|
+
* is checked by the operation that reads it, so a malformed variable that an operation never
|
|
5
|
+
* reads cannot stop that operation.
|
|
6
|
+
*/
|
|
7
|
+
export interface ISystemdUserEnvironment {
|
|
8
|
+
/** The account's home directory; absent when the calling uid has no passwd entry. */
|
|
9
|
+
readonly homeDirectory?: string;
|
|
10
|
+
/** A non-empty XDG_CONFIG_HOME. */
|
|
11
|
+
readonly configDirectory?: string;
|
|
12
|
+
/** A non-empty XDG_DATA_HOME. */
|
|
13
|
+
readonly dataDirectory?: string;
|
|
14
|
+
/** The explicit option, otherwise a non-empty XDG_RUNTIME_DIR. */
|
|
15
|
+
readonly runtimeDirectory?: string;
|
|
16
|
+
}
|
|
17
|
+
/** The environment every user-manager call passes to systemctl, once it has been admitted. */
|
|
18
|
+
export type TSystemdUserManagerEnvironment = ISystemdUserEnvironment & {
|
|
19
|
+
readonly homeDirectory: string;
|
|
20
|
+
readonly runtimeDirectory: string;
|
|
21
|
+
};
|
|
22
|
+
/** Absolute, normalized, bounded and printable; never the root itself or a trailing slash. */
|
|
23
|
+
export declare const isSafeDirectory: (value: unknown) => value is string;
|
|
24
|
+
/**
|
|
25
|
+
* An empty XDG variable counts as unset, as the XDG base directory specification defines. An
|
|
26
|
+
* explicit runtime directory option is never reinterpreted, so an empty option stays malformed.
|
|
27
|
+
*/
|
|
28
|
+
export declare const captureUserEnvironment: (runtimeDirectoryOption: string | undefined) => ISystemdUserEnvironment;
|
|
29
|
+
/**
|
|
30
|
+
* Every call that reaches the user manager passes the runtime and home directories and any set
|
|
31
|
+
* XDG config/data roots to systemctl, so all of them must be well formed before the first call.
|
|
32
|
+
*/
|
|
33
|
+
export declare const isUserManagerEnvironment: (environment: ISystemdUserEnvironment) => environment is TSystemdUserManagerEnvironment;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as plugins from './smartdaemon.plugins.js';
|
|
2
|
+
/** Absolute, normalized, bounded and printable; never the root itself or a trailing slash. */
|
|
3
|
+
export const isSafeDirectory = (value) => typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
|
|
4
|
+
plugins.path.normalize(value) === value && !value.endsWith('/') &&
|
|
5
|
+
value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
|
|
6
|
+
/**
|
|
7
|
+
* An empty XDG variable counts as unset, as the XDG base directory specification defines. An
|
|
8
|
+
* explicit runtime directory option is never reinterpreted, so an empty option stays malformed.
|
|
9
|
+
*/
|
|
10
|
+
export const captureUserEnvironment = (runtimeDirectoryOption) => {
|
|
11
|
+
let homeDirectory;
|
|
12
|
+
try {
|
|
13
|
+
homeDirectory = plugins.os.userInfo().homedir;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// os.userInfo() throws for a uid without a passwd entry. The home directory is then absent,
|
|
17
|
+
// and every operation that reads it refuses with its own invalid_options code.
|
|
18
|
+
}
|
|
19
|
+
return Object.freeze({
|
|
20
|
+
homeDirectory,
|
|
21
|
+
configDirectory: process.env.XDG_CONFIG_HOME || undefined,
|
|
22
|
+
dataDirectory: process.env.XDG_DATA_HOME || undefined,
|
|
23
|
+
runtimeDirectory: runtimeDirectoryOption ?? (process.env.XDG_RUNTIME_DIR || undefined),
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Every call that reaches the user manager passes the runtime and home directories and any set
|
|
28
|
+
* XDG config/data roots to systemctl, so all of them must be well formed before the first call.
|
|
29
|
+
*/
|
|
30
|
+
export const isUserManagerEnvironment = (environment) => isSafeDirectory(environment.runtimeDirectory) && isSafeDirectory(environment.homeDirectory) &&
|
|
31
|
+
(environment.configDirectory === undefined || isSafeDirectory(environment.configDirectory)) &&
|
|
32
|
+
(environment.dataDirectory === undefined || isSafeDirectory(environment.dataDirectory));
|
|
33
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtZC51c2VyZW52aXJvbm1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zeXN0ZW1kLnVzZXJlbnZpcm9ubWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBeUJwRCw4RkFBOEY7QUFDOUYsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLENBQUMsS0FBYyxFQUFtQixFQUFFLENBQ2pFLE9BQU8sS0FBSyxLQUFLLFFBQVEsSUFBSSxLQUFLLEtBQUssR0FBRyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztJQUM1RSxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztJQUMvRCxLQUFLLENBQUMsTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUV6RDs7O0dBR0c7QUFDSCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUNwQyxzQkFBMEMsRUFDakIsRUFBRTtJQUMzQixJQUFJLGFBQWlDLENBQUM7SUFDdEMsSUFBSSxDQUFDO1FBQ0gsYUFBYSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDO0lBQ2hELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCw0RkFBNEY7UUFDNUYsK0VBQStFO0lBQ2pGLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDbkIsYUFBYTtRQUNiLGVBQWUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsSUFBSSxTQUFTO1FBQ3pELGFBQWEsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSSxTQUFTO1FBQ3JELGdCQUFnQixFQUFFLHNCQUFzQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxlQUFlLElBQUksU0FBUyxDQUFDO0tBQ3ZGLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQztBQUVGOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLHdCQUF3QixHQUFHLENBQ3RDLFdBQW9DLEVBQ1csRUFBRSxDQUNqRCxlQUFlLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLElBQUksZUFBZSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUM7SUFDM0YsQ0FBQyxXQUFXLENBQUMsZUFBZSxLQUFLLFNBQVMsSUFBSSxlQUFlLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzNGLENBQUMsV0FBVyxDQUFDLGFBQWEsS0FBSyxTQUFTLElBQUksZUFBZSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDIn0=
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -192,14 +192,20 @@ can choose another absolute executable path and `commandTimeoutMs` (default
|
|
|
192
192
|
The default `scope: 'system'` retains system-manager behavior. `scope: 'user'`
|
|
193
193
|
uses `systemctl --user` as the calling user. Every `SystemdUnit` operation contacts
|
|
194
194
|
the user manager, so each requires a real, owned, private `XDG_RUNTIME_DIR` (or an
|
|
195
|
-
explicit `runtimeDirectory`) and passes that directory with the user's home and
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
195
|
+
explicit `runtimeDirectory`) and passes that directory with the user's home and any
|
|
196
|
+
set `XDG_CONFIG_HOME` and `XDG_DATA_HOME` to the command. Before each call, all of
|
|
197
|
+
them must be absolute, normalized paths without a trailing slash, and the runtime
|
|
198
|
+
directory is checked again on disk; a missing, malformed, replaced, linked or
|
|
199
|
+
group-accessible runtime directory, a malformed XDG root and a missing or malformed
|
|
200
|
+
home directory each fail with `invalid_options` before contacting systemd.
|
|
201
|
+
|
|
202
|
+
Construction validates only the options it is given: the unit name, `systemctlPath`,
|
|
203
|
+
`commandTimeoutMs`, `scope` and a supplied `runtimeDirectory`, which must be a
|
|
204
|
+
well-formed path (and is refused for system scope). It reads, but does not validate,
|
|
205
|
+
the process environment above, so a unit can be constructed without a login session
|
|
206
|
+
(cron, a plain ssh command) or with a malformed XDG variable; its calls then refuse.
|
|
207
|
+
An empty XDG variable counts as unset. The environment is captured at construction;
|
|
208
|
+
later changes to `process.env` do not affect an existing unit.
|
|
203
209
|
|
|
204
210
|
`inspectConfiguration()` reports the selected `fragmentPath`, opaque `dropInPaths`
|
|
205
211
|
list and `needsReload` flag. `reloadConfiguration()` explicitly reloads the manager's
|
|
@@ -284,12 +290,25 @@ current user manager and do not escalate privileges. The installer rejects unsaf
|
|
|
284
290
|
ownership or group-writable path components; prepare those directories explicitly
|
|
285
291
|
before installation. It never changes the permissions of existing directories.
|
|
286
292
|
|
|
287
|
-
A user-scope `SystemdUnitFile`
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
`
|
|
291
|
-
|
|
292
|
-
|
|
293
|
+
A user-scope `SystemdUnitFile` validates each value where it is read:
|
|
294
|
+
|
|
295
|
+
- Construction validates the unit's options as `SystemdUnit` does, a supplied
|
|
296
|
+
`unitDirectory` and `expectedUid` (which must equal the caller's uid). Without
|
|
297
|
+
`unitDirectory`, it also derives the public `path` from `XDG_DATA_HOME`, or from the
|
|
298
|
+
home directory when that is unset, and rejects a missing or malformed source there
|
|
299
|
+
with `invalid_options`; no other process value is validated at construction.
|
|
300
|
+
- `inspect()` reads only the unit directory as that uid. It needs no user manager, no
|
|
301
|
+
runtime directory and no XDG config root, so with an explicit `unitDirectory` it
|
|
302
|
+
works whatever `XDG_CONFIG_HOME`, `XDG_DATA_HOME`, `XDG_RUNTIME_DIR` and the home
|
|
303
|
+
directory hold.
|
|
304
|
+
- `install()` admits, reloads and verifies through the manager and recognizes the
|
|
305
|
+
user's persistent and runtime mask paths. It therefore needs everything the manager
|
|
306
|
+
calls need, plus a well-formed config root (`XDG_CONFIG_HOME`, or `~/.config`), and
|
|
307
|
+
rejects anything missing or malformed with `invalid_options` before touching any
|
|
308
|
+
directory or running `systemctl`.
|
|
309
|
+
|
|
310
|
+
An owner can therefore ask whether its definition is installed from a context without
|
|
311
|
+
a login session:
|
|
293
312
|
|
|
294
313
|
```typescript
|
|
295
314
|
// Resolves to null when the file is absent, or { path, sha256 } for a protected definition.
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import * as plugins from './smartdaemon.plugins.js';
|
|
2
|
+
import {
|
|
3
|
+
type ISystemdUserEnvironment,
|
|
4
|
+
type TSystemdUserManagerEnvironment,
|
|
5
|
+
captureUserEnvironment,
|
|
6
|
+
isSafeDirectory,
|
|
7
|
+
isUserManagerEnvironment,
|
|
8
|
+
} from './systemd.userenvironment.js';
|
|
2
9
|
|
|
3
10
|
export interface ISystemdUnitOptions {
|
|
4
11
|
unitName: string;
|
|
5
12
|
/** Defaults to the system manager. User scope addresses the calling user's manager only. */
|
|
6
13
|
scope?: 'system' | 'user';
|
|
7
14
|
/**
|
|
8
|
-
* User-manager socket directory. Defaults to a non-empty XDG_RUNTIME_DIR.
|
|
9
|
-
* construction
|
|
15
|
+
* User-manager socket directory. Defaults to a non-empty XDG_RUNTIME_DIR. A supplied option must
|
|
16
|
+
* be well formed at construction. The process default may be absent or malformed there; every
|
|
17
|
+
* call that contacts the user manager then refuses with `invalid_options`.
|
|
10
18
|
*/
|
|
11
19
|
runtimeDirectory?: string;
|
|
12
20
|
/** Absolute executable path supplied by trusted owning code. */
|
|
@@ -74,30 +82,21 @@ export class SystemdUnit {
|
|
|
74
82
|
private readonly executable: string;
|
|
75
83
|
private readonly timeout: number;
|
|
76
84
|
private readonly scope: 'system' | 'user';
|
|
77
|
-
|
|
78
|
-
private readonly
|
|
79
|
-
private readonly configDirectory?: string;
|
|
80
|
-
private readonly dataDirectory?: string;
|
|
85
|
+
/** Present exactly for user scope. */
|
|
86
|
+
private readonly userEnvironment?: ISystemdUserEnvironment;
|
|
81
87
|
|
|
82
88
|
constructor(optionsArg: ISystemdUnitOptions) {
|
|
83
89
|
this.unitName = optionsArg?.unitName;
|
|
84
90
|
this.executable = optionsArg?.systemctlPath ?? '/usr/bin/systemctl';
|
|
85
91
|
this.timeout = optionsArg?.commandTimeoutMs ?? 120000;
|
|
86
92
|
this.scope = optionsArg?.scope ?? 'system';
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const safeDirectory = (value: unknown): value is string =>
|
|
95
|
-
typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
|
|
96
|
-
plugins.path.normalize(value) === value && !value.endsWith('/') &&
|
|
97
|
-
value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
|
|
98
|
-
// Only a supplied runtime directory is validated here. Its absence matters solely to calls that
|
|
99
|
-
// reach the user manager, and those refuse it in validateUserRuntime(). Admitting absence lets
|
|
100
|
-
// owners read protected unit files from contexts without a login session (cron, plain ssh).
|
|
93
|
+
this.userEnvironment = this.scope === 'user'
|
|
94
|
+
? captureUserEnvironment(optionsArg?.runtimeDirectory) : undefined;
|
|
95
|
+
// Construction validates only the options it is given. The process-derived user environment
|
|
96
|
+
// (home, XDG config/data/runtime roots) is validated by userManagerEnvironment() before every
|
|
97
|
+
// systemctl call, because only those calls read it. SystemdUnitFile builds its unit at
|
|
98
|
+
// construction, so refusing that environment here would also refuse SystemdUnitFile.inspect(),
|
|
99
|
+
// which never contacts the manager.
|
|
101
100
|
if (
|
|
102
101
|
typeof this.unitName !== 'string' ||
|
|
103
102
|
!/^[a-zA-Z0-9][a-zA-Z0-9_.:@-]{0,230}\.service$/.test(this.unitName) ||
|
|
@@ -106,11 +105,8 @@ export class SystemdUnit {
|
|
|
106
105
|
this.timeout < 1 || this.timeout > 600000 ||
|
|
107
106
|
!['system', 'user'].includes(this.scope) ||
|
|
108
107
|
(this.scope === 'system' && optionsArg?.runtimeDirectory !== undefined) ||
|
|
109
|
-
(this.scope === 'user' &&
|
|
110
|
-
|
|
111
|
-
!safeDirectory(this.homeDirectory) ||
|
|
112
|
-
this.configDirectory !== undefined && !safeDirectory(this.configDirectory) ||
|
|
113
|
-
this.dataDirectory !== undefined && !safeDirectory(this.dataDirectory)))
|
|
108
|
+
(this.scope === 'user' && optionsArg?.runtimeDirectory !== undefined &&
|
|
109
|
+
!isSafeDirectory(optionsArg.runtimeDirectory))
|
|
114
110
|
) throw new SystemdUnitError('invalid_options');
|
|
115
111
|
}
|
|
116
112
|
|
|
@@ -227,11 +223,15 @@ export class SystemdUnit {
|
|
|
227
223
|
return this.inspectConfiguration();
|
|
228
224
|
}
|
|
229
225
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Runs before every systemctl invocation, so an absent or malformed user environment and a
|
|
228
|
+
* missing or unsafe runtime directory refuse without side effects. Undefined for system scope.
|
|
229
|
+
*/
|
|
230
|
+
private async userManagerEnvironment(): Promise<TSystemdUserManagerEnvironment | undefined> {
|
|
231
|
+
const environment = this.userEnvironment;
|
|
232
|
+
if (environment === undefined) return undefined;
|
|
233
|
+
if (!isUserManagerEnvironment(environment)) throw new SystemdUnitError('invalid_options');
|
|
234
|
+
const runtimeDirectory = environment.runtimeDirectory;
|
|
235
235
|
try {
|
|
236
236
|
const uid = process.getuid?.();
|
|
237
237
|
if (process.platform !== 'linux' || uid === undefined || process.geteuid?.() !== uid ||
|
|
@@ -244,10 +244,11 @@ export class SystemdUnit {
|
|
|
244
244
|
} catch {
|
|
245
245
|
throw new SystemdUnitError('invalid_options');
|
|
246
246
|
}
|
|
247
|
+
return environment;
|
|
247
248
|
}
|
|
248
249
|
|
|
249
250
|
private async command(argsArg: string[]): Promise<string> {
|
|
250
|
-
await this.
|
|
251
|
+
const userEnvironment = await this.userManagerEnvironment();
|
|
251
252
|
return new Promise((resolve, reject) => {
|
|
252
253
|
plugins.childProcess.execFile(
|
|
253
254
|
this.executable,
|
|
@@ -258,11 +259,13 @@ export class SystemdUnit {
|
|
|
258
259
|
killSignal: 'SIGKILL',
|
|
259
260
|
maxBuffer: 16384,
|
|
260
261
|
windowsHide: true,
|
|
261
|
-
env:
|
|
262
|
+
env: userEnvironment
|
|
262
263
|
? { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C',
|
|
263
|
-
HOME:
|
|
264
|
-
...(
|
|
265
|
-
|
|
264
|
+
HOME: userEnvironment.homeDirectory, XDG_RUNTIME_DIR: userEnvironment.runtimeDirectory,
|
|
265
|
+
...(userEnvironment.configDirectory
|
|
266
|
+
? { XDG_CONFIG_HOME: userEnvironment.configDirectory } : {}),
|
|
267
|
+
...(userEnvironment.dataDirectory
|
|
268
|
+
? { XDG_DATA_HOME: userEnvironment.dataDirectory } : {}) }
|
|
266
269
|
: { PATH: '/usr/bin:/bin', LANG: 'C', LC_ALL: 'C' },
|
|
267
270
|
},
|
|
268
271
|
(error, stdout) => {
|
|
@@ -6,6 +6,12 @@ import {
|
|
|
6
6
|
type ISystemdUnitState,
|
|
7
7
|
SystemdUnit,
|
|
8
8
|
} from './classes.systemdunit.js';
|
|
9
|
+
import {
|
|
10
|
+
type ISystemdUserEnvironment,
|
|
11
|
+
captureUserEnvironment,
|
|
12
|
+
isSafeDirectory,
|
|
13
|
+
isUserManagerEnvironment,
|
|
14
|
+
} from './systemd.userenvironment.js';
|
|
9
15
|
|
|
10
16
|
export interface ISystemdUnitFileOptions extends ISystemdUnitOptions {
|
|
11
17
|
/** Local vendor definitions can be installed without removing an administrator's mask. */
|
|
@@ -13,6 +19,10 @@ export interface ISystemdUnitFileOptions extends ISystemdUnitOptions {
|
|
|
13
19
|
/** Trusted owning-code qualification only. Defaults to root for system, current uid for user. */
|
|
14
20
|
expectedUid?: number;
|
|
15
21
|
}
|
|
22
|
+
interface IMaskDirectories {
|
|
23
|
+
readonly persistent: readonly string[];
|
|
24
|
+
readonly runtime: readonly string[];
|
|
25
|
+
}
|
|
16
26
|
export interface ISystemdUnitFileRecord {
|
|
17
27
|
readonly path: string;
|
|
18
28
|
readonly sha256: string;
|
|
@@ -57,42 +67,65 @@ export class SystemdUnitFile {
|
|
|
57
67
|
private readonly directory: string;
|
|
58
68
|
private readonly uid: number;
|
|
59
69
|
private readonly scope: 'system' | 'user';
|
|
60
|
-
|
|
61
|
-
private readonly
|
|
70
|
+
/** Present exactly for user scope; read only by the default path and by install(). */
|
|
71
|
+
private readonly userEnvironment?: ISystemdUserEnvironment;
|
|
62
72
|
private readonly unit: SystemdUnit;
|
|
63
73
|
private readonly name: string;
|
|
64
74
|
private busy = false;
|
|
65
75
|
|
|
66
76
|
constructor(options: ISystemdUnitFileOptions) {
|
|
77
|
+
// Validates the unit's explicit options, including a supplied runtime directory. Like this
|
|
78
|
+
// class, it captures but does not validate the process-derived user environment.
|
|
67
79
|
this.unit = new SystemdUnit(options);
|
|
68
80
|
this.name = options.unitName;
|
|
69
81
|
this.scope = options.scope ?? 'system';
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
?
|
|
73
|
-
|
|
74
|
-
? process.env.XDG_CONFIG_HOME || plugins.path.join(home!, '.config') : undefined;
|
|
75
|
-
// Resolved exactly as SystemdUnit resolves it, so both agree on presence.
|
|
76
|
-
this.runtimeDirectory = this.scope === 'user'
|
|
77
|
-
? options.runtimeDirectory ?? (process.env.XDG_RUNTIME_DIR || undefined) : undefined;
|
|
78
|
-
this.directory = options.unitDirectory ?? (this.scope === 'user'
|
|
79
|
-
? plugins.path.join(dataDirectory!, 'systemd/user') : '/usr/local/lib/systemd/system');
|
|
82
|
+
// Captured in the same synchronous step as the unit's own snapshot, so both read equal values.
|
|
83
|
+
this.userEnvironment = this.scope === 'user'
|
|
84
|
+
? captureUserEnvironment(options.runtimeDirectory) : undefined;
|
|
85
|
+
const directory = options.unitDirectory ?? this.defaultDirectory();
|
|
80
86
|
this.uid = options.expectedUid ?? (this.scope === 'user' ? process.getuid?.() ?? -1 : 0);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
// inspect() reads the unit directory as this uid and nothing else. The config and runtime
|
|
88
|
+
// roots and the manager environment are refused later, by install(), before any effect.
|
|
89
|
+
if (
|
|
90
|
+
!isSafeDirectory(directory) || !Number.isSafeInteger(this.uid) || this.uid < 0 ||
|
|
91
|
+
this.scope === 'user' && this.uid !== process.getuid?.()
|
|
92
|
+
) throw new SystemdUnitFileError('invalid_options');
|
|
93
|
+
this.directory = directory;
|
|
94
|
+
this.path = plugins.path.join(directory, this.name);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Only the default location reads XDG_DATA_HOME, or the home directory when that is unset. The
|
|
99
|
+
* public path exists from construction, so a malformed source refuses there: joining would
|
|
100
|
+
* otherwise normalize a value such as `/data/../elsewhere` into a plausible directory.
|
|
101
|
+
*/
|
|
102
|
+
private defaultDirectory(): string | undefined {
|
|
103
|
+
const environment = this.userEnvironment;
|
|
104
|
+
if (environment === undefined) return '/usr/local/lib/systemd/system';
|
|
105
|
+
const dataDirectory = environment.dataDirectory ?? (isSafeDirectory(environment.homeDirectory)
|
|
106
|
+
? plugins.path.join(environment.homeDirectory, '.local/share') : undefined);
|
|
107
|
+
return isSafeDirectory(dataDirectory) ? plugins.path.join(dataDirectory, 'systemd/user') : undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Directories whose entry for this unit is a mask the manager may report. Only install() reads
|
|
112
|
+
* them. Null when the user environment cannot drive the manager or name the config root.
|
|
113
|
+
*/
|
|
114
|
+
private maskDirectories(): IMaskDirectories | null {
|
|
115
|
+
const environment = this.userEnvironment;
|
|
116
|
+
if (environment === undefined) {
|
|
117
|
+
return { persistent: ['/etc/systemd/system'], runtime: ['/run/systemd/system'] };
|
|
118
|
+
}
|
|
119
|
+
const configDirectory = environment.configDirectory ??
|
|
120
|
+
(isSafeDirectory(environment.homeDirectory)
|
|
121
|
+
? plugins.path.join(environment.homeDirectory, '.config') : undefined);
|
|
122
|
+
if (!isUserManagerEnvironment(environment) || !isSafeDirectory(configDirectory)) return null;
|
|
123
|
+
const userDirectories = (roots: readonly string[]) =>
|
|
124
|
+
roots.map(root => plugins.path.join(root, 'systemd/user'));
|
|
125
|
+
return {
|
|
126
|
+
persistent: userDirectories([configDirectory, '/etc']),
|
|
127
|
+
runtime: userDirectories([environment.runtimeDirectory, '/run']),
|
|
128
|
+
};
|
|
96
129
|
}
|
|
97
130
|
|
|
98
131
|
/**
|
|
@@ -117,20 +150,22 @@ export class SystemdUnitFile {
|
|
|
117
150
|
definition instanceof SystemdServiceDefinition && definition.unitName === this.name &&
|
|
118
151
|
definition.scope === this.scope &&
|
|
119
152
|
(expectedSha256 === null ||
|
|
120
|
-
typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256))
|
|
121
|
-
// Installation admits, reloads and verifies through the user manager and recognizes its
|
|
122
|
-
// runtime mask path. Refusing here, before the busy latch and any directory or systemctl
|
|
123
|
-
// effect, keeps the local error code instead of a wrapped write_failed.
|
|
124
|
-
(this.scope === 'system' || this.runtimeDirectory !== undefined),
|
|
153
|
+
typeof expectedSha256 === 'string' && /^[a-f0-9]{64}$/.test(expectedSha256)),
|
|
125
154
|
'invalid_options',
|
|
126
155
|
);
|
|
156
|
+
// Installation admits, reloads and verifies through the user manager and recognizes its
|
|
157
|
+
// persistent and runtime mask paths, so it needs the whole user environment. Refusing here,
|
|
158
|
+
// before the busy latch and any directory or systemctl effect, keeps the local error code
|
|
159
|
+
// instead of a wrapped write_failed.
|
|
160
|
+
const maskDirectories = this.maskDirectories();
|
|
161
|
+
if (maskDirectories === null) throw new SystemdUnitFileError('invalid_options');
|
|
127
162
|
requireValue(!this.busy, 'busy');
|
|
128
163
|
this.busy = true;
|
|
129
164
|
let temporary: string | undefined;
|
|
130
165
|
let temporaryInfo: plugins.Stats | undefined;
|
|
131
166
|
try {
|
|
132
167
|
const before = await this.unit.inspect();
|
|
133
|
-
const beforeConfiguration = await this.admit(before);
|
|
168
|
+
const beforeConfiguration = await this.admit(before, maskDirectories);
|
|
134
169
|
await this.directories(true);
|
|
135
170
|
const parent = await plugins.fs.lstat(this.directory);
|
|
136
171
|
const previous = await this.read(this.path);
|
|
@@ -163,7 +198,7 @@ export class SystemdUnitFile {
|
|
|
163
198
|
requireValue(sameFile(parent, await plugins.fs.lstat(this.directory)), 'unsafe_path');
|
|
164
199
|
const rechecked = await this.unit.inspect();
|
|
165
200
|
requireValue(JSON.stringify(rechecked) === JSON.stringify(before), 'changed');
|
|
166
|
-
const recheckedConfiguration = await this.admit(rechecked);
|
|
201
|
+
const recheckedConfiguration = await this.admit(rechecked, maskDirectories);
|
|
167
202
|
requireValue(
|
|
168
203
|
recheckedConfiguration.fragmentPath === beforeConfiguration.fragmentPath,
|
|
169
204
|
'changed',
|
|
@@ -214,7 +249,10 @@ export class SystemdUnitFile {
|
|
|
214
249
|
}
|
|
215
250
|
}
|
|
216
251
|
|
|
217
|
-
private async admit(
|
|
252
|
+
private async admit(
|
|
253
|
+
state: ISystemdUnitState,
|
|
254
|
+
maskDirectories: IMaskDirectories,
|
|
255
|
+
): Promise<ISystemdUnitConfigurationState> {
|
|
218
256
|
requireValue(
|
|
219
257
|
quiet(state) && (masked(state) ||
|
|
220
258
|
state.loadState === 'loaded' &&
|
|
@@ -223,14 +261,9 @@ export class SystemdUnitFile {
|
|
|
223
261
|
'unsafe_unit',
|
|
224
262
|
);
|
|
225
263
|
const configuration = await this.unit.inspectConfiguration();
|
|
226
|
-
const maskPaths =
|
|
227
|
-
?
|
|
228
|
-
|
|
229
|
-
this.name,
|
|
230
|
-
)]
|
|
231
|
-
: (state.unitFileState === 'masked-runtime'
|
|
232
|
-
? [this.runtimeDirectory!, '/run'].map(root => plugins.path.join(root, 'systemd/user', this.name))
|
|
233
|
-
: [this.configDirectory!, '/etc'].map(root => plugins.path.join(root, 'systemd/user', this.name)));
|
|
264
|
+
const maskPaths = (state.unitFileState === 'masked-runtime'
|
|
265
|
+
? maskDirectories.runtime : maskDirectories.persistent)
|
|
266
|
+
.map(directory => plugins.path.join(directory, this.name));
|
|
234
267
|
requireValue(
|
|
235
268
|
!configuration.needsReload && configuration.dropInPaths === '' &&
|
|
236
269
|
(masked(state)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as plugins from './smartdaemon.plugins.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The calling process's user-manager environment, captured once at construction so a unit file
|
|
5
|
+
* and the unit it drives read the same values. Nothing here is validated at capture: each value
|
|
6
|
+
* is checked by the operation that reads it, so a malformed variable that an operation never
|
|
7
|
+
* reads cannot stop that operation.
|
|
8
|
+
*/
|
|
9
|
+
export interface ISystemdUserEnvironment {
|
|
10
|
+
/** The account's home directory; absent when the calling uid has no passwd entry. */
|
|
11
|
+
readonly homeDirectory?: string;
|
|
12
|
+
/** A non-empty XDG_CONFIG_HOME. */
|
|
13
|
+
readonly configDirectory?: string;
|
|
14
|
+
/** A non-empty XDG_DATA_HOME. */
|
|
15
|
+
readonly dataDirectory?: string;
|
|
16
|
+
/** The explicit option, otherwise a non-empty XDG_RUNTIME_DIR. */
|
|
17
|
+
readonly runtimeDirectory?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** The environment every user-manager call passes to systemctl, once it has been admitted. */
|
|
21
|
+
export type TSystemdUserManagerEnvironment = ISystemdUserEnvironment & {
|
|
22
|
+
readonly homeDirectory: string;
|
|
23
|
+
readonly runtimeDirectory: string;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** Absolute, normalized, bounded and printable; never the root itself or a trailing slash. */
|
|
27
|
+
export const isSafeDirectory = (value: unknown): value is string =>
|
|
28
|
+
typeof value === 'string' && value !== '/' && plugins.path.isAbsolute(value) &&
|
|
29
|
+
plugins.path.normalize(value) === value && !value.endsWith('/') &&
|
|
30
|
+
value.length <= 4000 && !/[\x00-\x1f\x7f]/.test(value);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* An empty XDG variable counts as unset, as the XDG base directory specification defines. An
|
|
34
|
+
* explicit runtime directory option is never reinterpreted, so an empty option stays malformed.
|
|
35
|
+
*/
|
|
36
|
+
export const captureUserEnvironment = (
|
|
37
|
+
runtimeDirectoryOption: string | undefined,
|
|
38
|
+
): ISystemdUserEnvironment => {
|
|
39
|
+
let homeDirectory: string | undefined;
|
|
40
|
+
try {
|
|
41
|
+
homeDirectory = plugins.os.userInfo().homedir;
|
|
42
|
+
} catch {
|
|
43
|
+
// os.userInfo() throws for a uid without a passwd entry. The home directory is then absent,
|
|
44
|
+
// and every operation that reads it refuses with its own invalid_options code.
|
|
45
|
+
}
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
homeDirectory,
|
|
48
|
+
configDirectory: process.env.XDG_CONFIG_HOME || undefined,
|
|
49
|
+
dataDirectory: process.env.XDG_DATA_HOME || undefined,
|
|
50
|
+
runtimeDirectory: runtimeDirectoryOption ?? (process.env.XDG_RUNTIME_DIR || undefined),
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Every call that reaches the user manager passes the runtime and home directories and any set
|
|
56
|
+
* XDG config/data roots to systemctl, so all of them must be well formed before the first call.
|
|
57
|
+
*/
|
|
58
|
+
export const isUserManagerEnvironment = (
|
|
59
|
+
environment: ISystemdUserEnvironment,
|
|
60
|
+
): environment is TSystemdUserManagerEnvironment =>
|
|
61
|
+
isSafeDirectory(environment.runtimeDirectory) && isSafeDirectory(environment.homeDirectory) &&
|
|
62
|
+
(environment.configDirectory === undefined || isSafeDirectory(environment.configDirectory)) &&
|
|
63
|
+
(environment.dataDirectory === undefined || isSafeDirectory(environment.dataDirectory));
|