Check-BcContainerHelperPermissions.ps1

<#
 .Synopsis
  Checks Permissions for BcContainerHelper to run
 .Description
  When running BcContainerHelper as administrator, you have access to everything.
  When running BcContainerHelper as a user, that user needs:
  - Full control to C:\ProgramData\BcContainerHelper (in order to create and remove containers)
  - Modify permissions to C:\Windows\System32\drivers\etc\hosts (if you use -updatehosts)
  - Full control to docker engine pipe (in order to run docker commands)
  This script checks these permissions and allows you to fix the permissions by specifying -fix
 .Parameter fix
  Specify fix in order for this script to attempt to fix permissions
 .Parameter silent
  Specify -silent to stay silent on successfull permission checks
 .Parameter ignoreHosts
  Specify -ignoreHosts to ignore checking the permissions for the hosts file
 .Example
  Check-BcContainerHelperPermissions -fix
 .Example
  Check-BcContainerHelperPermissions -fix -ignoreHosts
 .Example
  Check-BcContainerHelperPermissions -silent
#>

function Check-BcContainerHelperPermissions {
    Param (
        [switch] $Fix,
        [switch] $Silent,
        [switch] $IgnoreHosts
    )

    if (!$isAdministrator -or $Fix) {

        $startProcessParams = @{
            "Verb" = "RunAs"
            "Wait" = $true
            "WindowStyle" = "Hidden"
            "PassThru" = $true
        }
        if ($isPsCore) {
            $startProcessParams += @{ "FilePath" = "pwsh" }
        }
        else {
            $startProcessParams += @{ "FilePath" = "powershell" }
        }
        if (!$silent) {
            if ($isAdministrator) {
                Write-Host "Running as administrator"
            } else {
                Write-Host "Running as $myUsername"
            }
        }

        # Check access to C:\ProgramData\BcContainerHelper
        if (!$silent) {
            Write-Host "Checking permissions to $($bcContainerHelperConfig.hostHelperFolder)"
        }
        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($myUsername,'FullControl', 3, 'InheritOnly', 'Allow')
        $acl = Get-Acl -Path $bcContainerHelperConfig.hostHelperFolder
        $access = $acl.Access | Where-Object { $_.IdentityReference -eq $rule.IdentityReference -and $_.FileSystemRights -eq $rule.FileSystemRights -and $_.AccessControlType -eq $rule.AccessControlType -and $_.InheritanceFlags -eq $rule.InheritanceFlags }
        if ($access) {
            if (!$silent) {
                Write-Host -ForegroundColor Green "$myUsername has the right permissions to $($bcContainerHelperConfig.hostHelperFolder)"
            }
        } else {
            Write-Host -ForegroundColor Red "$myUsername does NOT have Full Control to $($bcContainerHelperConfig.hostHelperFolder) and all subfolders"
            if (!$Fix) {
                Write-Host -ForegroundColor Red "You need to run as administrator or you can run Check-BcContainerHelperPermissions -Fix to fix permissions"
            } else {
                Write-Host -ForegroundColor Yellow "Trying to add permissions"
                $scriptblock = {
                    Param($myUsername, $hostHelperFolder)
                    try {
                        $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($myUsername,'FullControl', 3, 'InheritOnly', 'Allow')
                        $acl = Get-Acl -Path $hostHelperFolder
                        $acl.AddAccessRule($rule)
                        Set-Acl -Path $hostHelperFolder -AclObject $acl
                        EXIT 0
                    } catch {
                        EXIT 1
                    }
                }
                $exitCode = (Start-Process @startProcessParams -ArgumentList "-command & {$scriptblock} -myUsername '$myUsername' -hostHelperFolder '$($bcContainerHelperConfig.hostHelperFolder)'").ExitCode
                if ($exitcode -eq 0) {
                    Write-Host -ForegroundColor Green "Permissions successfully added"
                } else {
                    Write-Host -ForegroundColor Red "Error adding permissions"
                }
            }
        }
    
        if (!$IgnoreHosts) {
            # check access to c:\windows\system32\drivers\etc\hosts
            $hostsFile = Join-Path $env:SystemRoot "System32\drivers\etc\hosts"
            if (!$silent) {
                Write-Host "Checking permissions to $hostsFile"
            }
            $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($myUsername,'Modify', 'Allow')
            $acl = Get-Acl -Path $hostsFile
            $access = $acl.Access | Where-Object { $_.IdentityReference -eq $rule.IdentityReference -and $_.FileSystemRights -eq $rule.FileSystemRights -and $_.AccessControlType -eq $rule.AccessControlType }
            if ($access) {
                if (!$silent) {
                    Write-Host -ForegroundColor Green "$myUsername has the right permissions to $hostsFile"
                }
            } else {
                Write-Host -ForegroundColor Red "$myUsername does NOT have modify permissions to $hostsFile"
                if (!$Fix) {
                    Write-Host -ForegroundColor Red "You need to run as administrator or you can run Check-BcContainerHelperPermissions -Fix to fix permissions"
                } else {
                    Write-Host -ForegroundColor Yellow "Trying to add permissions"
                    $scriptblock = {
                        Param($myUsername, $hostsFile)
                        try {
                            $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($myUsername,'Modify', 'Allow')
                            $acl = Get-Acl -Path $hostsFile
                            $acl.AddAccessRule($rule)
                            Set-Acl -Path $hostsFile -AclObject $acl
                            EXIT 0
                        } catch {
                            EXIT 1
                        }
                    }
                    $exitcode = (Start-Process @startProcessParams -ArgumentList "-command & {$scriptblock} -myUsername '$myUsername' -hostsFile '$hostsFile'").ExitCode
                    if ($exitcode -eq 0) {
                        Write-Host -ForegroundColor Green "Permissions successfully added"
                    } else {
                        Write-Host -ForegroundColor Red "Error adding permissions"
                    }
                }
            }
        }

        # Check Access to Docker Deamon Socket
        # Thanks to Tobias Fenster, Axians Infoma for this blog post:
        # https://www.axians-infoma.com/techblog/allow-access-to-the-docker-engine-without-admin-rights-on-windows/
        # Pointing me in the right directions wrt. running docker commands without admin rights
        if (!$silent) {
            Write-Host "Checking permissions to docker commands"
        }
        $npipe = ""
        $dockerOk = $true
        $pre = $errorActionPreference
        $errorActionPreference = 'Continue'
        try{
            $tempFile = [System.IO.Path]::GetTempFileName()
            $ps = docker ps 2> $tempFile
            if ($LASTEXITCODE -ne 0) {
                $dockerOk = $false
                $err = [System.IO.File]::ReadAllText($tempFile)
                Write-Host "ERROR: $err"
                Remove-Item -Path $tempFile -ErrorAction Ignore
                $npipeStart = $err.IndexOf('\\.\pipe')
                if ($npipeStart -lt 0) {
                    $npipeStart = $err.IndexOf('//./pipe')
                }
                $npipe = $err.Substring($npipeStart)
                $npipeEnd = $npipe.IndexOf(':')
                $npipe = $npipe.SubString(0, $npipeEnd)
                Write-Host "npipe: $npipe"
            }
        } catch {
            $dockerOk = $false
        }
        $errorActionPreference = $pre

        if ($dockerOk) {
            if (!$silent) {
                Write-Host -ForegroundColor Green "$myUsername has the right permissions to run docker commands"
            }
        } else {
            Write-Host -ForegroundColor Red "$myUsername does NOT have permissions to run docker commands"
            if (!$Fix) {
                Write-Host -ForegroundColor Red "You need to run as administrator or you can run Check-BcContainerHelperPermissions -Fix to fix permissions"
            } else {
                if ($npipe -eq "") {
                    Write-Host -ForegroundColor Red "Unable to determine docker deamon socket. Are you sure Docker is running and reachable?"
                } else {
                    Write-Host -ForegroundColor Yellow "Trying to add permissions"
                    $scriptblock = {
                        Param($myUsername, $npipe)
                        try {
                            $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($myUsername,'FullControl', 'Allow')
                            $acl = Get-Acl -Path $npipe
                            $acl.AddAccessRule($rule)
                            Set-Acl -Path $npipe -AclObject $acl
                            exit 0
                        } catch {
                            exit 1
                        }
                    }
            
                    $exitcode = (Start-Process @startProcessParams -ArgumentList "-command & {$scriptblock} -myUsername '$myUsername' -npipe '$npipe'").ExitCode
                    if ($exitcode -eq 0) {
                        Write-Host -ForegroundColor Green "Permissions successfully added"
                    } else {
                        Write-Host -ForegroundColor Red "Error adding permissions"
                    }
                }
            }
        }
    }
}
Set-Alias -Name Check-NavContainerHelperPermissions -Value Check-BcContainerHelperPermissions
Export-ModuleMember -Function Check-BcContainerHelperPermissions -Alias Check-NavContainerHelperPermissions


# SIG # Begin signature block
# MIImZgYJKoZIhvcNAQcCoIImVzCCJlMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC10R+pve6HLfeF
# +2KMDIhuyYKbiLaKW6J5J9LjCA+Yn6CCH34wggWNMIIEdaADAgECAhAOmxiO+dAt
# 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV
# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa
# Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy
# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD
# ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
# ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E
# MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy
# unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF
# xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1
# 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB
# MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR
# WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6
# nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB
# YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S
# UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x
# q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB
# NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP
# TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC
# AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp
# Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv
# bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0
# aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB
# LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc
# Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov
# Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy
# oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW
# juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF
# mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z
# twGpn1eqXijiuZQwggYaMIIEAqADAgECAhBiHW0MUgGeO5B5FSCJIRwKMA0GCSqG
# SIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBSb290IFI0
# NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5NTlaMFQxCzAJBgNVBAYTAkdC
# MRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVi
# bGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAw
# ggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjIztNsfvxYB5UXeWUzCxEeAEZG
# bEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NVDgFigOMYzB2OKhdqfWGVoYW3
# haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/36F09fy1tsB8je/RV0mIk8XL/
# tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05ZwmRmTnAO5/arnY83jeNzhP06S
# hdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm+qxp4VqpB3MV/h53yl41aHU5
# pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUedyz8rNyfQJy/aOs5b4s+ac7I
# H60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz44MPZ1f9+YEQIQty/NQd/2yGg
# W+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBMdlyh2n5HirY4jKnFH/9gRvd+
# QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFDLrkpr/NZZILyhAQnAg
# NpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritUpimqF6TNDDAOBgNVHQ8BAf8E
# BAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAb
# BgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0
# dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9v
# dFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0
# LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYucDdj
# MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0B
# AQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURhw1aVcdGRP4Wh60BAscjW4HL9
# hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0ZdOaWTsyNyBBsMLHqafvIhrCym
# laS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajjcw5+w/KeFvPYfLF/ldYpmlG+
# vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNcWbWDRF/3sBp6fWXhz7DcML4i
# TAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalOhOfCipnx8CaLZeVme5yELg09
# Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJszkyeiaerlphwoKx1uHRzNyE6
# bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z76mKnzAfZxCl/3dq3dUNw4rg3
# sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5JKdGvspbOrTfOXyXvmPL6E52z
# 1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHHj95Ejza63zdrEcxWLDX6xWls
# /GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2Bev6SivBBOHY+uqiirZtg0y9
# ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/L9Uo2bC5a4CH2RwwggZZMIIE
# waADAgECAhANIM3qwHRbWKHw+Zq6JhzlMA0GCSqGSIb3DQEBDAUAMFQxCzAJBgNV
# BAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3Rp
# Z28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwHhcNMjExMDIyMDAwMDAwWhcN
# MjQxMDIxMjM1OTU5WjBdMQswCQYDVQQGEwJESzEUMBIGA1UECAwLSG92ZWRzdGFk
# ZW4xGzAZBgNVBAoMEkZyZWRkeSBLcmlzdGlhbnNlbjEbMBkGA1UEAwwSRnJlZGR5
# IEtyaXN0aWFuc2VuMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgYC5
# tlg+VRktRRkahxxaV8+DAd6vHoDpcO6w7yT24lnSoMuA6nR7kgy90Y/sHIwKE9Ww
# t/px/GAY8eBePWjJrFpG8fBtJbXadRTVd/470Hs/q9t+kh6A/0ELj7wYsKSNOyuF
# Poy4rtClOv9ZmrRpoDVnh8Epwg2DpklX2BNzykzBQxIbkpp+xVo2mhPNWDIesntc
# 4/BnSebLGw1Vkxmu2acKkIjYrne/7lsuyL9ue0vk8TGk9JBPNPbGKJvHu9szP9oG
# oH36fU1sEZ+AacXrp+onsyPf/hkkpAMHAhzQHl+5Ikvcus/cDm06twm7VywmZcas
# 2rFAV5MyE6WMEaYAolwAHiPz9WAs2GDhFtZZg1tzbRjJIIgPpR+doTIcpcDBcHnN
# dSdgWKrTkr2f339oT5bnJfo7oVzc/2HGWvb8Fom6LQAqSC11vWmznHYsCm72g+fo
# TKqW8lLDfLF0+aFvToLosrtW9l6Z+l+RQ8MtJ9EHOm2Ny8cFLzZCDZYw32BydwcL
# V5rKdy4Ica9on5xZvyMOLiFwuL4v2V4pjEgKJaGSS/IVSMEGjrM9DHT6YS4/oq9q
# 20rQUmMZZQmGmEyyKQ8t11si8VHtScN5m0Li8peoWfCU9mRFxSESwTWow8d462+o
# 9/SzmDxCACdFwzvfKx4JqDMm55cL+beunIvc0NsCAwEAAaOCAZwwggGYMB8GA1Ud
# IwQYMBaAFA8qyyCHKLjsb0iuK1SmKaoXpM0MMB0GA1UdDgQWBBTZD6uy9ZWIIqQh
# 3srYu1FlUhdM0TAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUE
# DDAKBggrBgEFBQcDAzARBglghkgBhvhCAQEEBAMCBBAwSgYDVR0gBEMwQTA1Bgwr
# BgEEAbIxAQIBAwIwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9D
# UFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGln
# by5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUF
# BwEBBG0wazBEBggrBgEFBQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0
# aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6
# Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQASEbZACurQeQN8
# WDTR+YyNpoQ29YAbbdBRhhzHkT/1ao7LE0QIOgGR4GwKRzufCAwu8pCBiMOUTDHT
# ezkh0rQrG6khxBX2nSTBL5i4LwKMR08HgZBsbECciABy15yexYWoB/D0H8WuGe63
# PhGWueR4IFPbIz+jEVxfW0Nyyr7bXTecpKd1iprm+TOmzc2E6ab95dkcXdJVx6Zy
# s++QrrOfQ+a57qEXkS/wnjjbN9hukL0zg+g8L4DHLKTodzfiQOampvV8QzbnB7Y8
# YjNcxR9s/nptnlQH3jorNFhktiBXvD62jc8pAIg6wyH6NxSMjtTsn7QhkIp2kusw
# IQwD8hN/fZ/m6gkXZhRJWFr2WRZOz+edZ62Jf25C/NYWscwfBwn2hzRZf1HgyxkX
# Al88dvvUA3kw1T6uo8aAB9IcL6Owiy7q4T+RLRF7oqx0vcw0193Yhq/gPOaUFlqz
# ExP6TQ5TR9XWVPQk+a1B1ATKMLi1JShO6KWTmNkFkgkgpkW69BEwggauMIIElqAD
# AgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYT
# AlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2Vy
# dC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAz
# MjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQK
# Ew5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBS
# U0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDM
# g/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOx
# s+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09ns
# ad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtA
# rF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149z
# k6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6
# OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qh
# HGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1
# KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX
# 6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0
# sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQID
# AQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2F
# L3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08w
# DgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEB
# BGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsG
# AQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz
# dGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdp
# Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgG
# BmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+Y
# qUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjY
# C+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0
# FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6
# WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGj
# VoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzp
# SwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwd
# eDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o
# 08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n
# +2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y
# 3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIO
# K+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGvDCCBKSgAwIBAgIQC65mvFq6f5WH
# xvnpBOMzBDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMO
# RGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNB
# NDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTI0MDkyNjAwMDAwMFoXDTM1
# MTEyNTIzNTk1OVowQjELMAkGA1UEBhMCVVMxETAPBgNVBAoTCERpZ2lDZXJ0MSAw
# HgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyNDCCAiIwDQYJKoZIhvcNAQEB
# BQADggIPADCCAgoCggIBAL5qc5/2lSGrljC6W23mWaO16P2RHxjEiDtqmeOlwf0K
# MCBDEr4IxHRGd7+L660x5XltSVhhK64zi9CeC9B6lUdXM0s71EOcRe8+CEJp+3R2
# O8oo76EO7o5tLuslxdr9Qq82aKcpA9O//X6QE+AcaU/byaCagLD/GLoUb35SfWHh
# 43rOH3bpLEx7pZ7avVnpUVmPvkxT8c2a2yC0WMp8hMu60tZR0ChaV76Nhnj37DEY
# TX9ReNZ8hIOYe4jl7/r419CvEYVIrH6sN00yx49boUuumF9i2T8UuKGn9966fR5X
# 6kgXj3o5WHhHVO+NBikDO0mlUh902wS/Eeh8F/UFaRp1z5SnROHwSJ+QQRZ1fisD
# 8UTVDSupWJNstVkiqLq+ISTdEjJKGjVfIcsgA4l9cbk8Smlzddh4EfvFrpVNnes4
# c16Jidj5XiPVdsn5n10jxmGpxoMc6iPkoaDhi6JjHd5ibfdp5uzIXp4P0wXkgNs+
# CO/CacBqU0R4k+8h6gYldp4FCMgrXdKWfM4N0u25OEAuEa3JyidxW48jwBqIJqIm
# d93NRxvd1aepSeNeREXAu2xUDEW8aqzFQDYmr9ZONuc2MhTMizchNULpUEoA6Vva
# 7b1XCB+1rxvbKmLqfY/M/SdV6mwWTyeVy5Z/JkvMFpnQy5wR14GJcv6dQ4aEKOX5
# AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNV
# HSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgB
# hv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYE
# FJ9XLAN3DigVkGalY17uT5IfdqBbMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9j
# cmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZU
# aW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzAB
# hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9j
# YWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEy
# NTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAD2tHh92mVvj
# OIQSR9lDkfYR25tOCB3RKE/P09x7gUsmXqt40ouRl3lj+8QioVYq3igpwrPvBmZd
# rlWBb0HvqT00nFSXgmUrDKNSQqGTdpjHsPy+LaalTW0qVjvUBhcHzBMutB6Hzele
# dbDCzFzUy34VarPnvIWrqVogK0qM8gJhh/+qDEAIdO/KkYesLyTVOoJ4eTq7gj9U
# FAL1UruJKlTnCVaM2UeUUW/8z3fvjxhN6hdT98Vr2FYlCS7Mbb4Hv5swO+aAXxWU
# m3WpByXtgVQxiBlTVYzqfLDbe9PpBKDBfk+rabTFDZXoUke7zPgtd7/fvWTlCs30
# VAGEsshJmLbJ6ZbQ/xll/HjO9JbNVekBv2Tgem+mLptR7yIrpaidRJXrI+UzB6vA
# lk/8a1u7cIqV0yef4uaZFORNekUgQHTqddmsPCEIYQP7xGxZBIhdmm4bhYsVA6G2
# WgNFYagLDBzpmk9104WQzYuVNsxyoVLObhx3RugaEGru+SojW4dHPoWrUhftNpFC
# 5H7QEY7MhKRyrBe7ucykW7eaCuWBsBb4HOKRFVDcrZgdwaSIqMDiCLg4D+TPVgKx
# 2EgEdeoHNHT9l3ZDBD+XgbF+23/zBjeCtxz+dL/9NWR6P2eZRi7zcEO1xwcdcqJs
# yz/JceENc2Sg8h3KeFUCS7tpFk7CrDqkMYIGPjCCBjoCAQEwaDBUMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2AhANIM3qwHRbWKHw+Zq6JhzlMA0G
# CWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZI
# hvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcC
# ARUwLwYJKoZIhvcNAQkEMSIEIOxLEnhh7/CI90nIrfY//U6wcHae980K3EgW8C+i
# HPMSMA0GCSqGSIb3DQEBAQUABIICAA3RAQjY/JZee55AbRVTlOMDiN5XjYrhyOvl
# cJSszHMSmr2jo+TCCSZjgsXNmd+sibUNHk3LYK5Fqh11Pew4Z+bDQoHWSyw7Kc/z
# P6My4aIIeV48sGj6M3bQ5sWsykPY6FKzZZeykgsWIgJPnzQWqsWey4fd2H9JPbAl
# cuP59JLzMlD9sG15dBLnfw0njjUEmXflDQ/JfvgYWWTCi79TSQ6yKAISGOypb3IX
# uKL9UrWHiBEZPPJhkjLaHKpRrzS1PXzpt+ZegPttrsi26zW6kV+ADJ38eC5sFWwc
# BA+diPWvr/ouk070GzhrAM5pja5hAs8RNb6Dzwp1IED8WdmHKI1JsOmjV9CHmPSs
# F0AIlAp4NS0G/3J7g06KL8bdvVtojmhWoCovZwFgXYxpVf23O+7LOrPlaEiupzkr
# L5fwwBGdPuJYgZJ8G77L9M2aixU+JgtIsxyFPfkS/cxNnbYt5ooY2vSIw/cxcVTX
# Yq/siFzsKAbYlCS43j7VaTgAPWI5n6O02If3WyF43oH4qwWsHnahPUG+Fbwzfpz8
# KS7aZ1nxFluWkNweLExSDhfK3yrejrdU6/WD9APFLKsoLCShUkCCtw2HUAQdQDbw
# Bw6X7VM+vVyuVnO2Jo0wu8Dpx+E1ym7KxmEJlI269hIRZ0Z538HOiVMehjdC4Ckf
# YHHX3ijroYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UE
# BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2Vy
# dCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQC65m
# vFq6f5WHxvnpBOMzBDANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkq
# hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI0MTAxMDA2MzcyMlowLwYJKoZIhvcN
# AQkEMSIEIGiYBkJQB64AOj/VLPLyWVAMuoAnTic2rm52i908CzdxMA0GCSqGSIb3
# DQEBAQUABIICAH90Mn0NumTrBtp5cPDK6mggz/YFoKgabWQp/P7o5aEWecV4Hnmb
# 0LvTewU11vVKgSsQhkjc44SlWvDKiHDbOs2unlivv4t0ezWS9q5kN+Sl0vNPkOSL
# 3jnftKQbPJ30RL+wZ7ZJJu/I82qM54ROBHeXU47JLqdaPguXY3wU8jjlCMhjb8HQ
# p4NbzmgfzAa02kmtPRxAw8OFfxSh5FYwspHk7z/TxFjun0IBgIzmXBWHhQSfiFdS
# jHPmBF1+UwirkqjXaNvJLiRot4NZSd7A4L0n0laIyGOWU6oNRkmkOr1PjLiE3C8t
# YmCbKTBaortRgO01hy9ig6vmPQFV9HDQfyO+plcCZpubC5wOnXqSKSQd3GPrg4We
# 0+hd590AaZf0nhvTueS+s9v09UAXkrHyryzrNM9aT2zCO2bq3Zn+NeIP/MsEN22e
# UC9DBgJlMZu4OBytdp6vG1+z6Mps/OVwuG3I0VNkSTKd3nFl4FisXs8BMgVXRcva
# GyuByRDqBxh1zRm6esLZPzXPxHkP5wqHVuwhHUmCdgxvqhdStZgZWZaRavVb5J50
# 2Zl1LArMuYjRhMUhHESe06+yA/7uj1LtT8KdL9o/Fhq/AlVGgWb25PVwwOXG6q3+
# /EX8t4bdJj9KZDZ1o7cGmCoBeESAehLP1GHfOlm/FkBVgwpze7glHKvt
# SIG # End signature block