Monitor: drop cert pre-gate + force Report IP after AESFMA connect

Two fixes for the AESFMA swap path:

1. Removed the X509Chain root-thumbprint pre-check. Bay user reported
   "claims connect not yet operational, but i was able to manually
   connect" - meaning the cert IS in LocalMachine\My but
   $chain.Build() returns a partial chain (probably missing an
   intermediate in the local trust store), so our root-thumbprint
   match returned false and Monitor never even tried the netsh
   connect. Letting netsh attempt directly - it's the source of
   truth on whether EAP-TLS auth succeeds. Rate-limited to 30s
   between attempts to avoid log spam when AESFMA truly isn't
   reachable.

2. Bumped post-connect verify sleep 8s -> 15s. WLAN auth + DHCP can
   take longer than 8s on first attempt.

3. New: once Test-AESFMAConnected returns true and INTERNETACCESS
   is deleted, force-run GE_ReportIP_3_v1.EXE /ForceUpdate=True /S
   so the webhook gets the corp-AESFMA IP immediately instead of
   waiting for the next DHCP-change trigger (which may never fire
   if AESFMA was the bay's first 10.x lease). $script:cache.
   ReportIpForced caches the one-shot fire.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-05-15 08:25:37 -04:00
parent 3385bc87aa
commit 76a3ba513c

View File

@@ -189,6 +189,7 @@ $script:cache = @{
SfldPolicyPushed = $false
CredsReadyPushed = $false
LockdownCompletePushed = $false
ReportIpForced = $false
InternetAccessDeleted = $false
}
@@ -348,49 +349,56 @@ function Get-Phase1 {
return $false
}
# Fast path: AESFMA already connected (cert + WLAN service handled
# it without our help, or a prior tick connected). Delete
# INTERNETACCESS if still present, flip cache flag, stop trying.
if (Test-AESFMAConnected) {
Write-Host "AESFMA already connected - cleaning up INTERNETACCESS..."
# Already connected (either via WLAN auto-join, prior tick's
# attempt, or an operator manual connect). Clean up
# INTERNETACCESS, force a Report IP push from the AESFMA-attached
# corp address, and stop trying.
Write-Host "AESFMA connected - cleaning up INTERNETACCESS..."
$null = netsh wlan delete profile name="INTERNETACCESS" 2>&1 | Out-String
$script:cache.InternetAccessDeleted = $true
} else {
# Slow path: walk LocalMachine\My for any cert chained to the
# GE Aerospace FreeRADIUS root (thumbprint from AESFMA.xml).
$aesfmaRootThumb = '27F0C9A22B28CE7687B115A29E31BF4B3ABB180F'
$hasAesfmaCert = $false
try {
foreach ($cert in (Get-ChildItem 'Cert:\LocalMachine\My' -ErrorAction SilentlyContinue)) {
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.ChainPolicy.RevocationMode = 'NoCheck'
$null = $chain.Build($cert)
foreach ($el in $chain.ChainElements) {
if ($el.Certificate.Thumbprint -eq $aesfmaRootThumb) {
$hasAesfmaCert = $true; break
}
# Force the GE Report IP exe to post the new (AESFMA corp) IP
# to the Tines webhook immediately - default trigger is on
# DHCP event + slow interval, this skips the wait.
if (-not $script:cache.ReportIpForced) {
$rip = 'C:\ProgramData\ReportIP\GE_ReportIP_3_v1.EXE'
if (Test-Path $rip) {
try {
Start-Process -FilePath $rip -ArgumentList '/ForceUpdate=True','/S' -WindowStyle Hidden -ErrorAction Stop
Write-Host "Forced GE Report IP push (corp-AESFMA IP)."
$script:cache.ReportIpForced = $true
} catch {
Write-Warning "Force GE Report IP failed: $_"
}
if ($hasAesfmaCert) { break }
}
} catch {}
if ($hasAesfmaCert) {
}
} else {
# Not connected. Try without pre-gating on a cert chain check -
# the X509Chain.Build can return a partial chain (e.g. missing
# intermediate) which made the strict root-thumbprint match
# false even when EAP-TLS would actually succeed. Let netsh
# itself be the source of truth via the connect attempt.
# Rate-limit: at most one attempt every 30 seconds to avoid
# spam when AESFMA isn't actually reachable.
$now = Get-Date
if (-not $script:cache.AesfmaNextAttempt -or $now -ge $script:cache.AesfmaNextAttempt) {
try {
Write-Host "AESFMA cert detected (chains to GE RADIUS root) - connecting AESFMA..."
Write-Host "Attempting AESFMA connect (INTERNETACCESS stays up as fallback)..."
$null = netsh wlan connect name="AESFMA" ssid="AESFMA" 2>&1 | Out-String
Start-Sleep -Seconds 8
Start-Sleep -Seconds 15
if (Test-AESFMAConnected) {
Write-Host "AESFMA connected. Deleting INTERNETACCESS profile..."
$null = netsh wlan delete profile name="INTERNETACCESS" 2>&1 | Out-String
$script:cache.InternetAccessDeleted = $true
} else {
Write-Host "AESFMA cert present but connect not yet operational - retry next tick."
Write-Host "AESFMA connect not yet operational - will retry in 30s."
$script:cache.AesfmaNextAttempt = $now.AddSeconds(30)
}
} catch {
Write-Warning "AESFMA connect/swap attempt failed: $_"
$script:cache.AesfmaNextAttempt = $now.AddSeconds(30)
}
}
# else: cert not delivered yet. INTERNETACCESS stays. Retry next tick.
}
}
# idx=7 push fires AS SOON AS DeviceId is captured. We want the QR