nox-openclaw-hunter 1.0.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 (211) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +140 -0
  3. package/bin/nox.js +2 -0
  4. package/dist/branding.d.ts +39 -0
  5. package/dist/branding.d.ts.map +1 -0
  6. package/dist/branding.js +66 -0
  7. package/dist/branding.js.map +1 -0
  8. package/dist/cli.d.ts +15 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +94 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/commands/export.d.ts +21 -0
  13. package/dist/commands/export.d.ts.map +1 -0
  14. package/dist/commands/export.js +616 -0
  15. package/dist/commands/export.js.map +1 -0
  16. package/dist/commands/index.d.ts +8 -0
  17. package/dist/commands/index.d.ts.map +1 -0
  18. package/dist/commands/index.js +8 -0
  19. package/dist/commands/index.js.map +1 -0
  20. package/dist/commands/isolate.d.ts +30 -0
  21. package/dist/commands/isolate.d.ts.map +1 -0
  22. package/dist/commands/isolate.js +547 -0
  23. package/dist/commands/isolate.js.map +1 -0
  24. package/dist/commands/purge.d.ts +22 -0
  25. package/dist/commands/purge.d.ts.map +1 -0
  26. package/dist/commands/purge.js +295 -0
  27. package/dist/commands/purge.js.map +1 -0
  28. package/dist/commands/scan.d.ts +23 -0
  29. package/dist/commands/scan.d.ts.map +1 -0
  30. package/dist/commands/scan.js +155 -0
  31. package/dist/commands/scan.js.map +1 -0
  32. package/dist/detector/app-bundle.d.ts +13 -0
  33. package/dist/detector/app-bundle.d.ts.map +1 -0
  34. package/dist/detector/app-bundle.js +27 -0
  35. package/dist/detector/app-bundle.js.map +1 -0
  36. package/dist/detector/cli-binary.d.ts +12 -0
  37. package/dist/detector/cli-binary.d.ts.map +1 -0
  38. package/dist/detector/cli-binary.js +66 -0
  39. package/dist/detector/cli-binary.js.map +1 -0
  40. package/dist/detector/config.d.ts +21 -0
  41. package/dist/detector/config.d.ts.map +1 -0
  42. package/dist/detector/config.js +337 -0
  43. package/dist/detector/config.js.map +1 -0
  44. package/dist/detector/detection-config.d.ts +24 -0
  45. package/dist/detector/detection-config.d.ts.map +1 -0
  46. package/dist/detector/detection-config.js +242 -0
  47. package/dist/detector/detection-config.js.map +1 -0
  48. package/dist/detector/docker.d.ts +10 -0
  49. package/dist/detector/docker.d.ts.map +1 -0
  50. package/dist/detector/docker.js +94 -0
  51. package/dist/detector/docker.js.map +1 -0
  52. package/dist/detector/index.d.ts +50 -0
  53. package/dist/detector/index.d.ts.map +1 -0
  54. package/dist/detector/index.js +155 -0
  55. package/dist/detector/index.js.map +1 -0
  56. package/dist/detector/network.d.ts +34 -0
  57. package/dist/detector/network.d.ts.map +1 -0
  58. package/dist/detector/network.js +205 -0
  59. package/dist/detector/network.js.map +1 -0
  60. package/dist/detector/process.d.ts +16 -0
  61. package/dist/detector/process.d.ts.map +1 -0
  62. package/dist/detector/process.js +47 -0
  63. package/dist/detector/process.js.map +1 -0
  64. package/dist/detector/service.d.ts +17 -0
  65. package/dist/detector/service.d.ts.map +1 -0
  66. package/dist/detector/service.js +51 -0
  67. package/dist/detector/service.js.map +1 -0
  68. package/dist/enforcer/docker-cleaner.d.ts +30 -0
  69. package/dist/enforcer/docker-cleaner.d.ts.map +1 -0
  70. package/dist/enforcer/docker-cleaner.js +163 -0
  71. package/dist/enforcer/docker-cleaner.js.map +1 -0
  72. package/dist/enforcer/file-remover.d.ts +34 -0
  73. package/dist/enforcer/file-remover.d.ts.map +1 -0
  74. package/dist/enforcer/file-remover.js +137 -0
  75. package/dist/enforcer/file-remover.js.map +1 -0
  76. package/dist/enforcer/index.d.ts +33 -0
  77. package/dist/enforcer/index.d.ts.map +1 -0
  78. package/dist/enforcer/index.js +142 -0
  79. package/dist/enforcer/index.js.map +1 -0
  80. package/dist/enforcer/process-killer.d.ts +18 -0
  81. package/dist/enforcer/process-killer.d.ts.map +1 -0
  82. package/dist/enforcer/process-killer.js +80 -0
  83. package/dist/enforcer/process-killer.js.map +1 -0
  84. package/dist/enforcer/service-stopper.d.ts +23 -0
  85. package/dist/enforcer/service-stopper.d.ts.map +1 -0
  86. package/dist/enforcer/service-stopper.js +95 -0
  87. package/dist/enforcer/service-stopper.js.map +1 -0
  88. package/dist/index.d.ts +6 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +10 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/isolator/firewall.d.ts +25 -0
  93. package/dist/isolator/firewall.d.ts.map +1 -0
  94. package/dist/isolator/firewall.js +114 -0
  95. package/dist/isolator/firewall.js.map +1 -0
  96. package/dist/isolator/index.d.ts +63 -0
  97. package/dist/isolator/index.d.ts.map +1 -0
  98. package/dist/isolator/index.js +201 -0
  99. package/dist/isolator/index.js.map +1 -0
  100. package/dist/isolator/lockdown.d.ts +22 -0
  101. package/dist/isolator/lockdown.d.ts.map +1 -0
  102. package/dist/isolator/lockdown.js +401 -0
  103. package/dist/isolator/lockdown.js.map +1 -0
  104. package/dist/isolator/quarantine.d.ts +39 -0
  105. package/dist/isolator/quarantine.d.ts.map +1 -0
  106. package/dist/isolator/quarantine.js +364 -0
  107. package/dist/isolator/quarantine.js.map +1 -0
  108. package/dist/mdm/index.d.ts +93 -0
  109. package/dist/mdm/index.d.ts.map +1 -0
  110. package/dist/mdm/index.js +414 -0
  111. package/dist/mdm/index.js.map +1 -0
  112. package/dist/mdm/intune.d.ts +69 -0
  113. package/dist/mdm/intune.d.ts.map +1 -0
  114. package/dist/mdm/intune.js +409 -0
  115. package/dist/mdm/intune.js.map +1 -0
  116. package/dist/mdm/jamf.d.ts +58 -0
  117. package/dist/mdm/jamf.d.ts.map +1 -0
  118. package/dist/mdm/jamf.js +441 -0
  119. package/dist/mdm/jamf.js.map +1 -0
  120. package/dist/mdm/jumpcloud.d.ts +73 -0
  121. package/dist/mdm/jumpcloud.d.ts.map +1 -0
  122. package/dist/mdm/jumpcloud.js +470 -0
  123. package/dist/mdm/jumpcloud.js.map +1 -0
  124. package/dist/mdm/templates/detect.ps1.d.ts +30 -0
  125. package/dist/mdm/templates/detect.ps1.d.ts.map +1 -0
  126. package/dist/mdm/templates/detect.ps1.js +463 -0
  127. package/dist/mdm/templates/detect.ps1.js.map +1 -0
  128. package/dist/mdm/templates/detect.sh.d.ts +30 -0
  129. package/dist/mdm/templates/detect.sh.d.ts.map +1 -0
  130. package/dist/mdm/templates/detect.sh.js +474 -0
  131. package/dist/mdm/templates/detect.sh.js.map +1 -0
  132. package/dist/mdm/templates/enforce.ps1.d.ts +33 -0
  133. package/dist/mdm/templates/enforce.ps1.d.ts.map +1 -0
  134. package/dist/mdm/templates/enforce.ps1.js +681 -0
  135. package/dist/mdm/templates/enforce.ps1.js.map +1 -0
  136. package/dist/mdm/templates/enforce.sh.d.ts +33 -0
  137. package/dist/mdm/templates/enforce.sh.d.ts.map +1 -0
  138. package/dist/mdm/templates/enforce.sh.js +591 -0
  139. package/dist/mdm/templates/enforce.sh.js.map +1 -0
  140. package/dist/platform/darwin.d.ts +6 -0
  141. package/dist/platform/darwin.d.ts.map +1 -0
  142. package/dist/platform/darwin.js +192 -0
  143. package/dist/platform/darwin.js.map +1 -0
  144. package/dist/platform/index.d.ts +43 -0
  145. package/dist/platform/index.d.ts.map +1 -0
  146. package/dist/platform/index.js +27 -0
  147. package/dist/platform/index.js.map +1 -0
  148. package/dist/platform/linux.d.ts +6 -0
  149. package/dist/platform/linux.d.ts.map +1 -0
  150. package/dist/platform/linux.js +134 -0
  151. package/dist/platform/linux.js.map +1 -0
  152. package/dist/platform/windows.d.ts +6 -0
  153. package/dist/platform/windows.d.ts.map +1 -0
  154. package/dist/platform/windows.js +134 -0
  155. package/dist/platform/windows.js.map +1 -0
  156. package/dist/reporter/console.d.ts +27 -0
  157. package/dist/reporter/console.d.ts.map +1 -0
  158. package/dist/reporter/console.js +431 -0
  159. package/dist/reporter/console.js.map +1 -0
  160. package/dist/reporter/index.d.ts +11 -0
  161. package/dist/reporter/index.d.ts.map +1 -0
  162. package/dist/reporter/index.js +13 -0
  163. package/dist/reporter/index.js.map +1 -0
  164. package/dist/reporter/json.d.ts +61 -0
  165. package/dist/reporter/json.d.ts.map +1 -0
  166. package/dist/reporter/json.js +75 -0
  167. package/dist/reporter/json.js.map +1 -0
  168. package/dist/reporter/webhook.d.ts +57 -0
  169. package/dist/reporter/webhook.d.ts.map +1 -0
  170. package/dist/reporter/webhook.js +230 -0
  171. package/dist/reporter/webhook.js.map +1 -0
  172. package/dist/types/config.d.ts +116 -0
  173. package/dist/types/config.d.ts.map +1 -0
  174. package/dist/types/config.js +6 -0
  175. package/dist/types/config.js.map +1 -0
  176. package/dist/types/detection.d.ts +85 -0
  177. package/dist/types/detection.d.ts.map +1 -0
  178. package/dist/types/detection.js +5 -0
  179. package/dist/types/detection.js.map +1 -0
  180. package/dist/types/enforcement.d.ts +33 -0
  181. package/dist/types/enforcement.d.ts.map +1 -0
  182. package/dist/types/enforcement.js +5 -0
  183. package/dist/types/enforcement.js.map +1 -0
  184. package/dist/types/index.d.ts +8 -0
  185. package/dist/types/index.d.ts.map +1 -0
  186. package/dist/types/index.js +8 -0
  187. package/dist/types/index.js.map +1 -0
  188. package/dist/types/isolation.d.ts +55 -0
  189. package/dist/types/isolation.d.ts.map +1 -0
  190. package/dist/types/isolation.js +5 -0
  191. package/dist/types/isolation.js.map +1 -0
  192. package/dist/utils/exec.d.ts +48 -0
  193. package/dist/utils/exec.d.ts.map +1 -0
  194. package/dist/utils/exec.js +103 -0
  195. package/dist/utils/exec.js.map +1 -0
  196. package/dist/utils/fs.d.ts +34 -0
  197. package/dist/utils/fs.d.ts.map +1 -0
  198. package/dist/utils/fs.js +111 -0
  199. package/dist/utils/fs.js.map +1 -0
  200. package/dist/utils/index.d.ts +7 -0
  201. package/dist/utils/index.d.ts.map +1 -0
  202. package/dist/utils/index.js +7 -0
  203. package/dist/utils/index.js.map +1 -0
  204. package/dist/utils/logger.d.ts +14 -0
  205. package/dist/utils/logger.d.ts.map +1 -0
  206. package/dist/utils/logger.js +48 -0
  207. package/dist/utils/logger.js.map +1 -0
  208. package/docs/intune.md +390 -0
  209. package/docs/jamf.md +400 -0
  210. package/docs/jumpcloud.md +510 -0
  211. package/package.json +65 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Shell enforcement script template for MDM deployment.
3
+ * Targets macOS and Linux systems.
4
+ */
5
+ export interface EnforceShellOptions {
6
+ webhookUrl?: string;
7
+ webhookToken?: string;
8
+ gatewayPort?: number;
9
+ verbose?: boolean;
10
+ dryRun?: boolean;
11
+ quarantine?: boolean;
12
+ }
13
+ /**
14
+ * Generate enforcement shell script.
15
+ */
16
+ export declare function generateEnforceShellScript(options?: EnforceShellOptions): string;
17
+ /**
18
+ * Get script metadata for documentation.
19
+ */
20
+ export declare function getEnforceShellMetadata(): {
21
+ filename: string;
22
+ extension: string;
23
+ platform: string;
24
+ description: string;
25
+ requirements: string[];
26
+ exitCodes: {
27
+ 0: string;
28
+ 1: string;
29
+ 2: string;
30
+ 3: string;
31
+ };
32
+ };
33
+ //# sourceMappingURL=enforce.sh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforce.sh.d.ts","sourceRoot":"","sources":["../../../src/mdm/templates/enforce.sh.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAmCD;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAiiBpF;AAED;;GAEG;AACH,wBAAgB,uBAAuB;;;;;;;;;;;;EActC"}
@@ -0,0 +1,591 @@
1
+ /**
2
+ * Shell enforcement script template for MDM deployment.
3
+ * Targets macOS and Linux systems.
4
+ */
5
+ import { VERSION, COMPANY } from '../../branding.js';
6
+ /**
7
+ * Escape a string for safe use in shell scripts.
8
+ * Escapes characters that could enable shell injection.
9
+ */
10
+ function escapeShellString(str) {
11
+ // Remove null bytes
12
+ let escaped = str.replace(/\0/g, '');
13
+ // Escape backslashes first, then single quotes
14
+ escaped = escaped.replace(/\\/g, '\\\\');
15
+ escaped = escaped.replace(/'/g, "'\\''");
16
+ // Escape special shell characters
17
+ escaped = escaped.replace(/\$/g, '\\$');
18
+ escaped = escaped.replace(/`/g, '\\`');
19
+ escaped = escaped.replace(/"/g, '\\"');
20
+ escaped = escaped.replace(/!/g, '\\!');
21
+ return escaped;
22
+ }
23
+ /**
24
+ * Validate URL format for MDM scripts.
25
+ */
26
+ function validateMdmUrl(url) {
27
+ try {
28
+ const parsed = new URL(url);
29
+ if (!['http:', 'https:'].includes(parsed.protocol)) {
30
+ throw new Error('Invalid protocol');
31
+ }
32
+ return escapeShellString(url);
33
+ }
34
+ catch {
35
+ throw new Error(`Invalid webhook URL: ${url}`);
36
+ }
37
+ }
38
+ /**
39
+ * Generate enforcement shell script.
40
+ */
41
+ export function generateEnforceShellScript(options = {}) {
42
+ const { webhookUrl, webhookToken, gatewayPort = 18789, verbose = false, dryRun = false, quarantine = false, } = options;
43
+ // Validate and sanitize inputs to prevent shell injection
44
+ const safeWebhookUrl = webhookUrl ? validateMdmUrl(webhookUrl) : undefined;
45
+ const safeWebhookToken = webhookToken ? escapeShellString(webhookToken) : undefined;
46
+ // Validate gateway port
47
+ if (gatewayPort < 1 || gatewayPort > 65535 || !Number.isInteger(gatewayPort)) {
48
+ throw new Error(`Invalid gateway port: ${gatewayPort}`);
49
+ }
50
+ const webhookSection = safeWebhookUrl
51
+ ? `
52
+ # Webhook configuration
53
+ WEBHOOK_URL="${safeWebhookUrl}"
54
+ ${safeWebhookToken ? `WEBHOOK_TOKEN="${safeWebhookToken}"` : 'WEBHOOK_TOKEN=""'}
55
+
56
+ send_webhook() {
57
+ local status="$1"
58
+ local severity="$2"
59
+ local details="$3"
60
+
61
+ local payload
62
+ payload=$(cat <<PAYLOAD
63
+ {
64
+ "event": "openclaw.enforcement",
65
+ "version": "1.0",
66
+ "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
67
+ "status": "$status",
68
+ "severity": "$severity",
69
+ "host": {
70
+ "hostname": "$(hostname)",
71
+ "os": "$(uname -s)",
72
+ "arch": "$(uname -m)",
73
+ "user": "$USER"
74
+ },
75
+ "actions": "$details",
76
+ "dryRun": ${dryRun},
77
+ "source": {
78
+ "tool": "nox-openclaw-detector",
79
+ "version": "${VERSION}",
80
+ "vendor": "${COMPANY}"
81
+ }
82
+ }
83
+ PAYLOAD
84
+ )
85
+
86
+ local auth_header=""
87
+ if [[ -n "$WEBHOOK_TOKEN" ]]; then
88
+ auth_header="-H \\"Authorization: Bearer $WEBHOOK_TOKEN\\""
89
+ fi
90
+
91
+ curl -s -X POST "$WEBHOOK_URL" \\
92
+ -H "Content-Type: application/json" \\
93
+ $auth_header \\
94
+ -d "$payload" \\
95
+ --connect-timeout 10 \\
96
+ --max-time 30 > /dev/null 2>&1 || true
97
+ }
98
+ `
99
+ : '';
100
+ const verboseLog = verbose
101
+ ? `
102
+ log_verbose() {
103
+ echo "[DEBUG] $(date '+%Y-%m-%d %H:%M:%S') $1"
104
+ }
105
+ `
106
+ : `
107
+ log_verbose() { :; } # No-op when not verbose
108
+ `;
109
+ const dryRunCheck = dryRun
110
+ ? `
111
+ DRY_RUN=true
112
+ execute() {
113
+ log_action "[DRY RUN] Would execute: $*"
114
+ }
115
+ `
116
+ : `
117
+ DRY_RUN=false
118
+ execute() {
119
+ "$@"
120
+ }
121
+ `;
122
+ const quarantineSection = quarantine
123
+ ? `
124
+ # Quarantine configuration
125
+ QUARANTINE_BASE="/var/nox-quarantine"
126
+ QUARANTINE_ID="$(date +%Y%m%d_%H%M%S)_$(whoami)"
127
+ QUARANTINE_DIR="$QUARANTINE_BASE/$QUARANTINE_ID"
128
+
129
+ setup_quarantine() {
130
+ if [[ $DRY_RUN == true ]]; then
131
+ log_action "[DRY RUN] Would create quarantine directory: $QUARANTINE_DIR"
132
+ return
133
+ fi
134
+
135
+ mkdir -p "$QUARANTINE_DIR/binaries"
136
+ mkdir -p "$QUARANTINE_DIR/config"
137
+ mkdir -p "$QUARANTINE_DIR/services"
138
+
139
+ # Create manifest
140
+ cat > "$QUARANTINE_DIR/manifest.json" <<MANIFEST
141
+ {
142
+ "id": "$QUARANTINE_ID",
143
+ "timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
144
+ "hostname": "$(hostname)",
145
+ "user": "$(whoami)",
146
+ "artifacts": []
147
+ }
148
+ MANIFEST
149
+
150
+ log_action "Quarantine directory created: $QUARANTINE_DIR"
151
+ }
152
+
153
+ quarantine_file() {
154
+ local src="$1"
155
+ local category="$2"
156
+ local dest="$QUARANTINE_DIR/$category/$(basename "$src")"
157
+
158
+ if [[ $DRY_RUN == true ]]; then
159
+ log_action "[DRY RUN] Would quarantine: $src -> $dest"
160
+ return
161
+ fi
162
+
163
+ if [[ -e "$src" ]]; then
164
+ mv "$src" "$dest" 2>/dev/null || cp -r "$src" "$dest" && rm -rf "$src"
165
+ log_action "Quarantined: $src -> $dest"
166
+ fi
167
+ }
168
+ `
169
+ : `
170
+ quarantine_file() {
171
+ local src="$1"
172
+ # No quarantine, just remove
173
+ remove_path "$src"
174
+ }
175
+ `;
176
+ return `#!/bin/bash
177
+ # ==============================================================================
178
+ # Nox OpenClaw Enforcement Script
179
+ # ==============================================================================
180
+ # Generated by nox-openclaw-detector v${VERSION}
181
+ # ${COMPANY} - https://nox.security
182
+ #
183
+ # WARNING: This script will remove OpenClaw installations!
184
+ # Run with sudo/root for full enforcement capabilities.
185
+ #
186
+ # Exit Codes:
187
+ # 0 - Enforcement successful
188
+ # 1 - Enforcement partially failed
189
+ # 2 - Script error
190
+ # 3 - Nothing to enforce (clean system)
191
+ #
192
+ # Usage:
193
+ # sudo ./enforce-openclaw.sh
194
+ # sudo ./enforce-openclaw.sh --verbose
195
+ # ==============================================================================
196
+
197
+ set -uo pipefail
198
+
199
+ # Configuration
200
+ GATEWAY_PORT=${gatewayPort}
201
+ ENFORCEMENT_ACTIONS=()
202
+ FAILED_ACTIONS=()
203
+ OPENCLAW_DETECTED=false
204
+ ${verboseLog}
205
+ ${dryRunCheck}
206
+ ${webhookSection}
207
+ ${quarantine ? quarantineSection : ''}
208
+
209
+ # Log enforcement action
210
+ log_action() {
211
+ local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
212
+ echo "$msg"
213
+ ENFORCEMENT_ACTIONS+=("$1")
214
+ }
215
+
216
+ # Log failed action
217
+ log_failure() {
218
+ local msg="[$(date '+%Y-%m-%d %H:%M:%S')] FAILED: $1"
219
+ echo "$msg" >&2
220
+ FAILED_ACTIONS+=("$1")
221
+ }
222
+
223
+ # Remove file or directory
224
+ remove_path() {
225
+ local path="$1"
226
+
227
+ if [[ ! -e "$path" ]]; then
228
+ return 0
229
+ fi
230
+
231
+ OPENCLAW_DETECTED=true
232
+
233
+ if [[ $DRY_RUN == true ]]; then
234
+ log_action "[DRY RUN] Would remove: $path"
235
+ return 0
236
+ fi
237
+
238
+ if rm -rf "$path" 2>/dev/null; then
239
+ log_action "Removed: $path"
240
+ return 0
241
+ else
242
+ log_failure "Could not remove: $path"
243
+ return 1
244
+ fi
245
+ }
246
+
247
+ # Check if running as root
248
+ check_privileges() {
249
+ if [[ $EUID -ne 0 ]]; then
250
+ echo "Warning: Not running as root. Some enforcement actions may fail."
251
+ echo "For complete enforcement, run: sudo $0"
252
+ echo ""
253
+ fi
254
+ }
255
+
256
+ # Kill OpenClaw processes
257
+ kill_processes() {
258
+ log_action "Checking for OpenClaw processes..."
259
+
260
+ local pids
261
+ pids=$(pgrep -f "openclaw" 2>/dev/null || true)
262
+
263
+ if [[ -n "$pids" ]]; then
264
+ OPENCLAW_DETECTED=true
265
+
266
+ if [[ $DRY_RUN == true ]]; then
267
+ log_action "[DRY RUN] Would kill processes: $pids"
268
+ return 0
269
+ fi
270
+
271
+ for pid in $pids; do
272
+ if kill -9 "$pid" 2>/dev/null; then
273
+ log_action "Killed process: $pid"
274
+ else
275
+ log_failure "Could not kill process: $pid"
276
+ fi
277
+ done
278
+ else
279
+ log_verbose "No OpenClaw processes found"
280
+ fi
281
+ }
282
+
283
+ # Stop and disable launchd services (macOS)
284
+ enforce_launchd() {
285
+ if [[ "$(uname -s)" != "Darwin" ]]; then
286
+ return
287
+ fi
288
+
289
+ log_action "Checking launchd services..."
290
+
291
+ local plist_patterns=("bot.molt" "openclaw")
292
+ local search_dirs=(
293
+ "$HOME/Library/LaunchAgents"
294
+ "/Library/LaunchAgents"
295
+ "/Library/LaunchDaemons"
296
+ )
297
+
298
+ for dir in "\${search_dirs[@]}"; do
299
+ if [[ ! -d "$dir" ]]; then
300
+ continue
301
+ fi
302
+
303
+ for pattern in "\${plist_patterns[@]}"; do
304
+ for plist in "$dir"/*"$pattern"*.plist; do
305
+ if [[ -f "$plist" ]]; then
306
+ OPENCLAW_DETECTED=true
307
+
308
+ if [[ $DRY_RUN == true ]]; then
309
+ log_action "[DRY RUN] Would unload and remove: $plist"
310
+ continue
311
+ fi
312
+
313
+ # Unload the service
314
+ launchctl unload "$plist" 2>/dev/null || true
315
+ launchctl bootout system "$plist" 2>/dev/null || true
316
+ launchctl bootout gui/$(id -u) "$plist" 2>/dev/null || true
317
+
318
+ # Quarantine or remove the plist
319
+ ${quarantine ? 'quarantine_file "$plist" "services"' : 'remove_path "$plist"'}
320
+
321
+ log_action "Disabled launchd service: $plist"
322
+ fi
323
+ done
324
+ done
325
+ done
326
+ }
327
+
328
+ # Stop and disable systemd services (Linux)
329
+ enforce_systemd() {
330
+ if ! command -v systemctl &>/dev/null; then
331
+ return
332
+ fi
333
+
334
+ log_action "Checking systemd services..."
335
+
336
+ local service_names=("openclaw" "openclaw.service" "bot.molt.gateway")
337
+
338
+ for service in "\${service_names[@]}"; do
339
+ if systemctl list-unit-files "$service" &>/dev/null 2>&1; then
340
+ OPENCLAW_DETECTED=true
341
+
342
+ if [[ $DRY_RUN == true ]]; then
343
+ log_action "[DRY RUN] Would stop and disable: $service"
344
+ continue
345
+ fi
346
+
347
+ systemctl stop "$service" 2>/dev/null || true
348
+ systemctl disable "$service" 2>/dev/null || true
349
+ log_action "Stopped and disabled systemd service: $service"
350
+ fi
351
+ done
352
+
353
+ # Remove service files
354
+ local service_paths=(
355
+ "/etc/systemd/system/openclaw.service"
356
+ "/usr/lib/systemd/system/openclaw.service"
357
+ "$HOME/.config/systemd/user/openclaw.service"
358
+ )
359
+
360
+ for service_path in "\${service_paths[@]}"; do
361
+ if [[ -f "$service_path" ]]; then
362
+ OPENCLAW_DETECTED=true
363
+ ${quarantine ? 'quarantine_file "$service_path" "services"' : 'remove_path "$service_path"'}
364
+ fi
365
+ done
366
+
367
+ # Reload systemd
368
+ if [[ $DRY_RUN == false ]]; then
369
+ systemctl daemon-reload 2>/dev/null || true
370
+ fi
371
+ }
372
+
373
+ # Remove CLI binaries
374
+ remove_cli_binaries() {
375
+ log_action "Checking for CLI binaries..."
376
+
377
+ local cli_paths=(
378
+ "/usr/local/bin/openclaw"
379
+ "/opt/homebrew/bin/openclaw"
380
+ "/usr/bin/openclaw"
381
+ "$HOME/.local/bin/openclaw"
382
+ "$HOME/bin/openclaw"
383
+ )
384
+
385
+ for cli_path in "\${cli_paths[@]}"; do
386
+ if [[ -f "$cli_path" ]]; then
387
+ OPENCLAW_DETECTED=true
388
+ ${quarantine ? 'quarantine_file "$cli_path" "binaries"' : 'remove_path "$cli_path"'}
389
+ fi
390
+ done
391
+ }
392
+
393
+ # Remove macOS app bundle
394
+ remove_app_bundle() {
395
+ if [[ "$(uname -s)" != "Darwin" ]]; then
396
+ return
397
+ fi
398
+
399
+ log_action "Checking for macOS app bundle..."
400
+
401
+ local app_paths=(
402
+ "/Applications/OpenClaw.app"
403
+ "$HOME/Applications/OpenClaw.app"
404
+ )
405
+
406
+ for app_path in "\${app_paths[@]}"; do
407
+ if [[ -d "$app_path" ]]; then
408
+ OPENCLAW_DETECTED=true
409
+ ${quarantine ? 'quarantine_file "$app_path" "binaries"' : 'remove_path "$app_path"'}
410
+ fi
411
+ done
412
+ }
413
+
414
+ # Remove configuration directories
415
+ remove_config_directories() {
416
+ log_action "Checking for configuration directories..."
417
+
418
+ # Current user
419
+ if [[ -d "$HOME/.openclaw" ]]; then
420
+ OPENCLAW_DETECTED=true
421
+ ${quarantine ? 'quarantine_file "$HOME/.openclaw" "config"' : 'remove_path "$HOME/.openclaw"'}
422
+ fi
423
+
424
+ # Other users (requires root)
425
+ if [[ $EUID -eq 0 ]]; then
426
+ for user_home in /Users/* /home/*; do
427
+ local config_dir="$user_home/.openclaw"
428
+ if [[ -d "$config_dir" && "$config_dir" != "$HOME/.openclaw" ]]; then
429
+ OPENCLAW_DETECTED=true
430
+ ${quarantine ? 'quarantine_file "$config_dir" "config"' : 'remove_path "$config_dir"'}
431
+ fi
432
+ done
433
+ fi
434
+ }
435
+
436
+ # Clean Docker artifacts
437
+ clean_docker() {
438
+ if ! command -v docker &>/dev/null; then
439
+ return
440
+ fi
441
+
442
+ log_action "Checking for Docker artifacts..."
443
+
444
+ # Stop and remove containers
445
+ local containers
446
+ containers=$(docker ps -a --filter "name=openclaw" --format "{{.ID}}" 2>/dev/null || true)
447
+
448
+ if [[ -n "$containers" ]]; then
449
+ OPENCLAW_DETECTED=true
450
+
451
+ if [[ $DRY_RUN == true ]]; then
452
+ log_action "[DRY RUN] Would remove Docker containers: $containers"
453
+ else
454
+ for container in $containers; do
455
+ docker stop "$container" 2>/dev/null || true
456
+ docker rm -f "$container" 2>/dev/null || true
457
+ log_action "Removed Docker container: $container"
458
+ done
459
+ fi
460
+ fi
461
+
462
+ # Remove images
463
+ local images
464
+ images=$(docker images --filter "reference=*openclaw*" --format "{{.ID}}" 2>/dev/null || true)
465
+
466
+ if [[ -n "$images" ]]; then
467
+ OPENCLAW_DETECTED=true
468
+
469
+ if [[ $DRY_RUN == true ]]; then
470
+ log_action "[DRY RUN] Would remove Docker images: $images"
471
+ else
472
+ for image in $images; do
473
+ docker rmi -f "$image" 2>/dev/null || true
474
+ log_action "Removed Docker image: $image"
475
+ done
476
+ fi
477
+ fi
478
+ }
479
+
480
+ # Block gateway port (optional isolation)
481
+ block_gateway_port() {
482
+ if [[ "${options.quarantine ? 'true' : 'false'}" != "true" ]]; then
483
+ return
484
+ fi
485
+
486
+ log_action "Blocking gateway port $GATEWAY_PORT..."
487
+
488
+ if [[ $DRY_RUN == true ]]; then
489
+ log_action "[DRY RUN] Would block port $GATEWAY_PORT"
490
+ return
491
+ fi
492
+
493
+ if [[ "$(uname -s)" == "Darwin" ]]; then
494
+ # macOS: use pf
495
+ echo "block drop out proto tcp from any to any port $GATEWAY_PORT" | pfctl -ef - 2>/dev/null && \
496
+ log_action "Blocked port $GATEWAY_PORT via pf" || \
497
+ log_failure "Could not block port via pf"
498
+ else
499
+ # Linux: use iptables
500
+ iptables -A OUTPUT -p tcp --dport "$GATEWAY_PORT" -j DROP 2>/dev/null && \
501
+ log_action "Blocked port $GATEWAY_PORT via iptables" || \
502
+ log_failure "Could not block port via iptables"
503
+ fi
504
+ }
505
+
506
+ # Main enforcement routine
507
+ main() {
508
+ echo "=============================================="
509
+ echo "Nox OpenClaw Enforcement"
510
+ echo "=============================================="
511
+ ${dryRun ? 'echo "[DRY RUN MODE - No changes will be made]"' : ''}
512
+ echo ""
513
+
514
+ check_privileges
515
+
516
+ ${quarantine ? 'setup_quarantine' : ''}
517
+
518
+ # Execute enforcement actions in order
519
+ kill_processes
520
+ enforce_launchd
521
+ enforce_systemd
522
+ remove_cli_binaries
523
+ remove_app_bundle
524
+ remove_config_directories
525
+ clean_docker
526
+ block_gateway_port
527
+
528
+ # Compile results
529
+ local actions_string=""
530
+ if [[ \${#ENFORCEMENT_ACTIONS[@]} -gt 0 ]]; then
531
+ actions_string=$(IFS="; "; echo "\${ENFORCEMENT_ACTIONS[*]}")
532
+ fi
533
+
534
+ echo ""
535
+ echo "=============================================="
536
+ echo "Enforcement Summary"
537
+ echo "=============================================="
538
+
539
+ # Send webhook notification
540
+ ${safeWebhookUrl ? `
541
+ if [[ $OPENCLAW_DETECTED == true ]]; then
542
+ if [[ \${#FAILED_ACTIONS[@]} -eq 0 ]]; then
543
+ send_webhook "success" "high" "$actions_string"
544
+ else
545
+ send_webhook "partial" "high" "$actions_string"
546
+ fi
547
+ else
548
+ send_webhook "clean" "info" "No OpenClaw installation found"
549
+ fi
550
+ ` : ''}
551
+
552
+ if [[ $OPENCLAW_DETECTED == false ]]; then
553
+ echo "No OpenClaw installation detected. System is clean."
554
+ exit 3
555
+ elif [[ \${#FAILED_ACTIONS[@]} -gt 0 ]]; then
556
+ echo "Enforcement partially completed with \${#FAILED_ACTIONS[@]} failures:"
557
+ for failure in "\${FAILED_ACTIONS[@]}"; do
558
+ echo " - $failure"
559
+ done
560
+ exit 1
561
+ else
562
+ echo "Enforcement completed successfully."
563
+ echo "Actions taken: \${#ENFORCEMENT_ACTIONS[@]}"
564
+ ${quarantine ? 'echo "Quarantine location: $QUARANTINE_DIR"' : ''}
565
+ exit 0
566
+ fi
567
+ }
568
+
569
+ # Run main function
570
+ main "$@"
571
+ `;
572
+ }
573
+ /**
574
+ * Get script metadata for documentation.
575
+ */
576
+ export function getEnforceShellMetadata() {
577
+ return {
578
+ filename: 'enforce-openclaw.sh',
579
+ extension: '.sh',
580
+ platform: 'unix',
581
+ description: 'Shell enforcement script for macOS and Linux',
582
+ requirements: ['bash 4.0+', 'Root/sudo access (recommended)', 'Standard Unix utilities'],
583
+ exitCodes: {
584
+ 0: 'Enforcement successful',
585
+ 1: 'Enforcement partially failed',
586
+ 2: 'Script error',
587
+ 3: 'Nothing to enforce (clean system)',
588
+ },
589
+ };
590
+ }
591
+ //# sourceMappingURL=enforce.sh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enforce.sh.js","sourceRoot":"","sources":["../../../src/mdm/templates/enforce.sh.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * macOS (Darwin) platform implementation.
3
+ */
4
+ import type { Platform } from './index.js';
5
+ export declare const darwin: Platform;
6
+ //# sourceMappingURL=darwin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"darwin.d.ts","sourceRoot":"","sources":["../../src/platform/darwin.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAQxD,eAAO,MAAM,MAAM,EAAE,QAyMpB,CAAC"}