defense-mcp-server 0.6.0

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.
Files changed (186) hide show
  1. package/CHANGELOG.md +471 -0
  2. package/LICENSE +21 -0
  3. package/README.md +242 -0
  4. package/build/core/auto-installer.d.ts +102 -0
  5. package/build/core/auto-installer.d.ts.map +1 -0
  6. package/build/core/auto-installer.js +833 -0
  7. package/build/core/backup-manager.d.ts +63 -0
  8. package/build/core/backup-manager.d.ts.map +1 -0
  9. package/build/core/backup-manager.js +189 -0
  10. package/build/core/changelog.d.ts +75 -0
  11. package/build/core/changelog.d.ts.map +1 -0
  12. package/build/core/changelog.js +123 -0
  13. package/build/core/command-allowlist.d.ts +129 -0
  14. package/build/core/command-allowlist.d.ts.map +1 -0
  15. package/build/core/command-allowlist.js +849 -0
  16. package/build/core/config.d.ts +79 -0
  17. package/build/core/config.d.ts.map +1 -0
  18. package/build/core/config.js +193 -0
  19. package/build/core/dependency-validator.d.ts +106 -0
  20. package/build/core/dependency-validator.d.ts.map +1 -0
  21. package/build/core/dependency-validator.js +405 -0
  22. package/build/core/distro-adapter.d.ts +177 -0
  23. package/build/core/distro-adapter.d.ts.map +1 -0
  24. package/build/core/distro-adapter.js +481 -0
  25. package/build/core/distro.d.ts +68 -0
  26. package/build/core/distro.d.ts.map +1 -0
  27. package/build/core/distro.js +457 -0
  28. package/build/core/encrypted-state.d.ts +76 -0
  29. package/build/core/encrypted-state.d.ts.map +1 -0
  30. package/build/core/encrypted-state.js +209 -0
  31. package/build/core/executor.d.ts +56 -0
  32. package/build/core/executor.d.ts.map +1 -0
  33. package/build/core/executor.js +350 -0
  34. package/build/core/installer.d.ts +92 -0
  35. package/build/core/installer.d.ts.map +1 -0
  36. package/build/core/installer.js +1072 -0
  37. package/build/core/logger.d.ts +102 -0
  38. package/build/core/logger.d.ts.map +1 -0
  39. package/build/core/logger.js +132 -0
  40. package/build/core/parsers.d.ts +151 -0
  41. package/build/core/parsers.d.ts.map +1 -0
  42. package/build/core/parsers.js +479 -0
  43. package/build/core/policy-engine.d.ts +170 -0
  44. package/build/core/policy-engine.d.ts.map +1 -0
  45. package/build/core/policy-engine.js +656 -0
  46. package/build/core/preflight.d.ts +157 -0
  47. package/build/core/preflight.d.ts.map +1 -0
  48. package/build/core/preflight.js +638 -0
  49. package/build/core/privilege-manager.d.ts +108 -0
  50. package/build/core/privilege-manager.d.ts.map +1 -0
  51. package/build/core/privilege-manager.js +363 -0
  52. package/build/core/rate-limiter.d.ts +67 -0
  53. package/build/core/rate-limiter.d.ts.map +1 -0
  54. package/build/core/rate-limiter.js +129 -0
  55. package/build/core/rollback.d.ts +73 -0
  56. package/build/core/rollback.d.ts.map +1 -0
  57. package/build/core/rollback.js +278 -0
  58. package/build/core/safeguards.d.ts +58 -0
  59. package/build/core/safeguards.d.ts.map +1 -0
  60. package/build/core/safeguards.js +448 -0
  61. package/build/core/sanitizer.d.ts +118 -0
  62. package/build/core/sanitizer.d.ts.map +1 -0
  63. package/build/core/sanitizer.js +459 -0
  64. package/build/core/secure-fs.d.ts +67 -0
  65. package/build/core/secure-fs.d.ts.map +1 -0
  66. package/build/core/secure-fs.js +143 -0
  67. package/build/core/spawn-safe.d.ts +55 -0
  68. package/build/core/spawn-safe.d.ts.map +1 -0
  69. package/build/core/spawn-safe.js +146 -0
  70. package/build/core/sudo-guard.d.ts +145 -0
  71. package/build/core/sudo-guard.d.ts.map +1 -0
  72. package/build/core/sudo-guard.js +349 -0
  73. package/build/core/sudo-session.d.ts +100 -0
  74. package/build/core/sudo-session.d.ts.map +1 -0
  75. package/build/core/sudo-session.js +319 -0
  76. package/build/core/tool-dependencies.d.ts +61 -0
  77. package/build/core/tool-dependencies.d.ts.map +1 -0
  78. package/build/core/tool-dependencies.js +571 -0
  79. package/build/core/tool-registry.d.ts +111 -0
  80. package/build/core/tool-registry.d.ts.map +1 -0
  81. package/build/core/tool-registry.js +656 -0
  82. package/build/core/tool-wrapper.d.ts +73 -0
  83. package/build/core/tool-wrapper.d.ts.map +1 -0
  84. package/build/core/tool-wrapper.js +296 -0
  85. package/build/index.d.ts +3 -0
  86. package/build/index.d.ts.map +1 -0
  87. package/build/index.js +247 -0
  88. package/build/tools/access-control.d.ts +9 -0
  89. package/build/tools/access-control.d.ts.map +1 -0
  90. package/build/tools/access-control.js +1818 -0
  91. package/build/tools/api-security.d.ts +12 -0
  92. package/build/tools/api-security.d.ts.map +1 -0
  93. package/build/tools/api-security.js +901 -0
  94. package/build/tools/app-hardening.d.ts +11 -0
  95. package/build/tools/app-hardening.d.ts.map +1 -0
  96. package/build/tools/app-hardening.js +768 -0
  97. package/build/tools/backup.d.ts +8 -0
  98. package/build/tools/backup.d.ts.map +1 -0
  99. package/build/tools/backup.js +381 -0
  100. package/build/tools/cloud-security.d.ts +17 -0
  101. package/build/tools/cloud-security.d.ts.map +1 -0
  102. package/build/tools/cloud-security.js +739 -0
  103. package/build/tools/compliance.d.ts +10 -0
  104. package/build/tools/compliance.d.ts.map +1 -0
  105. package/build/tools/compliance.js +1225 -0
  106. package/build/tools/container-security.d.ts +14 -0
  107. package/build/tools/container-security.d.ts.map +1 -0
  108. package/build/tools/container-security.js +788 -0
  109. package/build/tools/deception.d.ts +13 -0
  110. package/build/tools/deception.d.ts.map +1 -0
  111. package/build/tools/deception.js +763 -0
  112. package/build/tools/dns-security.d.ts +93 -0
  113. package/build/tools/dns-security.d.ts.map +1 -0
  114. package/build/tools/dns-security.js +745 -0
  115. package/build/tools/drift-detection.d.ts +8 -0
  116. package/build/tools/drift-detection.d.ts.map +1 -0
  117. package/build/tools/drift-detection.js +326 -0
  118. package/build/tools/ebpf-security.d.ts +15 -0
  119. package/build/tools/ebpf-security.d.ts.map +1 -0
  120. package/build/tools/ebpf-security.js +294 -0
  121. package/build/tools/encryption.d.ts +9 -0
  122. package/build/tools/encryption.d.ts.map +1 -0
  123. package/build/tools/encryption.js +1667 -0
  124. package/build/tools/firewall.d.ts +9 -0
  125. package/build/tools/firewall.d.ts.map +1 -0
  126. package/build/tools/firewall.js +1398 -0
  127. package/build/tools/hardening.d.ts +10 -0
  128. package/build/tools/hardening.d.ts.map +1 -0
  129. package/build/tools/hardening.js +2654 -0
  130. package/build/tools/ids.d.ts +9 -0
  131. package/build/tools/ids.d.ts.map +1 -0
  132. package/build/tools/ids.js +624 -0
  133. package/build/tools/incident-response.d.ts +10 -0
  134. package/build/tools/incident-response.d.ts.map +1 -0
  135. package/build/tools/incident-response.js +1180 -0
  136. package/build/tools/logging.d.ts +12 -0
  137. package/build/tools/logging.d.ts.map +1 -0
  138. package/build/tools/logging.js +454 -0
  139. package/build/tools/malware.d.ts +10 -0
  140. package/build/tools/malware.d.ts.map +1 -0
  141. package/build/tools/malware.js +532 -0
  142. package/build/tools/meta.d.ts +11 -0
  143. package/build/tools/meta.d.ts.map +1 -0
  144. package/build/tools/meta.js +2278 -0
  145. package/build/tools/network-defense.d.ts +12 -0
  146. package/build/tools/network-defense.d.ts.map +1 -0
  147. package/build/tools/network-defense.js +760 -0
  148. package/build/tools/patch-management.d.ts +3 -0
  149. package/build/tools/patch-management.d.ts.map +1 -0
  150. package/build/tools/patch-management.js +708 -0
  151. package/build/tools/process-security.d.ts +12 -0
  152. package/build/tools/process-security.d.ts.map +1 -0
  153. package/build/tools/process-security.js +784 -0
  154. package/build/tools/reporting.d.ts +11 -0
  155. package/build/tools/reporting.d.ts.map +1 -0
  156. package/build/tools/reporting.js +559 -0
  157. package/build/tools/secrets.d.ts +9 -0
  158. package/build/tools/secrets.d.ts.map +1 -0
  159. package/build/tools/secrets.js +596 -0
  160. package/build/tools/siem-integration.d.ts +18 -0
  161. package/build/tools/siem-integration.d.ts.map +1 -0
  162. package/build/tools/siem-integration.js +754 -0
  163. package/build/tools/sudo-management.d.ts +18 -0
  164. package/build/tools/sudo-management.d.ts.map +1 -0
  165. package/build/tools/sudo-management.js +737 -0
  166. package/build/tools/supply-chain-security.d.ts +8 -0
  167. package/build/tools/supply-chain-security.d.ts.map +1 -0
  168. package/build/tools/supply-chain-security.js +256 -0
  169. package/build/tools/threat-intel.d.ts +22 -0
  170. package/build/tools/threat-intel.d.ts.map +1 -0
  171. package/build/tools/threat-intel.js +749 -0
  172. package/build/tools/vulnerability-management.d.ts +11 -0
  173. package/build/tools/vulnerability-management.d.ts.map +1 -0
  174. package/build/tools/vulnerability-management.js +667 -0
  175. package/build/tools/waf.d.ts +12 -0
  176. package/build/tools/waf.d.ts.map +1 -0
  177. package/build/tools/waf.js +843 -0
  178. package/build/tools/wireless-security.d.ts +19 -0
  179. package/build/tools/wireless-security.d.ts.map +1 -0
  180. package/build/tools/wireless-security.js +826 -0
  181. package/build/tools/zero-trust-network.d.ts +8 -0
  182. package/build/tools/zero-trust-network.d.ts.map +1 -0
  183. package/build/tools/zero-trust-network.js +367 -0
  184. package/docs/SAFEGUARDS.md +518 -0
  185. package/docs/TOOLS-REFERENCE.md +665 -0
  186. package/package.json +87 -0
@@ -0,0 +1,457 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { executeCommand } from "./executor.js";
4
+ // ── Cache ────────────────────────────────────────────────────────────────────
5
+ let cachedDistro = null;
6
+ // ── Internal helpers ─────────────────────────────────────────────────────────
7
+ function parseOsRelease(content) {
8
+ const result = {};
9
+ for (const line of content.split("\n")) {
10
+ const idx = line.indexOf("=");
11
+ if (idx === -1)
12
+ continue;
13
+ const key = line.substring(0, idx).trim();
14
+ let value = line.substring(idx + 1).trim();
15
+ if ((value.startsWith('"') && value.endsWith('"')) ||
16
+ (value.startsWith("'") && value.endsWith("'"))) {
17
+ value = value.slice(1, -1);
18
+ }
19
+ result[key] = value;
20
+ }
21
+ return result;
22
+ }
23
+ async function binaryExists(name) {
24
+ const result = await executeCommand({ command: "which", args: [name], timeout: 5000 });
25
+ return result.exitCode === 0;
26
+ }
27
+ async function detectWsl() {
28
+ try {
29
+ const content = await readFile("/proc/version", "utf-8");
30
+ return content.toLowerCase().includes("microsoft");
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ function idToSpecificDistro(id) {
37
+ const lower = id.toLowerCase().trim();
38
+ if (lower === "debian")
39
+ return "debian";
40
+ if (lower === "ubuntu")
41
+ return "ubuntu";
42
+ if (lower === "kali")
43
+ return "kali";
44
+ if (lower === "fedora")
45
+ return "fedora";
46
+ if (lower === "rhel" || lower === "redhat")
47
+ return "rhel";
48
+ if (lower.startsWith("centos"))
49
+ return "centos";
50
+ if (lower === "arch" || lower === "archlinux")
51
+ return "arch";
52
+ if (lower.startsWith("alpine"))
53
+ return "alpine";
54
+ if (lower.includes("suse") || lower === "sles")
55
+ return "opensuse";
56
+ if (lower === "macos")
57
+ return "macos";
58
+ return "unknown";
59
+ }
60
+ function idToFamily(id) {
61
+ const lower = id.toLowerCase();
62
+ const debianIds = ["debian", "ubuntu", "kali", "linuxmint", "pop", "elementary", "zorin", "mx", "antiX", "parrot", "raspbian"];
63
+ if (debianIds.some((d) => lower.includes(d)))
64
+ return "debian";
65
+ const rhelIds = ["rhel", "centos", "fedora", "rocky", "almalinux", "oracle", "amazon", "redhat"];
66
+ if (rhelIds.some((d) => lower.includes(d)))
67
+ return "rhel";
68
+ if (lower.includes("arch") || lower.includes("manjaro"))
69
+ return "arch";
70
+ if (lower.includes("alpine"))
71
+ return "alpine";
72
+ if (lower.includes("suse") || lower.includes("sles"))
73
+ return "suse";
74
+ return "unknown";
75
+ }
76
+ function familyToPackageManager(family) {
77
+ switch (family) {
78
+ case "debian": return "apt";
79
+ case "rhel": return "dnf";
80
+ case "arch": return "pacman";
81
+ case "alpine": return "apk";
82
+ case "suse": return "zypper";
83
+ default: return "unknown";
84
+ }
85
+ }
86
+ // ── detectDistro ─────────────────────────────────────────────────────────────
87
+ export async function detectDistro() {
88
+ if (cachedDistro)
89
+ return cachedDistro;
90
+ let id = "unknown";
91
+ let name = "Unknown Linux";
92
+ let version = "unknown";
93
+ let osFamily = "linux";
94
+ // macOS detection
95
+ if (process.platform === "darwin") {
96
+ osFamily = "darwin";
97
+ try {
98
+ const productResult = await executeCommand({ command: "sw_vers", args: ["-productName"], timeout: 5000 });
99
+ const versionResult = await executeCommand({ command: "sw_vers", args: ["-productVersion"], timeout: 5000 });
100
+ if (productResult.exitCode === 0) {
101
+ id = "macos";
102
+ name = productResult.stdout.trim();
103
+ version = versionResult.exitCode === 0 ? versionResult.stdout.trim() : "unknown";
104
+ }
105
+ }
106
+ catch {
107
+ id = "macos";
108
+ name = "macOS";
109
+ }
110
+ }
111
+ else {
112
+ // WSL detection
113
+ const isWsl = await detectWsl();
114
+ if (isWsl)
115
+ osFamily = "wsl";
116
+ }
117
+ // /etc/os-release
118
+ if (id === "unknown") {
119
+ try {
120
+ if (existsSync("/etc/os-release")) {
121
+ const content = readFileSync("/etc/os-release", "utf-8");
122
+ const fields = parseOsRelease(content);
123
+ id = fields.ID ?? id;
124
+ name = fields.PRETTY_NAME ?? fields.NAME ?? name;
125
+ version = fields.VERSION_ID ?? fields.VERSION ?? version;
126
+ }
127
+ }
128
+ catch { /* fallback */ }
129
+ }
130
+ // lsb_release
131
+ if (id === "unknown") {
132
+ try {
133
+ const result = await executeCommand({ command: "lsb_release", args: ["-a"], timeout: 5000 });
134
+ if (result.exitCode === 0) {
135
+ for (const line of result.stdout.split("\n")) {
136
+ if (line.startsWith("Distributor ID:"))
137
+ id = line.split(":")[1]?.trim().toLowerCase() ?? id;
138
+ else if (line.startsWith("Description:"))
139
+ name = line.split(":")[1]?.trim() ?? name;
140
+ else if (line.startsWith("Release:"))
141
+ version = line.split(":")[1]?.trim() ?? version;
142
+ }
143
+ }
144
+ }
145
+ catch { /* fallback */ }
146
+ }
147
+ // Distro-specific files
148
+ if (id === "unknown") {
149
+ const distroFiles = [
150
+ ["/etc/debian_version", "debian"],
151
+ ["/etc/redhat-release", "rhel"],
152
+ ["/etc/arch-release", "arch"],
153
+ ["/etc/alpine-release", "alpine"],
154
+ ["/etc/SuSE-release", "suse"],
155
+ ];
156
+ for (const [filePath, distroId] of distroFiles) {
157
+ try {
158
+ if (existsSync(filePath)) {
159
+ id = distroId;
160
+ version = readFileSync(filePath, "utf-8").trim().split("\n")[0];
161
+ break;
162
+ }
163
+ }
164
+ catch { /* try next */ }
165
+ }
166
+ }
167
+ const specificDistro = osFamily === "darwin" ? "macos" : idToSpecificDistro(id);
168
+ const family = idToFamily(id);
169
+ let packageManager = osFamily === "darwin" ? "brew" : familyToPackageManager(family);
170
+ if (family === "rhel") {
171
+ const hasDnf = await binaryExists("dnf");
172
+ packageManager = hasDnf ? "dnf" : "yum";
173
+ }
174
+ let initSystem = "unknown";
175
+ if (osFamily === "darwin") {
176
+ initSystem = "launchd";
177
+ }
178
+ else if (existsSync("/run/systemd/system")) {
179
+ initSystem = "systemd";
180
+ }
181
+ else if (existsSync("/sbin/openrc-run")) {
182
+ initSystem = "openrc";
183
+ }
184
+ else if (existsSync("/etc/init.d")) {
185
+ initSystem = "sysvinit";
186
+ }
187
+ const [hasFirewalld, hasUfw, hasSelinux, hasApparmor] = await Promise.all([
188
+ binaryExists("firewall-cmd"),
189
+ binaryExists("ufw"),
190
+ binaryExists("getenforce"),
191
+ binaryExists("apparmor_status"),
192
+ ]);
193
+ cachedDistro = {
194
+ id, name, version,
195
+ osFamily, specificDistro, family,
196
+ packageManager, initSystem,
197
+ hasFirewalld, hasUfw, hasSelinux, hasApparmor,
198
+ };
199
+ console.error(`[distro] Detected: ${name} (${id}) osFamily=${osFamily} family=${family} pkg=${packageManager} init=${initSystem}`);
200
+ return cachedDistro;
201
+ }
202
+ // ── PackageManager factory ───────────────────────────────────────────────────
203
+ export function getPackageManager(nameOrDistro) {
204
+ const mgr = resolvePackageManagerName(nameOrDistro);
205
+ switch (mgr) {
206
+ case "apt": return {
207
+ installCmd: (pkg) => ["apt-get", "install", "-y", pkg],
208
+ removeCmd: (pkg) => ["apt-get", "remove", "-y", pkg],
209
+ updateCmd: () => ["apt-get", "update"],
210
+ searchCmd: (term) => ["apt-cache", "search", term],
211
+ listInstalledCmd: () => ["dpkg", "--get-selections"],
212
+ };
213
+ case "dnf": return {
214
+ installCmd: (pkg) => ["dnf", "install", "-y", pkg],
215
+ removeCmd: (pkg) => ["dnf", "remove", "-y", pkg],
216
+ updateCmd: () => ["dnf", "check-update"],
217
+ searchCmd: (term) => ["dnf", "search", term],
218
+ listInstalledCmd: () => ["dnf", "list", "installed"],
219
+ };
220
+ case "yum": return {
221
+ installCmd: (pkg) => ["yum", "install", "-y", pkg],
222
+ removeCmd: (pkg) => ["yum", "remove", "-y", pkg],
223
+ updateCmd: () => ["yum", "check-update"],
224
+ searchCmd: (term) => ["yum", "search", term],
225
+ listInstalledCmd: () => ["yum", "list", "installed"],
226
+ };
227
+ case "pacman": return {
228
+ installCmd: (pkg) => ["pacman", "-S", "--noconfirm", pkg],
229
+ removeCmd: (pkg) => ["pacman", "-R", "--noconfirm", pkg],
230
+ updateCmd: () => ["pacman", "-Sy"],
231
+ searchCmd: (term) => ["pacman", "-Ss", term],
232
+ listInstalledCmd: () => ["pacman", "-Q"],
233
+ };
234
+ case "brew": return {
235
+ installCmd: (pkg) => ["brew", "install", pkg],
236
+ removeCmd: (pkg) => ["brew", "uninstall", pkg],
237
+ updateCmd: () => ["brew", "update"],
238
+ searchCmd: (term) => ["brew", "search", term],
239
+ listInstalledCmd: () => ["brew", "list"],
240
+ };
241
+ case "apk": return {
242
+ installCmd: (pkg) => ["apk", "add", pkg],
243
+ removeCmd: (pkg) => ["apk", "del", pkg],
244
+ updateCmd: () => ["apk", "update"],
245
+ searchCmd: (term) => ["apk", "search", term],
246
+ listInstalledCmd: () => ["apk", "info"],
247
+ };
248
+ case "zypper": return {
249
+ installCmd: (pkg) => ["zypper", "install", "-y", pkg],
250
+ removeCmd: (pkg) => ["zypper", "remove", "-y", pkg],
251
+ updateCmd: () => ["zypper", "refresh"],
252
+ searchCmd: (term) => ["zypper", "search", term],
253
+ listInstalledCmd: () => ["zypper", "packages", "--installed-only"],
254
+ };
255
+ default: return {
256
+ installCmd: (pkg) => ["echo", `[unknown-pkg-mgr] install ${pkg}`],
257
+ removeCmd: (pkg) => ["echo", `[unknown-pkg-mgr] remove ${pkg}`],
258
+ updateCmd: () => ["echo", "[unknown-pkg-mgr] update"],
259
+ searchCmd: (term) => ["echo", `[unknown-pkg-mgr] search ${term}`],
260
+ listInstalledCmd: () => ["echo", "[unknown-pkg-mgr] list-installed"],
261
+ };
262
+ }
263
+ }
264
+ function resolvePackageManagerName(input) {
265
+ if (!input)
266
+ return "unknown";
267
+ const lower = input.toLowerCase().trim();
268
+ const directNames = ["apt", "dnf", "yum", "pacman", "brew", "apk", "zypper"];
269
+ if (directNames.includes(lower))
270
+ return lower;
271
+ switch (lower) {
272
+ case "debian":
273
+ case "ubuntu":
274
+ case "kali": return "apt";
275
+ case "fedora":
276
+ case "rhel":
277
+ case "centos": return "dnf";
278
+ case "arch": return "pacman";
279
+ case "alpine": return "apk";
280
+ case "opensuse": return "zypper";
281
+ case "macos": return "brew";
282
+ default: return "unknown";
283
+ }
284
+ }
285
+ // ── ServiceManager factory ───────────────────────────────────────────────────
286
+ function detectInitSystemSync() {
287
+ if (process.platform === "darwin")
288
+ return "launchd";
289
+ if (existsSync("/run/systemd/system"))
290
+ return "systemd";
291
+ if (existsSync("/sbin/openrc-run"))
292
+ return "openrc";
293
+ if (existsSync("/etc/init.d"))
294
+ return "sysvinit";
295
+ return "unknown";
296
+ }
297
+ export function getServiceManager(initSystem) {
298
+ const system = initSystem ?? detectInitSystemSync();
299
+ switch (system) {
300
+ case "systemd": return {
301
+ startCmd: (svc) => ["systemctl", "start", svc],
302
+ stopCmd: (svc) => ["systemctl", "stop", svc],
303
+ enableCmd: (svc) => ["systemctl", "enable", svc],
304
+ disableCmd: (svc) => ["systemctl", "disable", svc],
305
+ statusCmd: (svc) => ["systemctl", "status", svc],
306
+ listServicesCmd: () => ["systemctl", "list-units", "--type=service", "--all"],
307
+ };
308
+ case "launchd": return {
309
+ startCmd: (svc) => ["launchctl", "start", svc],
310
+ stopCmd: (svc) => ["launchctl", "stop", svc],
311
+ enableCmd: (svc) => ["launchctl", "load", "-w", svc],
312
+ disableCmd: (svc) => ["launchctl", "unload", "-w", svc],
313
+ statusCmd: (svc) => ["launchctl", "list", svc],
314
+ listServicesCmd: () => ["launchctl", "list"],
315
+ };
316
+ case "openrc": return {
317
+ startCmd: (svc) => ["rc-service", svc, "start"],
318
+ stopCmd: (svc) => ["rc-service", svc, "stop"],
319
+ enableCmd: (svc) => ["rc-update", "add", svc, "default"],
320
+ disableCmd: (svc) => ["rc-update", "del", svc, "default"],
321
+ statusCmd: (svc) => ["rc-service", svc, "status"],
322
+ listServicesCmd: () => ["rc-status", "--all"],
323
+ };
324
+ default: return {
325
+ startCmd: (svc) => ["service", svc, "start"],
326
+ stopCmd: (svc) => ["service", svc, "stop"],
327
+ enableCmd: (svc) => ["update-rc.d", svc, "enable"],
328
+ disableCmd: (svc) => ["update-rc.d", svc, "disable"],
329
+ statusCmd: (svc) => ["service", svc, "status"],
330
+ listServicesCmd: () => ["service", "--status-all"],
331
+ };
332
+ }
333
+ }
334
+ // ── Firewall Backend factory ─────────────────────────────────────────────────
335
+ function buildFirewallBackend(fbName) {
336
+ switch (fbName) {
337
+ case "ufw": return {
338
+ name: fbName,
339
+ allowCmd: (port, proto = "tcp") => ["ufw", "allow", `${port}/${proto}`],
340
+ denyCmd: (port, proto = "tcp") => ["ufw", "deny", `${port}/${proto}`],
341
+ listCmd: () => ["ufw", "status", "verbose"],
342
+ flushCmd: () => ["ufw", "reset"],
343
+ };
344
+ case "firewalld": return {
345
+ name: fbName,
346
+ allowCmd: (port, proto = "tcp") => ["firewall-cmd", "--permanent", `--add-port=${port}/${proto}`],
347
+ denyCmd: (port, proto = "tcp") => ["firewall-cmd", "--permanent", `--remove-port=${port}/${proto}`],
348
+ listCmd: () => ["firewall-cmd", "--list-all"],
349
+ flushCmd: () => ["firewall-cmd", "--complete-reload"],
350
+ };
351
+ case "nftables": return {
352
+ name: fbName,
353
+ allowCmd: (port, proto = "tcp") => ["nft", "add", "rule", "inet", "filter", "input", proto, "dport", String(port), "accept"],
354
+ denyCmd: (port, proto = "tcp") => ["nft", "add", "rule", "inet", "filter", "input", proto, "dport", String(port), "drop"],
355
+ listCmd: () => ["nft", "list", "ruleset"],
356
+ flushCmd: () => ["nft", "flush", "ruleset"],
357
+ };
358
+ case "iptables": return {
359
+ name: fbName,
360
+ allowCmd: (port, proto = "tcp") => ["iptables", "-A", "INPUT", "-p", proto, "--dport", String(port), "-j", "ACCEPT"],
361
+ denyCmd: (port, proto = "tcp") => ["iptables", "-A", "INPUT", "-p", proto, "--dport", String(port), "-j", "DROP"],
362
+ listCmd: () => ["iptables", "-L", "-n", "-v"],
363
+ flushCmd: () => ["iptables", "-F"],
364
+ };
365
+ case "pf": return {
366
+ name: fbName,
367
+ allowCmd: (port, proto = "tcp") => ["pfctl", "-e", "-f", "-"],
368
+ denyCmd: (port, proto = "tcp") => ["pfctl", "-e", "-f", "-"],
369
+ listCmd: () => ["pfctl", "-sr"],
370
+ flushCmd: () => ["pfctl", "-F", "all"],
371
+ };
372
+ default: return {
373
+ name: "unknown",
374
+ allowCmd: () => ["echo", "[unknown-firewall] allow"],
375
+ denyCmd: () => ["echo", "[unknown-firewall] deny"],
376
+ listCmd: () => ["echo", "[unknown-firewall] list"],
377
+ flushCmd: () => ["echo", "[unknown-firewall] flush"],
378
+ };
379
+ }
380
+ }
381
+ export async function getFirewallBackend() {
382
+ const [hasUfwBin, hasFirewalldBin, hasNft, hasIptables, hasPf] = await Promise.all([
383
+ binaryExists("ufw"),
384
+ binaryExists("firewall-cmd"),
385
+ binaryExists("nft"),
386
+ binaryExists("iptables"),
387
+ binaryExists("pfctl"),
388
+ ]);
389
+ if (hasUfwBin)
390
+ return buildFirewallBackend("ufw");
391
+ if (hasFirewalldBin)
392
+ return buildFirewallBackend("firewalld");
393
+ if (hasNft)
394
+ return buildFirewallBackend("nftables");
395
+ if (hasIptables)
396
+ return buildFirewallBackend("iptables");
397
+ if (hasPf)
398
+ return buildFirewallBackend("pf");
399
+ return buildFirewallBackend("unknown");
400
+ }
401
+ // ── Capability detection ─────────────────────────────────────────────────────
402
+ async function safeCap(fn) {
403
+ try {
404
+ return await fn();
405
+ }
406
+ catch {
407
+ return false;
408
+ }
409
+ }
410
+ async function fileReadable(path) {
411
+ try {
412
+ await readFile(path, "utf-8");
413
+ return true;
414
+ }
415
+ catch {
416
+ return false;
417
+ }
418
+ }
419
+ export async function canUseAppArmor() {
420
+ return safeCap(async () => (await binaryExists("apparmor_status")) || (await fileReadable("/sys/kernel/security/apparmor")));
421
+ }
422
+ export async function canUseSELinux() {
423
+ return safeCap(async () => (await binaryExists("getenforce")) || (await fileReadable("/sys/fs/selinux")));
424
+ }
425
+ export async function canUseAuditd() {
426
+ return safeCap(() => binaryExists("auditctl"));
427
+ }
428
+ export async function canUseSystemd() {
429
+ return safeCap(async () => existsSync("/run/systemd/system"));
430
+ }
431
+ export async function canUseIPTables() {
432
+ return safeCap(() => binaryExists("iptables"));
433
+ }
434
+ export async function canUseNFTables() {
435
+ return safeCap(() => binaryExists("nft"));
436
+ }
437
+ export async function canUseBPF() {
438
+ return safeCap(async () => (await binaryExists("bpftool")) || existsSync("/sys/fs/bpf"));
439
+ }
440
+ export async function hasTPM() {
441
+ return safeCap(async () => existsSync("/dev/tpm0") || existsSync("/dev/tpmrm0"));
442
+ }
443
+ export async function hasSecureBoot() {
444
+ return safeCap(async () => {
445
+ const r = await executeCommand({ command: "mokutil", args: ["--sb-state"], timeout: 5000 });
446
+ return r.exitCode === 0 && r.stdout.toLowerCase().includes("secureboot enabled");
447
+ });
448
+ }
449
+ // ── Legacy helpers (backwards compatibility) ─────────────────────────────────
450
+ /** @deprecated Prefer getPackageManager(pkgManager).installCmd(pkg) */
451
+ export function getInstallCommand(pkgManager, pkg) {
452
+ return getPackageManager(pkgManager).installCmd(pkg);
453
+ }
454
+ /** @deprecated Prefer getPackageManager(pkgManager).updateCmd() */
455
+ export function getUpdateCommand(pkgManager) {
456
+ return getPackageManager(pkgManager).updateCmd();
457
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * encrypted-state.ts — Encrypted storage for sensitive state data.
3
+ *
4
+ * Provides AES-256-GCM encrypted at-rest storage for rollback data,
5
+ * policy files, sudo session tokens, and other sensitive state.
6
+ *
7
+ * Key derivation uses PBKDF2 from a configurable secret via the
8
+ * `KALI_DEFENSE_STATE_KEY` environment variable. If no key is
9
+ * configured, falls back to unencrypted mode with a warning.
10
+ *
11
+ * @module encrypted-state
12
+ */
13
+ /**
14
+ * Encrypted state storage for sensitive data at rest.
15
+ *
16
+ * Uses AES-256-GCM with PBKDF2-derived keys when `KALI_DEFENSE_STATE_KEY`
17
+ * is set. Falls back to plaintext JSON when no key is configured.
18
+ */
19
+ export declare class SecureStateStore {
20
+ private readonly stateDir;
21
+ private readonly secret;
22
+ /**
23
+ * @param stateDir - Directory for state files (default: `/tmp/kali-defense/state/`)
24
+ * @param secret - Encryption secret. If omitted, reads from `KALI_DEFENSE_STATE_KEY` env var.
25
+ * Pass empty string or omit to use unencrypted fallback.
26
+ */
27
+ constructor(stateDir?: string, secret?: string);
28
+ /**
29
+ * Whether the store is operating in encrypted mode.
30
+ */
31
+ get encrypted(): boolean;
32
+ /**
33
+ * Save a state object to disk.
34
+ *
35
+ * @param id - Unique identifier for the state (used as filename stem)
36
+ * @param data - JSON-serializable object to persist
37
+ */
38
+ save(id: string, data: object): void;
39
+ /**
40
+ * Load a state object from disk.
41
+ *
42
+ * @param id - Unique identifier for the state
43
+ * @returns The deserialized object, or `null` if the state file doesn't exist
44
+ */
45
+ load(id: string): object | null;
46
+ /**
47
+ * Delete a state file from disk.
48
+ *
49
+ * @param id - Unique identifier for the state to delete
50
+ */
51
+ delete(id: string): void;
52
+ /** Build the full file path for a state ID. */
53
+ private filePath;
54
+ /** Ensure the state directory exists with secure permissions. */
55
+ private ensureStateDir;
56
+ /** Derive an AES-256 key from the secret and a salt. */
57
+ private deriveKey;
58
+ /**
59
+ * Encrypt plaintext JSON using AES-256-GCM.
60
+ * Returns a Buffer: [salt (16)] [iv (12)] [authTag (16)] [ciphertext]
61
+ */
62
+ private encrypt;
63
+ /**
64
+ * Decrypt an AES-256-GCM encrypted buffer.
65
+ * Expects format: [salt (16)] [iv (12)] [authTag (16)] [ciphertext]
66
+ */
67
+ private decrypt;
68
+ }
69
+ /**
70
+ * Default singleton SecureStateStore instance.
71
+ *
72
+ * Uses the default state directory and reads the encryption key from
73
+ * the `KALI_DEFENSE_STATE_KEY` environment variable.
74
+ */
75
+ export declare const secureState: SecureStateStore;
76
+ //# sourceMappingURL=encrypted-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypted-state.d.ts","sourceRoot":"","sources":["../../src/core/encrypted-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA4DH;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IAEvC;;;;OAIG;gBACS,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAwB9C;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;;OAKG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAmBpC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAiB/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAcxB,+CAA+C;IAC/C,OAAO,CAAC,QAAQ;IAMhB,iEAAiE;IACjE,OAAO,CAAC,cAAc;IAOtB,wDAAwD;IACxD,OAAO,CAAC,SAAS;IAajB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAgBf;;;OAGG;IACH,OAAO,CAAC,OAAO;CAoChB;AAID;;;;;GAKG;AACH,eAAO,MAAM,WAAW,kBAAyB,CAAC"}