Private/Provider.ps1
|
<# .SYNOPSIS Discovers whether the paid capabilities are present, and dispatches to them. .DESCRIPTION This file is not a licence check. There is nothing here to disable, because the three paid capabilities -- executing a containment plan, delivering a trip to a SOAR endpoint, and keeping state apart per tenant profile -- are not in this repository at all. They live in a separate module, EntraTripwirePro, and holding that module is the entitlement. The distinction matters to anyone reading this code with a view to removing a gate. There is no gate: these functions ask whether a capability is installed, and when it is not they say which one is missing and what the free module does instead. Deleting the question does not reveal working code underneath. What stays on this side of the line, deliberately: * Every verdict. Detection, scoring, suppression and the containment plan are computed here, so no paid code can change what this module reports. * The write allowlist. The paid module issues its writes through the gateway in this repository, injected as a script block, so it cannot make a call this module does not permit. * The confirmation prompt and the audit log. #> $script:TripwireProviderModule = 'EntraTripwirePro' <# .SYNOPSIS The paid module's state, resolved once per session. #> function Get-TripwireProvider { [CmdletBinding()] [OutputType([pscustomobject])] param([switch] $Refresh) if (-not $Refresh -and $null -ne $script:TripwireProvider) { return $script:TripwireProvider } $absent = { param($reason) [pscustomobject]@{ Available = $false; Name = $script:TripwireProviderModule; Version = $null; Capabilities = @(); Reason = $reason } } $available = Get-Module -ListAvailable -Name $script:TripwireProviderModule -ErrorAction SilentlyContinue if (-not $available) { $script:TripwireProvider = & $absent "$script:TripwireProviderModule is not installed. The free module does everything that produces a verdict; see docs/PRO.md for what the paid module adds and how to get it." return $script:TripwireProvider } try { Import-Module -Name $script:TripwireProviderModule -ErrorAction Stop } catch { $script:TripwireProvider = & $absent "$script:TripwireProviderModule is installed but did not load: $($_.Exception.Message)" return $script:TripwireProvider } # The contract is one command. A module that does not export it is not a provider this # version knows how to talk to, and saying so beats calling into it and failing later. if (-not (Get-Command -Name 'Get-EntraTripwireProCapability' -Module $script:TripwireProviderModule -ErrorAction SilentlyContinue)) { $script:TripwireProvider = & $absent "$script:TripwireProviderModule loaded but does not export Get-EntraTripwireProCapability, so its capabilities cannot be established. Update it." return $script:TripwireProvider } try { $caps = @(Get-EntraTripwireProCapability) } catch { $script:TripwireProvider = & $absent "$script:TripwireProviderModule could not report its capabilities: $($_.Exception.Message)" return $script:TripwireProvider } $loaded = Get-Module -Name $script:TripwireProviderModule | Select-Object -First 1 $script:TripwireProvider = [pscustomobject]@{ Available = ($caps.Count -gt 0) Name = $script:TripwireProviderModule Version = if ($loaded) { $loaded.Version } else { $null } Capabilities = $caps Reason = if ($caps.Count -gt 0) { $null } else { "$script:TripwireProviderModule is installed but reports no capabilities. Run Get-EntraTripwireProCapability -Verbose for the reason it gives." } } return $script:TripwireProvider } <# .SYNOPSIS Is a named paid capability installed? .DESCRIPTION Never throws. This is consulted while deciding whether containment may act, and an exception there would surface during an incident as a crash rather than as an answer. #> function Test-TripwireProFeature { [CmdletBinding()] [OutputType([bool])] param([Parameter(Mandatory)] [ValidateSet('containment', 'soar', 'multitenant')] [string] $Feature) try { return (@((Get-TripwireProvider).Capabilities) -contains $Feature) } catch { return $false } } <# .SYNOPSIS Call a paid capability, or fail with the reason it is unavailable. #> function Invoke-TripwireProCapability { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateSet('Containment', 'Webhook', 'Profile', 'Activate')] [string] $Capability, [Parameter(Mandatory)] [hashtable] $Arguments ) $command = switch ($Capability) { 'Containment' { 'Invoke-EntraTripwireProContainment' } 'Webhook' { 'Send-EntraTripwireProWebhook' } 'Profile' { 'Resolve-EntraTripwireProProfile' } 'Activate' { 'Enable-EntraTripwireProLicense' } } $provider = Get-TripwireProvider # Activate is the exception: a provider that reports no capabilities because its # licence lapsed is exactly the one that needs a new key, so refusing to reach it # would make the problem unfixable from here. if (-not $provider.Available -and $Capability -ne 'Activate') { throw $provider.Reason } if ($Capability -eq 'Activate' -and -not (Get-Module -ListAvailable -Name $script:TripwireProviderModule -ErrorAction SilentlyContinue)) { throw $provider.Reason } $resolved = Get-Command -Name $command -Module $script:TripwireProviderModule -ErrorAction SilentlyContinue if (-not $resolved) { throw "$($provider.Name) $($provider.Version) does not export $command, so the $Capability capability cannot be used. Update it." } return (& $resolved @Arguments) } |