@trillboards/edge-sdk 0.2.21 → 0.2.24
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/deploy/macos/scripts/setup-litertlm.sh +30 -0
- package/deploy/windows/e2e/test-enterprise-trust-store.ps1 +341 -0
- package/deploy/windows/setup-litertlm.ps1 +49 -1
- package/dist/AudienceAnalyzeClient.d.ts +32 -1
- package/dist/AudienceAnalyzeClient.d.ts.map +1 -1
- package/dist/AudienceAnalyzeClient.js +34 -5
- package/dist/AudienceAnalyzeClient.js.map +1 -1
- package/dist/CloudSensingManager.d.ts +30 -0
- package/dist/CloudSensingManager.d.ts.map +1 -1
- package/dist/CloudSensingManager.js +61 -1
- package/dist/CloudSensingManager.js.map +1 -1
- package/dist/EdgeAgent.js +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +60 -0
- package/dist/cli.js.map +1 -1
- package/dist/diagnose.d.ts +37 -4
- package/dist/diagnose.d.ts.map +1 -1
- package/dist/diagnose.js +155 -6
- package/dist/diagnose.js.map +1 -1
- package/dist/enterpriseNetwork.d.ts +130 -0
- package/dist/enterpriseNetwork.d.ts.map +1 -0
- package/dist/enterpriseNetwork.js +568 -0
- package/dist/enterpriseNetwork.js.map +1 -0
- package/dist/enterpriseProxy.d.ts +73 -0
- package/dist/enterpriseProxy.d.ts.map +1 -0
- package/dist/enterpriseProxy.js +406 -0
- package/dist/enterpriseProxy.js.map +1 -0
- package/dist/enterpriseTrust.d.ts +188 -0
- package/dist/enterpriseTrust.d.ts.map +1 -0
- package/dist/enterpriseTrust.js +615 -0
- package/dist/enterpriseTrust.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -1
- package/dist/index.js.map +1 -1
- package/dist/localNetworkAccess.d.ts +166 -0
- package/dist/localNetworkAccess.d.ts.map +1 -0
- package/dist/localNetworkAccess.js +490 -0
- package/dist/localNetworkAccess.js.map +1 -0
- package/dist/sensingRunMode.d.ts +36 -0
- package/dist/sensingRunMode.d.ts.map +1 -1
- package/dist/sensingRunMode.js +63 -1
- package/dist/sensingRunMode.js.map +1 -1
- package/dist/transportFailure.d.ts +118 -0
- package/dist/transportFailure.d.ts.map +1 -0
- package/dist/transportFailure.js +267 -0
- package/dist/transportFailure.js.map +1 -0
- package/package.json +1 -1
|
@@ -168,6 +168,36 @@ if [ "$HOST_OS" = "Darwin" ] && [ "$HOST_ARCH" != "arm64" ]; then
|
|
|
168
168
|
exit 0
|
|
169
169
|
fi
|
|
170
170
|
|
|
171
|
+
# 0b. Enterprise TLS + proxy for uv.
|
|
172
|
+
#
|
|
173
|
+
# uv ships bundled Mozilla roots and does NOT consult the macOS keychain, so on
|
|
174
|
+
# a network that inspects TLS this step is the first thing that fails -- and it
|
|
175
|
+
# fails with a message about local AI, which is the wrong cause. UV_SYSTEM_CERTS
|
|
176
|
+
# switches it to the platform's native verifier; UV_NATIVE_TLS is the older,
|
|
177
|
+
# deprecated-but-still-read name for the same setting, exported too because
|
|
178
|
+
# `uv tool install` here is UNPINNED and the version that lands is whatever is
|
|
179
|
+
# current that day. An unknown env var is ignored, so both are safe; a CLI flag
|
|
180
|
+
# would fail outright on a version that does not have it.
|
|
181
|
+
export UV_SYSTEM_CERTS=1
|
|
182
|
+
export UV_NATIVE_TLS=1
|
|
183
|
+
|
|
184
|
+
# The proxy half: uv reads only the environment, never the macOS system proxy
|
|
185
|
+
# settings. Fill them in from scutil when the operator has not set them already.
|
|
186
|
+
if [ -z "${HTTPS_PROXY:-}" ] && [ -z "${https_proxy:-}" ] && [ -z "${ALL_PROXY:-}" ]; then
|
|
187
|
+
_proxy_conf="$(/usr/sbin/scutil --proxy 2>/dev/null || true)"
|
|
188
|
+
_proxy_enabled="$(printf '%s\n' "$_proxy_conf" | awk '/HTTPSEnable/ {print $3}')"
|
|
189
|
+
if [ "$_proxy_enabled" = "1" ]; then
|
|
190
|
+
_proxy_host="$(printf '%s\n' "$_proxy_conf" | awk '/HTTPSProxy/ {print $3}')"
|
|
191
|
+
_proxy_port="$(printf '%s\n' "$_proxy_conf" | awk '/HTTPSPort/ {print $3}')"
|
|
192
|
+
if [ -n "$_proxy_host" ]; then
|
|
193
|
+
HTTPS_PROXY="http://$_proxy_host${_proxy_port:+:$_proxy_port}"
|
|
194
|
+
export HTTPS_PROXY
|
|
195
|
+
export HTTP_PROXY="$HTTPS_PROXY"
|
|
196
|
+
log "using this machine's configured proxy for local AI downloads: $HTTPS_PROXY"
|
|
197
|
+
fi
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
|
|
171
201
|
# 1. uv (PATH first; else official standalone installer, home-domain).
|
|
172
202
|
export PATH="$LOCAL_BIN:$USER_HOME/.cargo/bin:$PATH"
|
|
173
203
|
if ! command -v uv >/dev/null 2>&1; then
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
<#
|
|
2
|
+
RUNTIME PROOF: the connector reads THIS MACHINE'S Windows certificate store,
|
|
3
|
+
and still refuses a certificate that store does not vouch for.
|
|
4
|
+
|
|
5
|
+
WHY THIS EXISTS
|
|
6
|
+
---------------
|
|
7
|
+
Node ships its own Mozilla-derived root list and does not consult the Windows
|
|
8
|
+
store, so behind a TLS-inspecting corporate proxy the connector could not
|
|
9
|
+
reach the API at all -- on the repair install path, silently, in a background
|
|
10
|
+
process with no window. The Node-side fix reads the Root stores at runtime.
|
|
11
|
+
Everything about that fix is Windows-specific and the merge-gating CI lane is
|
|
12
|
+
Linux, so on Linux the store reader is exercised only through an injected
|
|
13
|
+
seam. This script is the half that is NOT a seam: it imports a throwaway
|
|
14
|
+
certificate into the REAL LocalMachine\Root store and measures what the REAL
|
|
15
|
+
shipped code does with it.
|
|
16
|
+
|
|
17
|
+
WHAT IT PROVES, AND THE CONTROL FOR EACH
|
|
18
|
+
----------------------------------------
|
|
19
|
+
A. BEFORE the import, the connector REFUSES the inspecting proxy's
|
|
20
|
+
certificate. <- the failing control. If this passes, the machine already
|
|
21
|
+
trusted the root and every later assertion is vacuous.
|
|
22
|
+
It also asserts the store read returned SOMETHING and the request really
|
|
23
|
+
went through the proxy, so B cannot pass for the wrong reason.
|
|
24
|
+
B. AFTER the import, the SAME request succeeds. Only the store changed.
|
|
25
|
+
C. AFTER the import, a certificate from a DIFFERENT root is STILL refused.
|
|
26
|
+
This is the assertion `rejectUnauthorized:false` would fail, and it is
|
|
27
|
+
the whole reason B is not evidence of a security regression.
|
|
28
|
+
D. The store read is not blocked by execution policy: it keeps working under
|
|
29
|
+
a machine-scope AllSigned GPO, which is the estate this work targets.
|
|
30
|
+
(The reader uses `powershell -Command`, and execution policy governs
|
|
31
|
+
script FILES; a regression to `-File` would fail exactly here.)
|
|
32
|
+
|
|
33
|
+
It REQUIRES elevation, and it must import into LocalMachine\Root specifically.
|
|
34
|
+
CurrentUser\Root is writable by the signed-in user in the ACL sense, which is
|
|
35
|
+
exactly what makes it a trap: a write to a CurrentUser TRUST-ANCHOR store is
|
|
36
|
+
gated behind an interactive "you are about to install a certificate from a
|
|
37
|
+
certification authority" consent dialog. On a headless runner nobody can answer
|
|
38
|
+
it, so Import-Certificate BLOCKS rather than fails -- it hung 23 minutes and ate
|
|
39
|
+
the job's entire timeout on 2026-08-15, reporting neither pass nor fail.
|
|
40
|
+
LocalMachine\Root is gated by administrator rights instead of by a dialog, so it
|
|
41
|
+
is non-interactive. That costs nothing here: CASE D already sets a machine-scope
|
|
42
|
+
execution policy, so this script has always needed admin, and hosted
|
|
43
|
+
windows-latest is elevated. It is also the more faithful test -- an AD GPO
|
|
44
|
+
pushes an enterprise root to LocalMachine\Root, and the connector runs as a
|
|
45
|
+
service, which has no CurrentUser store of its own.
|
|
46
|
+
The reader consults both LocalMachine\Root and CurrentUser\Root.
|
|
47
|
+
|
|
48
|
+
Certificates live in Cert:\CurrentUser\My + a temp dir for the life of the run
|
|
49
|
+
and are removed in the finally block. Nothing is printed.
|
|
50
|
+
#>
|
|
51
|
+
[CmdletBinding()]
|
|
52
|
+
param(
|
|
53
|
+
[string]$RepoRoot = (Resolve-Path (Join-Path $PSScriptRoot "..\..\..\..\..\..")).Path
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
$ErrorActionPreference = "Stop"
|
|
57
|
+
$ProgressPreference = "SilentlyContinue"
|
|
58
|
+
|
|
59
|
+
$work = Join-Path $env:RUNNER_TEMP ("tb-trust-proof-" + [Guid]::NewGuid().ToString("N").Substring(0, 8))
|
|
60
|
+
$sdkDir = Join-Path $RepoRoot "trillboards-edge-sdk\packages\edge-sdk"
|
|
61
|
+
$TARGET_DNS = "api.trillboards.test"
|
|
62
|
+
$minted = @()
|
|
63
|
+
$trustedThumbprint = $null
|
|
64
|
+
$policyChanged = $false
|
|
65
|
+
# Prior MachinePolicy registry state, captured in CASE D and restored in finally.
|
|
66
|
+
$polKeyExisted = $false
|
|
67
|
+
$priorEnable = $null
|
|
68
|
+
$priorPolicy = $null
|
|
69
|
+
|
|
70
|
+
function Fail([string]$Message) {
|
|
71
|
+
Write-Host "FAIL: $Message"
|
|
72
|
+
exit 1
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# New-SelfSignedCertificate is the native path here: no openssl on PATH is
|
|
76
|
+
# required (Git for Windows ships one but does not put it on PATH on the hosted
|
|
77
|
+
# images), and a -Signer chain is exactly the CA -> leaf shape we need.
|
|
78
|
+
function New-ProofCa([string]$CommonName) {
|
|
79
|
+
$ca = New-SelfSignedCertificate `
|
|
80
|
+
-Type Custom `
|
|
81
|
+
-Subject "CN=$CommonName" `
|
|
82
|
+
-KeyExportPolicy Exportable `
|
|
83
|
+
-KeyUsage CertSign, CRLSign `
|
|
84
|
+
-TextExtension @("2.5.29.19={text}CA=true&pathlength=0") `
|
|
85
|
+
-CertStoreLocation "Cert:\CurrentUser\My" `
|
|
86
|
+
-NotAfter (Get-Date).AddHours(2)
|
|
87
|
+
$script:minted += $ca.Thumbprint
|
|
88
|
+
return $ca
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function New-ProofLeaf($Ca, [string]$Dns) {
|
|
92
|
+
$leaf = New-SelfSignedCertificate `
|
|
93
|
+
-Type Custom `
|
|
94
|
+
-Subject "CN=$Dns" `
|
|
95
|
+
-DnsName $Dns `
|
|
96
|
+
-KeyExportPolicy Exportable `
|
|
97
|
+
-Signer $Ca `
|
|
98
|
+
-CertStoreLocation "Cert:\CurrentUser\My" `
|
|
99
|
+
-NotAfter (Get-Date).AddHours(2)
|
|
100
|
+
$script:minted += $leaf.Thumbprint
|
|
101
|
+
return $leaf
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
New-Item -ItemType Directory -Force -Path $work | Out-Null
|
|
106
|
+
|
|
107
|
+
Write-Host "== Minting a throwaway inspection CA and one for the negative control =="
|
|
108
|
+
$ca = New-ProofCa -CommonName "Trillboards Windows Trust Proof CA"
|
|
109
|
+
$otherCa = New-ProofCa -CommonName "Trillboards Windows Trust Proof OTHER CA"
|
|
110
|
+
$leaf = New-ProofLeaf -Ca $ca -Dns $TARGET_DNS
|
|
111
|
+
$otherLeaf = New-ProofLeaf -Ca $otherCa -Dns $TARGET_DNS
|
|
112
|
+
|
|
113
|
+
$pfxPassword = ConvertTo-SecureString -String ([Guid]::NewGuid().ToString("N")) -AsPlainText -Force
|
|
114
|
+
$pfxPlain = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
|
|
115
|
+
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($pfxPassword))
|
|
116
|
+
$leafPfx = Join-Path $work "leaf.pfx"
|
|
117
|
+
$otherPfx = Join-Path $work "otherleaf.pfx"
|
|
118
|
+
$caCer = Join-Path $work "ca.cer"
|
|
119
|
+
Export-PfxCertificate -Cert $leaf -FilePath $leafPfx -Password $pfxPassword | Out-Null
|
|
120
|
+
Export-PfxCertificate -Cert $otherLeaf -FilePath $otherPfx -Password $pfxPassword | Out-Null
|
|
121
|
+
Export-Certificate -Cert $ca -FilePath $caCer -Type CERT | Out-Null
|
|
122
|
+
|
|
123
|
+
# The probe: an inspecting proxy plus the SHIPPED agent, driven from Node so
|
|
124
|
+
# that what is measured is the real dist/ build and not a re-implementation.
|
|
125
|
+
$probe = Join-Path $work "probe.js"
|
|
126
|
+
$probeBody = @'
|
|
127
|
+
// Stands up a CONNECT proxy that terminates TLS itself (an inspection
|
|
128
|
+
// appliance), points the SHIPPED EnterpriseHttpsAgent at it, and reports what
|
|
129
|
+
// happened as one line of JSON. Trust anchors come from the REAL Windows store
|
|
130
|
+
// via the shipped reader -- nothing is injected.
|
|
131
|
+
const fs = require('fs');
|
|
132
|
+
const net = require('net');
|
|
133
|
+
const https = require('https');
|
|
134
|
+
const sdk = require(process.argv[2]);
|
|
135
|
+
|
|
136
|
+
const pfx = fs.readFileSync(process.argv[3]);
|
|
137
|
+
const passphrase = process.argv[4];
|
|
138
|
+
const TARGET = 'api.trillboards.test';
|
|
139
|
+
|
|
140
|
+
const inspector = https.createServer({ pfx, passphrase }, (_req, res) => {
|
|
141
|
+
res.writeHead(200, { 'content-type': 'application/json' });
|
|
142
|
+
res.end('{"ok":true}');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const proxy = net.createServer((socket) => {
|
|
146
|
+
socket.once('data', (chunk) => {
|
|
147
|
+
if (!chunk.toString('latin1').startsWith('CONNECT ')) { socket.end('HTTP/1.1 405\r\n\r\n'); return; }
|
|
148
|
+
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
|
|
149
|
+
inspector.emit('connection', socket);
|
|
150
|
+
});
|
|
151
|
+
socket.on('error', () => {});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
proxy.listen(0, '127.0.0.1', () => {
|
|
155
|
+
const port = proxy.address().port;
|
|
156
|
+
process.env.HTTPS_PROXY = 'http://127.0.0.1:' + port;
|
|
157
|
+
// The REAL reader, against the REAL CurrentUser\Root + LocalMachine\Root.
|
|
158
|
+
sdk.resetEnterpriseNetworkCaches();
|
|
159
|
+
const posture = sdk.describeNetworkPosture('https://' + TARGET);
|
|
160
|
+
const agent = sdk.getEnterpriseAgent();
|
|
161
|
+
const done = (result) => {
|
|
162
|
+
console.log(JSON.stringify(Object.assign({
|
|
163
|
+
anchorCount: posture.trust.certs.length,
|
|
164
|
+
anchorSources: posture.trust.sources.map((s) => s.name),
|
|
165
|
+
anchorWarnings: posture.trust.warnings,
|
|
166
|
+
proxyUrl: posture.proxy.proxyUrl,
|
|
167
|
+
}, result)));
|
|
168
|
+
proxy.close(); inspector.close(); agent.destroy(); process.exit(0);
|
|
169
|
+
};
|
|
170
|
+
const req = https.request('https://' + TARGET + '/health/live', { agent, timeout: 10000 }, (res) => {
|
|
171
|
+
res.resume();
|
|
172
|
+
res.on('end', () => done({ outcome: 'connected', statusCode: res.statusCode }));
|
|
173
|
+
});
|
|
174
|
+
req.on('timeout', () => req.destroy(new Error('probe timed out')));
|
|
175
|
+
req.on('error', (err) => done({
|
|
176
|
+
outcome: 'refused',
|
|
177
|
+
code: err.code || null,
|
|
178
|
+
failureClass: sdk.classifyTransportError(err, {}).failureClass,
|
|
179
|
+
}));
|
|
180
|
+
req.end();
|
|
181
|
+
});
|
|
182
|
+
'@
|
|
183
|
+
Set-Content -LiteralPath $probe -Value $probeBody -Encoding Ascii
|
|
184
|
+
|
|
185
|
+
# Build from the MONOREPO root, not the package: edge-sdk requires its sibling
|
|
186
|
+
# workspaces at runtime, so a package-scoped build silently depends on some
|
|
187
|
+
# earlier step in this job having built them. Building all of them here means
|
|
188
|
+
# this script is correct on its own and cannot be broken by a step reorder.
|
|
189
|
+
Write-Host "== Building the SDK so the probe measures the shipped build =="
|
|
190
|
+
Push-Location (Join-Path $RepoRoot "trillboards-edge-sdk")
|
|
191
|
+
& npm run build 2>&1 | Out-Null
|
|
192
|
+
$buildExit = $LASTEXITCODE
|
|
193
|
+
Pop-Location
|
|
194
|
+
if ($buildExit -ne 0) { Fail "edge-sdk build failed (exit $buildExit)" }
|
|
195
|
+
$sdkEntry = Join-Path $sdkDir "dist\index.js"
|
|
196
|
+
if (-not (Test-Path -LiteralPath $sdkEntry)) { Fail "edge-sdk dist/index.js is missing after the build" }
|
|
197
|
+
|
|
198
|
+
function Invoke-Probe([string]$Pfx) {
|
|
199
|
+
$raw = & node $probe $sdkEntry $Pfx $pfxPlain
|
|
200
|
+
if ($LASTEXITCODE -ne 0) { throw "probe exited $LASTEXITCODE" }
|
|
201
|
+
return (($raw | Select-Object -Last 1) | ConvertFrom-Json)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# ---------------------------------------------------------------- CONTROL A
|
|
205
|
+
Write-Host ""
|
|
206
|
+
Write-Host "== CONTROL A: before the import, the inspection cert must be REFUSED =="
|
|
207
|
+
$before = Invoke-Probe -Pfx $leafPfx
|
|
208
|
+
Write-Host (" anchors read from the machine store: {0}" -f $before.anchorCount)
|
|
209
|
+
Write-Host (" sources: {0}" -f ($before.anchorSources -join ", "))
|
|
210
|
+
Write-Host (" warnings: {0}" -f ($before.anchorWarnings -join "; "))
|
|
211
|
+
Write-Host (" proxy in use: {0}" -f $before.proxyUrl)
|
|
212
|
+
Write-Host (" outcome: {0} {1} {2}" -f $before.outcome, $before.code, $before.failureClass)
|
|
213
|
+
if ($before.outcome -ne "refused") {
|
|
214
|
+
Fail "the untrusted inspection certificate was ACCEPTED before the import -- this probe cannot prove anything"
|
|
215
|
+
}
|
|
216
|
+
if ($before.failureClass -ne "tls_untrusted_root") {
|
|
217
|
+
Fail "expected failureClass tls_untrusted_root before the import, got '$($before.failureClass)'"
|
|
218
|
+
}
|
|
219
|
+
# The reader must have actually run. A store read that silently returned
|
|
220
|
+
# nothing would make case B below pass for the wrong reason.
|
|
221
|
+
if ([int]$before.anchorCount -lt 1) {
|
|
222
|
+
# The warnings are printed above. They are the whole point: the first version
|
|
223
|
+
# of the reader came back empty here with nothing to say about why, which
|
|
224
|
+
# cost a full windows-latest cycle to diagnose. Anything that reaches this
|
|
225
|
+
# line without an actionable warning above it is a reader bug of its own.
|
|
226
|
+
Fail "the Windows trust store read returned NO certificates -- see the warnings above; the reader did not run"
|
|
227
|
+
}
|
|
228
|
+
if (-not ("$($before.proxyUrl)" -like "http://127.0.0.1:*")) {
|
|
229
|
+
Fail "the probe did not go through the proxy -- HTTPS_PROXY was not honoured"
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# ---------------------------------------------------------------- CASE B
|
|
233
|
+
Write-Host ""
|
|
234
|
+
Write-Host "== CASE B: import the root into LocalMachine\Root and retry =="
|
|
235
|
+
# LocalMachine, NOT CurrentUser. A write to a CurrentUser trust-anchor store
|
|
236
|
+
# raises an interactive consent dialog, which on a headless runner never gets
|
|
237
|
+
# answered and hangs this script forever (see the header). LocalMachine\Root is
|
|
238
|
+
# admin-gated instead, and is where a GPO-pushed enterprise root actually lands.
|
|
239
|
+
$imported = Import-Certificate -FilePath $caCer -CertStoreLocation "Cert:\LocalMachine\Root"
|
|
240
|
+
$trustedThumbprint = $imported.Thumbprint
|
|
241
|
+
Write-Host " imported into Cert:\LocalMachine\Root (thumbprint recorded for cleanup)"
|
|
242
|
+
|
|
243
|
+
$after = Invoke-Probe -Pfx $leafPfx
|
|
244
|
+
Write-Host (" anchors read from the machine store: {0}" -f $after.anchorCount)
|
|
245
|
+
Write-Host (" outcome: {0} {1} {2}" -f $after.outcome, $after.statusCode, $after.failureClass)
|
|
246
|
+
if ($after.outcome -ne "connected" -or [int]$after.statusCode -ne 200) {
|
|
247
|
+
Fail "the connector still could not reach the API after the root was trusted (outcome=$($after.outcome) class=$($after.failureClass))"
|
|
248
|
+
}
|
|
249
|
+
if ([int]$after.anchorCount -le [int]$before.anchorCount) {
|
|
250
|
+
Fail "the anchor count did not grow after the import -- the reader is not seeing LocalMachine\Root"
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
# ---------------------------------------------------------------- CASE C
|
|
254
|
+
Write-Host ""
|
|
255
|
+
Write-Host "== CASE C: a cert from a DIFFERENT root is still REFUSED =="
|
|
256
|
+
$foreign = Invoke-Probe -Pfx $otherPfx
|
|
257
|
+
Write-Host (" outcome: {0} {1} {2}" -f $foreign.outcome, $foreign.code, $foreign.failureClass)
|
|
258
|
+
if ($foreign.outcome -ne "refused") {
|
|
259
|
+
Fail "a certificate that chains to NO trusted root was accepted -- verification has been weakened, which is worse than the bug this fixes"
|
|
260
|
+
}
|
|
261
|
+
if ($foreign.failureClass -ne "tls_untrusted_root") {
|
|
262
|
+
Fail "expected failureClass tls_untrusted_root for the foreign root, got '$($foreign.failureClass)'"
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
# ---------------------------------------------------------------- CASE D
|
|
266
|
+
Write-Host ""
|
|
267
|
+
Write-Host "== CASE D: the store read survives a machine-scope AllSigned GPO =="
|
|
268
|
+
# Set-ExecutionPolicy -Scope MachinePolicy is REFUSED by Windows on purpose
|
|
269
|
+
# ("Execution policies at the MachinePolicy or UserPolicy scopes must be set
|
|
270
|
+
# through Group Policy"), so the cmdlet cannot stage this arm at all. A real
|
|
271
|
+
# GPO does not call the cmdlet either -- it writes these registry values, and
|
|
272
|
+
# the policy scope is just their projection. Writing them directly IS the GPO,
|
|
273
|
+
# not a workaround for one.
|
|
274
|
+
#
|
|
275
|
+
# Only the Windows PowerShell 5.1 key is written, never the PowerShellCore
|
|
276
|
+
# one. 5.1 is the interpreter the reader shells out to (`powershell -Command`),
|
|
277
|
+
# so it is the one this arm is about, and leaving pwsh 7's policy alone means a
|
|
278
|
+
# cleanup that fails to run cannot take the rest of the job's pwsh steps down
|
|
279
|
+
# with it -- the failure mode the step's own post-check exists to catch.
|
|
280
|
+
$polKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell"
|
|
281
|
+
$polKeyExisted = Test-Path $polKey
|
|
282
|
+
if ($polKeyExisted) {
|
|
283
|
+
$priorEnable = (Get-ItemProperty -Path $polKey -Name EnableScripts -ErrorAction SilentlyContinue).EnableScripts
|
|
284
|
+
$priorPolicy = (Get-ItemProperty -Path $polKey -Name ExecutionPolicy -ErrorAction SilentlyContinue).ExecutionPolicy
|
|
285
|
+
}
|
|
286
|
+
New-Item -Path $polKey -Force | Out-Null
|
|
287
|
+
New-ItemProperty -Path $polKey -Name "EnableScripts" -Value 1 -PropertyType DWord -Force | Out-Null
|
|
288
|
+
New-ItemProperty -Path $polKey -Name "ExecutionPolicy" -Value "AllSigned" -PropertyType String -Force | Out-Null
|
|
289
|
+
$policyChanged = $true
|
|
290
|
+
# Read it back through the interpreter it governs, not through pwsh 7, which
|
|
291
|
+
# reads a different key and would report Undefined no matter what we staged.
|
|
292
|
+
$effective = (& powershell.exe -NoProfile -Command "Get-ExecutionPolicy -Scope MachinePolicy" | Select-Object -Last 1).ToString().Trim()
|
|
293
|
+
Write-Host (" MachinePolicy (Windows PowerShell 5.1) is now: {0}" -f $effective)
|
|
294
|
+
if ("$effective" -ne "AllSigned") {
|
|
295
|
+
Fail "could not stage MachinePolicy=AllSigned, so this arm would be vacuous"
|
|
296
|
+
}
|
|
297
|
+
$underPolicy = Invoke-Probe -Pfx $leafPfx
|
|
298
|
+
Write-Host (" anchors read under AllSigned: {0}" -f $underPolicy.anchorCount)
|
|
299
|
+
Write-Host (" outcome: {0}" -f $underPolicy.outcome)
|
|
300
|
+
if ([int]$underPolicy.anchorCount -lt [int]$after.anchorCount) {
|
|
301
|
+
Fail "the trust-store read returned fewer certificates under AllSigned ($($underPolicy.anchorCount) vs $($after.anchorCount)) -- execution policy is blocking it"
|
|
302
|
+
}
|
|
303
|
+
if ($underPolicy.outcome -ne "connected") {
|
|
304
|
+
Fail "the connector could not reach the API under AllSigned (outcome=$($underPolicy.outcome))"
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
Write-Host ""
|
|
308
|
+
Write-Host "PASS: refused before the import, connected after it, still refuses a foreign root, and reads the store under AllSigned."
|
|
309
|
+
exit 0
|
|
310
|
+
} catch {
|
|
311
|
+
Write-Host "FAIL: $_"
|
|
312
|
+
exit 1
|
|
313
|
+
} finally {
|
|
314
|
+
if ($policyChanged) {
|
|
315
|
+
# Restore exactly what was there, rather than deleting: on a developer's
|
|
316
|
+
# domain-joined machine this key may be REAL policy, and clearing it would
|
|
317
|
+
# silently relax that machine's execution policy.
|
|
318
|
+
$polKey = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell"
|
|
319
|
+
if ($polKeyExisted) {
|
|
320
|
+
if ($null -ne $priorEnable) {
|
|
321
|
+
New-ItemProperty -Path $polKey -Name "EnableScripts" -Value $priorEnable -PropertyType DWord -Force -ErrorAction SilentlyContinue | Out-Null
|
|
322
|
+
} else {
|
|
323
|
+
Remove-ItemProperty -Path $polKey -Name "EnableScripts" -Force -ErrorAction SilentlyContinue
|
|
324
|
+
}
|
|
325
|
+
if ($null -ne $priorPolicy) {
|
|
326
|
+
New-ItemProperty -Path $polKey -Name "ExecutionPolicy" -Value $priorPolicy -PropertyType String -Force -ErrorAction SilentlyContinue | Out-Null
|
|
327
|
+
} else {
|
|
328
|
+
Remove-ItemProperty -Path $polKey -Name "ExecutionPolicy" -Force -ErrorAction SilentlyContinue
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
Remove-Item -Path $polKey -Recurse -Force -ErrorAction SilentlyContinue
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
if ($trustedThumbprint) {
|
|
335
|
+
Remove-Item -LiteralPath "Cert:\LocalMachine\Root\$trustedThumbprint" -Force -ErrorAction SilentlyContinue
|
|
336
|
+
}
|
|
337
|
+
foreach ($thumb in $minted) {
|
|
338
|
+
Remove-Item -LiteralPath "Cert:\CurrentUser\My\$thumb" -Force -ErrorAction SilentlyContinue
|
|
339
|
+
}
|
|
340
|
+
if (Test-Path -LiteralPath $work) { Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue }
|
|
341
|
+
}
|
|
@@ -288,6 +288,45 @@ if ((Test-ServeHealthy) -and ($installedLitertLmVersion -ne $LitertLmVersion)) {
|
|
|
288
288
|
Log "serve is healthy but litert-lm is $(if ($installedLitertLmVersion) { $installedLitertLmVersion } else { 'unknown' }) not pinned $LitertLmVersion; reinstalling and restarting the serve"
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
+
# --- Enterprise TLS + proxy for uv -------------------------------------------
|
|
292
|
+
# uv does NOT use Schannel and does NOT auto-discover a Windows proxy. It ships
|
|
293
|
+
# bundled Mozilla roots and reads proxy settings only from environment
|
|
294
|
+
# variables. Behind a TLS-inspecting proxy that made this the step that failed:
|
|
295
|
+
# PowerShell fetched the uv installer fine over Schannel, then `uv tool install`
|
|
296
|
+
# died on the private root, and the installer aborted with "Private local AI
|
|
297
|
+
# could not be installed" -- a message naming the wrong cause.
|
|
298
|
+
#
|
|
299
|
+
# Two env vars, both fail-safe:
|
|
300
|
+
# UV_SYSTEM_CERTS -- current name; use the platform's native certificate store
|
|
301
|
+
# UV_NATIVE_TLS -- the deprecated-but-still-read older name for the same
|
|
302
|
+
# thing, set because `uv tool install` is UNPINNED here and
|
|
303
|
+
# the version that lands is whatever is current that day
|
|
304
|
+
# An unknown environment variable is ignored, so setting both is safe across
|
|
305
|
+
# every uv version; a CLI flag would fail outright on the version that lacks it.
|
|
306
|
+
$env:UV_SYSTEM_CERTS = "1"
|
|
307
|
+
$env:UV_NATIVE_TLS = "1"
|
|
308
|
+
|
|
309
|
+
# The proxy half. WinINET/WinHTTP are invisible to uv, so hand it the resolved
|
|
310
|
+
# proxy explicitly -- but only when the operator has not already set the
|
|
311
|
+
# variables, so an explicit HTTPS_PROXY always wins.
|
|
312
|
+
function Set-UvProxyEnvironment {
|
|
313
|
+
if ($env:HTTPS_PROXY -or $env:https_proxy -or $env:ALL_PROXY) { return }
|
|
314
|
+
try {
|
|
315
|
+
$probe = [Uri]"https://api.trillboards.com"
|
|
316
|
+
$systemProxy = [System.Net.WebRequest]::GetSystemWebProxy()
|
|
317
|
+
if ($null -eq $systemProxy) { return }
|
|
318
|
+
if ($systemProxy.IsBypassed($probe)) { return }
|
|
319
|
+
$resolved = $systemProxy.GetProxy($probe)
|
|
320
|
+
if ($null -eq $resolved -or $resolved.AbsoluteUri -eq $probe.AbsoluteUri) { return }
|
|
321
|
+
$env:HTTPS_PROXY = $resolved.AbsoluteUri.TrimEnd("/")
|
|
322
|
+
$env:HTTP_PROXY = $env:HTTPS_PROXY
|
|
323
|
+
Log ("using this machine's configured proxy for local AI downloads: {0}" -f $env:HTTPS_PROXY)
|
|
324
|
+
} catch {
|
|
325
|
+
Log "WARN: could not read this machine's proxy settings: $_"
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
Set-UvProxyEnvironment
|
|
329
|
+
|
|
291
330
|
$env:Path = "$LocalBin;$env:Path"
|
|
292
331
|
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
|
|
293
332
|
Log "uv not found; installing the local package runtime (no admin required)"
|
|
@@ -321,7 +360,16 @@ if ((Test-LitertLmCli) -and ($installedLitertLmVersion -eq $LitertLmVersion)) {
|
|
|
321
360
|
$litertlmPath = if ($litertlmCmd) { $litertlmCmd.Source } else { Join-Path $LocalBin "litert-lm.exe" }
|
|
322
361
|
if (-not (Test-LitertLmCli)) {
|
|
323
362
|
Log "litert-lm remains unhealthy after repair"
|
|
324
|
-
|
|
363
|
+
# Name the cause the log can actually distinguish. This step is the one that
|
|
364
|
+
# fails first on a TLS-inspecting network -- everything before it went over
|
|
365
|
+
# Schannel and worked -- so "check the internet connection" sent operators
|
|
366
|
+
# to look at a connection that was fine.
|
|
367
|
+
$tlsHint = ""
|
|
368
|
+
if ((Test-Path -LiteralPath $LogPath) -and
|
|
369
|
+
(Select-String -LiteralPath $LogPath -Pattern "certificate|CERTIFICATE_VERIFY|self.signed|SSL" -Quiet)) {
|
|
370
|
+
$tlsHint = " This machine appears to inspect TLS traffic: ask IT to install the inspection root into the Trusted Root Certification Authorities store, then retry."
|
|
371
|
+
}
|
|
372
|
+
Fail-LocalAi ("The local AI engine could not be installed. Check the internet connection, then retry Local AI." + $tlsHint)
|
|
325
373
|
Stop-SetupLock
|
|
326
374
|
exit 1
|
|
327
375
|
}
|
|
@@ -77,7 +77,24 @@ export interface AudienceAnalyzeResponse {
|
|
|
77
77
|
rawBody: string;
|
|
78
78
|
}
|
|
79
79
|
export type CameraHealthState = 'never_started' | 'starting' | 'open' | 'failed' | 'closed';
|
|
80
|
-
export type CameraHealthFailureClass = 'rtsp_auth' | 'rtsp_unreachable' | 'rtsp_timeout' | 'nvr_busy' | 'no_frames' | 'decode_error'
|
|
80
|
+
export type CameraHealthFailureClass = 'rtsp_auth' | 'rtsp_unreachable' | 'rtsp_timeout' | 'nvr_busy' | 'no_frames' | 'decode_error'
|
|
81
|
+
/**
|
|
82
|
+
* macOS is refusing this process access to the local network, so every LAN
|
|
83
|
+
* camera is unreachable at once.
|
|
84
|
+
*
|
|
85
|
+
* Deliberately NOT `rtsp_unreachable`. At the ffmpeg layer the two are the
|
|
86
|
+
* same string — "no route to host" — but they send the operator to opposite
|
|
87
|
+
* places: `rtsp_unreachable` means go look at the recorder, this means a
|
|
88
|
+
* human has to tick a box in System Settings › Privacy & Security › Local
|
|
89
|
+
* Network. It is only ever set when `probeLocalNetworkAccess()` has
|
|
90
|
+
* affirmatively proved the denial (see `localNetworkAccess.ts`); an
|
|
91
|
+
* ambiguous probe leaves the class as `rtsp_unreachable`, because inventing
|
|
92
|
+
* a permission problem misdirects just as badly as missing one.
|
|
93
|
+
*
|
|
94
|
+
* Like every other class it clears through the ordinary `state: 'open'`
|
|
95
|
+
* report, which carries no `lastFailureClass` and so nulls the column.
|
|
96
|
+
*/
|
|
97
|
+
| 'local_network_denied';
|
|
81
98
|
export type CameraSensingState = 'idle' | 'analyzing' | 'active' | 'waiting_for_capacity' | 'unavailable';
|
|
82
99
|
export interface CameraHealthReport {
|
|
83
100
|
state: CameraHealthState;
|
|
@@ -175,6 +192,20 @@ export declare class AudienceAnalyzeClient {
|
|
|
175
192
|
/**
|
|
176
193
|
* Default transport using Node's built-in http/https. No third-party deps so it
|
|
177
194
|
* survives bundling into a single self-contained binary.
|
|
195
|
+
*
|
|
196
|
+
* This is the SHARED transport for every cloud call the connector makes —
|
|
197
|
+
* `AudienceAnalyzeClient`, `PairClient`, `SetupSessionClient`,
|
|
198
|
+
* `DiscoveryReportClient` and `SensingProfileClient` all default to it — so the
|
|
199
|
+
* enterprise trust store and the machine's proxy are wired in here once and
|
|
200
|
+
* pairing gets them for free. Under TLS inspection pairing failed exactly the
|
|
201
|
+
* same way sensing did.
|
|
202
|
+
*
|
|
203
|
+
* The two changes here, and nothing else:
|
|
204
|
+
* - an agent carrying the platform trust anchors, and a CONNECT tunnel when
|
|
205
|
+
* the machine is configured to use a proxy (`getEnterpriseAgent`);
|
|
206
|
+
* - `req.on('error')` now rejects with a `TransportFailure` that NAMES the
|
|
207
|
+
* cause instead of an OpenSSL constant. Timeouts, retries and the request
|
|
208
|
+
* shape are untouched.
|
|
178
209
|
*/
|
|
179
210
|
export declare const defaultHttpPoster: HttpPoster;
|
|
180
211
|
//# sourceMappingURL=AudienceAnalyzeClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudienceAnalyzeClient.d.ts","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AudienceAnalyzeClient.d.ts","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,7 @@ const http = __importStar(require("http"));
|
|
|
38
38
|
const https = __importStar(require("https"));
|
|
39
39
|
const url_1 = require("url");
|
|
40
40
|
const crypto_1 = require("crypto");
|
|
41
|
+
const enterpriseNetwork_1 = require("./enterpriseNetwork");
|
|
41
42
|
class AudienceAnalyzeClient {
|
|
42
43
|
constructor(options, poster) {
|
|
43
44
|
if (!options.apiBaseUrl) {
|
|
@@ -235,6 +236,20 @@ function parseAnalyzeResponse(result) {
|
|
|
235
236
|
/**
|
|
236
237
|
* Default transport using Node's built-in http/https. No third-party deps so it
|
|
237
238
|
* survives bundling into a single self-contained binary.
|
|
239
|
+
*
|
|
240
|
+
* This is the SHARED transport for every cloud call the connector makes —
|
|
241
|
+
* `AudienceAnalyzeClient`, `PairClient`, `SetupSessionClient`,
|
|
242
|
+
* `DiscoveryReportClient` and `SensingProfileClient` all default to it — so the
|
|
243
|
+
* enterprise trust store and the machine's proxy are wired in here once and
|
|
244
|
+
* pairing gets them for free. Under TLS inspection pairing failed exactly the
|
|
245
|
+
* same way sensing did.
|
|
246
|
+
*
|
|
247
|
+
* The two changes here, and nothing else:
|
|
248
|
+
* - an agent carrying the platform trust anchors, and a CONNECT tunnel when
|
|
249
|
+
* the machine is configured to use a proxy (`getEnterpriseAgent`);
|
|
250
|
+
* - `req.on('error')` now rejects with a `TransportFailure` that NAMES the
|
|
251
|
+
* cause instead of an OpenSSL constant. Timeouts, retries and the request
|
|
252
|
+
* shape are untouched.
|
|
238
253
|
*/
|
|
239
254
|
const defaultHttpPoster = (url, options, body) => {
|
|
240
255
|
return new Promise((resolve, reject) => {
|
|
@@ -246,16 +261,24 @@ const defaultHttpPoster = (url, options, body) => {
|
|
|
246
261
|
reject(new Error(`Invalid audience-analyze URL: ${err.message}`));
|
|
247
262
|
return;
|
|
248
263
|
}
|
|
249
|
-
const
|
|
264
|
+
const isHttps = parsed.protocol === 'https:';
|
|
265
|
+
const mod = isHttps ? https : http;
|
|
250
266
|
const bodyBuffer = Buffer.from(body, 'utf-8');
|
|
251
|
-
const
|
|
267
|
+
const baseOptions = {
|
|
252
268
|
method: options.method,
|
|
253
269
|
headers: {
|
|
254
270
|
...options.headers,
|
|
255
271
|
'Content-Length': String(bodyBuffer.length),
|
|
256
272
|
},
|
|
257
273
|
timeout: options.timeoutMs,
|
|
258
|
-
|
|
274
|
+
// https tunnels through the agent (CONNECT); plain http is rewritten to
|
|
275
|
+
// absolute-form below, which is how a forward proxy expects it.
|
|
276
|
+
...(isHttps ? { agent: (0, enterpriseNetwork_1.getEnterpriseAgent)() } : {}),
|
|
277
|
+
};
|
|
278
|
+
const proxied = isHttps
|
|
279
|
+
? { options: baseOptions, proxyUrl: null }
|
|
280
|
+
: (0, enterpriseNetwork_1.applyHttpProxy)(url, baseOptions);
|
|
281
|
+
const onResponse = (res) => {
|
|
259
282
|
const chunks = [];
|
|
260
283
|
res.on('data', (chunk) => chunks.push(chunk));
|
|
261
284
|
res.on('end', () => {
|
|
@@ -264,8 +287,14 @@ const defaultHttpPoster = (url, options, body) => {
|
|
|
264
287
|
body: Buffer.concat(chunks).toString('utf-8'),
|
|
265
288
|
});
|
|
266
289
|
});
|
|
267
|
-
}
|
|
268
|
-
|
|
290
|
+
};
|
|
291
|
+
// With a plain-http proxy in play the target moves into `path` as an
|
|
292
|
+
// absolute URL and `host` becomes the proxy, so the URL must NOT also be
|
|
293
|
+
// passed positionally — Node would overwrite both from it.
|
|
294
|
+
const req = proxied.proxyUrl
|
|
295
|
+
? mod.request(proxied.options, onResponse)
|
|
296
|
+
: mod.request(url, baseOptions, onResponse);
|
|
297
|
+
req.on('error', (err) => reject((0, enterpriseNetwork_1.diagnoseTransportError)(err, url)));
|
|
269
298
|
req.on('timeout', () => {
|
|
270
299
|
req.destroy(new Error('audience-analyze request timed out'));
|
|
271
300
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AudienceAnalyzeClient.js","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAC7B,6CAA+B;AAC/B,6BAA0B;AAC1B,mCAAoC;
|
|
1
|
+
{"version":3,"file":"AudienceAnalyzeClient.js","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"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"}
|