ReCheck.psm1

[string[]]$unwantedDestinations = @(
    "255.255.255.254/32",
    "255.255.255.252/31",
    "255.255.255.248/30",
    "255.255.255.240/29",
    "255.255.255.224/28",
    "255.255.255.192/27",
    "255.255.255.128/26",
    "255.255.255.0/25",
    "255.255.254.0/24",
    "255.255.252.0/23",
    "255.255.248.0/22",
    "255.255.240.0/21",
    "255.255.224.0/20",
    "255.255.192.0/19",
    "255.255.128.0/18",
    "255.255.0.0/17",
    "255.254.0.0/16",
    "255.252.0.0/15",
    "255.248.0.0/14",
    "255.240.0.0/13",
    "255.224.0.0/12",
    "255.192.0.0/11",
    "255.128.0.0/10",
    "255.0.0.0/9",
    "254.0.0.0/8",
    "252.0.0.0/7",
    "248.0.0.0/6",
    "240.0.0.0/5",
    "224.0.0.0/4",
    "220.0.0.0/6",
    "218.0.0.0/7",
    "217.128.0.0/9",
    "217.64.0.0/10",
    "217.32.0.0/11",
    "217.16.0.0/12",
    "217.15.0.0/16",
    "217.14.128.0/17",
    "217.14.64.0/18",
    "217.14.60.0/22",
    "217.14.58.0/23",
    "217.14.57.128/25",
    "217.14.57.96/27",
    "217.14.57.80/28",
    "217.14.57.76/30",
    "217.14.57.74/31",
    "217.14.57.72/32",
    "217.14.57.64/29",
    "217.14.57.48/28",
    "217.14.57.44/30",
    "217.14.57.42/31",
    "217.14.57.40/32",
    "217.14.57.32/29",
    "217.14.57.16/28",
    "217.14.57.12/30",
    "217.14.57.10/31",
    "217.14.57.9/32",
    "217.14.57.0/29",
    "217.14.56.0/24",
    "217.14.52.0/22",
    "217.14.50.0/23",
    "217.14.49.128/25",
    "217.14.49.64/26",
    "217.14.49.32/27",
    "217.14.49.24/29",
    "217.14.49.22/31",
    "217.14.49.21/32",
    "217.14.49.16/30",
    "217.14.49.0/28",
    "217.14.48.0/24",
    "217.14.32.0/20",
    "217.14.0.0/19",
    "217.12.0.0/15",
    "217.8.0.0/14",
    "217.0.0.0/13",
    "216.0.0.0/8",
    "208.0.0.0/5",
    "200.0.0.0/5",
    "196.0.0.0/6",
    "194.0.0.0/7",
    "193.192.0.0/10",
    "193.176.0.0/12",
    "193.168.0.0/13",
    "193.166.0.0/15",
    "193.165.0.0/16",
    "193.164.192.0/18",
    "193.164.160.0/19",
    "193.164.152.0/21",
    "193.164.148.0/22",
    "193.164.147.0/24",
    "193.164.146.192/26",
    "193.164.146.190/31",
    "193.164.146.189/32",
    "193.164.146.184/30",
    "193.164.146.176/29",
    "193.164.146.160/28",
    "193.164.146.128/27",
    "193.164.146.0/25",
    "193.164.144.0/23",
    "193.164.128.0/20",
    "193.164.0.0/17",
    "193.160.0.0/14",
    "193.128.0.0/11",
    "193.0.0.0/9",
    "128.0.0.0/2",
    "64.0.0.0/2",
    "32.0.0.0/3",
    "16.0.0.0/4",
    "12.0.0.0/6",
    "11.0.0.0/8",
    "8.0.0.0/7",
    "0.0.0.0/5",
    "192.168.0.0/16",
    "0.0.0.1/32",
    "0.0.0.2/31",
    "0.0.0.4/30",
    "0.0.0.8/29",
    "0.0.0.16/28",
    "0.0.0.32/27",
    "0.0.0.64/26",
    "0.0.0.128/25"
    "0.0.1.0/24",
    "0.0.2.0/23",
    "0.0.4.0/22",
    "0.0.8.0/21",
    "0.0.16.0/20",
    "0.0.32.0/19",
    "0.0.64.0/18",
    "0.0.128.0/17",
    "0.1.0.0/16",
    "0.2.0.0/15",
    "0.4.0.0/14",
    "0.8.0.0/13",
    "0.16.0.0/12",
    "0.32.0.0/11",
    "0.64.0.0/10",
    "0.128.0.0/9",
    "1.0.0.0/8",
    "2.0.0.0/7",
    "4.0.0.0/6",
    "64.0.0.0/3",
    "96.0.0.0/6",
    "100.0.0.0/10",
    "100.64.0.0/10",
    "100.128.0.0/9",
    "101.0.0.0/8",
    "102.0.0.0/7",
    "104.0.0.0/5",
    "112.0.0.0/4",
    "128.0.0.0/3",
    "160.0.0.0/5",
    "168.0.0.0/6"
)

##Description: Checks if the local execution context is elevated
##Input: None
##Output: Boolean. True if the local execution context is elevated.
function CheckIfAdmin {
    $CurrentIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
    $CurrentSecurityPrincipal = [System.Security.Principal.WindowsPrincipal]::new($CurrentIdentity)
    $AdminPrincipal = [System.Security.Principal.WindowsBuiltInRole]::Administrator
    return $CurrentSecurityPrincipal.IsInRole($AdminPrincipal)
}

function EnsureAdmin {
    if (!(CheckIfAdmin)) {
        Write-Error "Please run this script with Administrative privileges." -ErrorAction Stop
    }
}

function Get-BestGw {
    $recommendedRoute = Find-NetRoute -RemoteIPAddress "8.8.8.8"
    $defaultRoute = Get-NetRoute -DestinationPrefix "0.0.0.0/0"
    [string]$bestGateway = $null

    if ($null -ne $recommendedRoute) {
        $bestGateway = $recommendedRoute[1].NextHop
    } else {
        $bestGateway = $defaultRoute.NextHop
    }
    return $bestGateway
}

function Remove-UnwantedRoutes {
    # Get default gateway.
    Write-Host "Determine best or default gateway." -ForegroundColor Yellow
    $bestGw = Get-BestGw

    if ([string]::IsNullOrEmpty($bestGw)) {
        Write-Error "Couldn't find the best route to the world." -ErrorAction Stop
    } else {
        Write-Host "The best gatewate to the world is [$bestGw]" -ForegroundColor Magenta
    }

    # Reconfigure routes
    Write-Host
    Write-Host "Reconfigure routes..." -ForegroundColor Yellow

    # get consolidated list
    $routeInstances = Get-NetRoute -AddressFamily IPv4 `
                    | Where-Object { $_.NextHop -ne "0.0.0.0" } `
                    | Where-Object { $unwantedDestinations -contains $_.DestinationPrefix } `
                    | Where-Object { !$_.DestinationPrefix.StartsWith("127.")}

    # remove unwanted routes
    foreach ($route in $routeInstances) {
        $dst = $route.DestinationPrefix
        $gw = $route.NextHop
        Write-Host "Removing unwanted route [$dst via $gw]..." -ForegroundColor Gray
        Remove-NetRoute -InputObject $route -Confirm:$false
    }

    # remove unwanted LAN routes
    $localNetPrefix =  ($bestGw.Split('.') | Select-Object -First 3) -Join '.'
    $lanRouteInstances = Get-NetRoute -AddressFamily IPv4 `
                | Where-Object { $_.DestinationPrefix.StartsWith($localNetPrefix) -and $_.NextHop -ne "0.0.0.0"}

    foreach ($route in $lanRouteInstances) {
        $dst = $route.DestinationPrefix
        $gw = $route.NextHop
        Write-Host "Removing route for LAN [$dst via $gw]..." -ForegroundColor Gray
        Remove-NetRoute -InputObject $route -Confirm:$false
    }
}

function Update-Routes {
    [CmdletBinding()]
    param()

    EnsureAdmin
    # update route table
    Remove-UnwantedRoutes
    # Check google reacheable.
    Write-Host
    Write-Host "Testing connection to Internet..." -ForegroundColor Yellow
    $testResult = Test-Connection -ComputerName 8.8.8.8 -Count 2 -Quiet
    if ($testResult -eq $true) {
        Write-Host "Congrats! You are all set. Internet working." -ForegroundColor Green
    } else {
        Write-Error "Sorry. Something went wrong."
    }

    for ($i = 2; $i -gt 0; $i--) {
        Write-Host "This window will be closed in $i seconds..."
        Start-Sleep -Seconds 1
    }
}

function Update-TracConfig {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]$siteName
    )
    $tracBasePath = "C:\Program Files (x86)\CheckPoint\Endpoint Connect"
    $tracDefaultsName = "trac.defaults"
    $tracConfigName = "trac.config"

    $epwdSrv = Get-Service -Name EPWD
    $tracSrv = Get-Service -Name TracSrvWrapper

    if ($null -eq $epwdSrv -or $null -eq $tracSrv) {
        Write-Error "Can't find Trac services" -ErrorAction Stop
    }

    # Stop services and check if stopped. Can't continue if services are running.
    if ($epwdSrv.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) {
        Write-Host "Stopping [$($epwdSrv.DisplayName)] service..."
        Stop-Service $epwdSrv -ErrorAction Stop
    }
    if ($tracSrv.Status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) {
        Write-Host "Stopping [$($tracSrv.DisplayName)] service..."
        Stop-Service $tracSrv -ErrorAction Stop
    }

    # ====================
    # Change trac settings
    $tracDefaultsPath = "$tracBasePath\$tracDefaultsName"
    # backup current defaults
    Copy-Item -Path $tracDefaultsPath -Destination "$tracDefaultsPath.backup"
    # patch defaults
    $obscureRegex = '(OBSCURE_FILE[\t|\s]+INT[\t|\s]+)(?<int>[0|1])([\t|\s]+GLOBAL[\t|\s]+)(?<global>[0|1])'
    $tracDefaultsOrig = Get-Content -Path $tracDefaultsPath
    if ($tracDefaultsOrig[0] -match $obscureRegex -and ($matches.int -eq 1 -or $matches.global -eq 1)) {
        Write-Host "Updating $tracDefaultsName file."
        $tracDefaultsPatched = $tracDefaultsOrig -replace $obscureRegex, '$1 0 $2 0'
        $tracDefaultsPatched | Out-File -FilePath $tracDefaultsPath -Encoding Ascii
    }

    # start and stop service to unobscure config
    Write-Host "Restarting [$($tracSrv.DisplayName)] service..."
    Start-Service $tracSrv -ErrorAction Stop
    Stop-Service $tracSrv -ErrorAction Stop

    # ====================
    # Reconfigure trac
    Write-Host "Updating $tracConfigName file..."
    $tracConfigPath = "$tracBasePath\$tracConfigName"
    # backup current settings
    Copy-Item -Path $tracConfigPath -Destination "$tracConfigPath.backup"
    $tracConfig = Get-Item -Path $tracConfigPath
    $tracConfigXml = [xml](Get-Content $tracConfig)
    $siteNode = $tracConfigXml.SelectSingleNode("//CONFIGURATION/SITE[@name='$siteName']")

    if ($null -eq $siteNode){
        Write-Error -Message "Can't find trac site with name [$siteName]." -ErrorAction Stop
    }

    # do not route all traffic via vpn
    Write-Host "Disable routing all traffic via gateway."
    $routeGwNode = $siteNode.SelectSingleNode("FROM_GW/PARAM[@neo_route_all_traffic_through_gateway]")
    $routeGwNode.Attributes["neo_route_all_traffic_through_gateway"].Value = "false"
    # do not close connections on connect
    Write-Host "Disable closing all connections on VPN connect."
    $closeConnNode = $siteNode.SelectSingleNode("FROM_GW/PARAM[@close_TCP_connections_on_VPN_connect]")
    $closeConnNode.Attributes["close_TCP_connections_on_VPN_connect"].Value = "false"
    # show post connect script window
    Write-Host "Do not show post-connection script window."
    $showScriptNode = $siteNode.SelectSingleNode("FROM_GW/PARAM[@post_connect_script_show_window]")
    $showScriptNode.Attributes["post_connect_script_show_window"].Value = "true"
    # don't disconnect on smart card removal
    Write-Host "Disable disconnecting on smart-card removing."
    $disconnectOnRemoveNode = $siteNode.SelectSingleNode("FROM_GW/PARAM[@disconnect_on_smartcard_removal]")
    $disconnectOnRemoveNode.Attributes["disconnect_on_smartcard_removal"].Value = "false"

    # remove 192.* routes
    $lanRangeNodes = $siteNode.SelectNodes("GW_LIST/GATEWAY/IP_RANGE/Range[starts-with(@from, '192.168')]")
    foreach($lanRangeNode in $lanRangeNodes) {
        $ipRangeNode = $lanRangeNode.ParentNode
        $gwName = $ipRangeNode.ParentNode.Name
        Write-Host "Removing ip range route from gw [$gwName] [from=$($lanRangeNode.from) to=$($lanRangeNode.to)]"
        $ipRangeNode.RemoveChild($lanRangeNode) | Out-Null
    }

    # create post connect script
    $postConnectScriptDir = "$($env:LOCALAPPDATA)\ReCheck"
    if (-not (Test-Path -Path $postConnectScriptDir)) {
        New-Item -Path $postConnectScriptDir -ItemType "directory"
    }
    $postConnectScriptPath = "$postConnectScriptDir\onconnect2.cmd"
    if (-not (Test-Path -Path $postConnectScriptPath)) {
        New-Item -Path $postConnectScriptPath
    } else {
        Clear-Content -Path $postConnectScriptPath
    }
    Add-Content -Path $postConnectScriptPath `
    -Value "powershell.exe -Command `"Start-Process powershell -ArgumentList `\`"-Command ``\`" & { Import-Module ReCheck; Update-Routes } ``\`" `\`" -Verb RunAs`""

    Write-Host "Setting up post-connection script."
    $postConnectScriptNode = $siteNode.SelectSingleNode("FROM_GW/PARAM[@post_connect_script]")
    if ($null -eq $postConnectScriptNode) {
       $postConnectScriptNode = $tracConfigXml.CreateElement("PARAM")
       $siteNode.FROM_GW.AppendChild($postConnectScriptNode)
    }
    $postConnectScriptNode.SetAttribute("post_connect_script", $postConnectScriptPath)

    # save file
    Write-Host "Saving updated config file."
    $tracConfigXml.Save("$($tracConfig.FullName)")
    # clear trac backups
    Write-Host "Clearing up built-in config backups."
    Remove-Item -Path "$tracConfigPath.bak" -ErrorAction SilentlyContinue
    Remove-Item -Path "$tracConfigPath.lastgood" -ErrorAction SilentlyContinue

    # ====================
    # Start trac services
    Write-Host "Starting [$($epwdSrv.DisplayName)] service..."
    Start-Service $epwdSrv -ErrorAction Continue
    Write-Host "Starting [$($tracSrv.DisplayName)] service..."
    Start-Service $tracSrv -ErrorAction Continue
}