rules/Azure.MariaDB.Rule.ps1

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

#
# Validation rules for Azure Database for MariaDB
#

#region Rules

# Synopsis: Enable Microsoft Defender for Cloud for Azure Database for MariaDB.
Rule 'Azure.MariaDB.DefenderCloud' -Ref 'AZR-000330' -Type 'Microsoft.DBforMariaDB/servers', 'Microsoft.DBforMariaDB/servers/securityAlertPolicies' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    if ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers') {
        $defenderConfigs = @(GetSubResources -ResourceType 'Microsoft.DBforMariaDB/servers/securityAlertPolicies')
        if ($defenderConfigs.Length -eq 0) {
            $Assert.Fail($LocalizedData.SubResourceNotFound, 'Microsoft.DBforMariaDB/servers/securityAlertPolicies')
        }
        foreach ($defenderConfig in $defenderConfigs) {
            $Assert.HasFieldValue($defenderConfig, 'properties.state', 'Enabled').
            PathPrefix('resources')
        }
    }
    elseif ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers/securityAlertPolicies') {
        $Assert.HasFieldValue($TargetObject, 'properties.state', 'Enabled')
    }
}

# Synopsis: Azure Database for MariaDB servers should only accept encrypted connections.
Rule 'Azure.MariaDB.UseSSL' -Ref 'AZR-000334' -Type 'Microsoft.DBforMariaDB/servers' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    $Assert.HasFieldValue($TargetObject, 'properties.sslEnforcement', 'Enabled').Reason($LocalizedData.MariaDBEncryptedConnection)
}

# Synopsis: Azure Database for MariaDB servers should reject TLS versions older than 1.2.
Rule 'Azure.MariaDB.MinTLS' -Ref 'AZR-000335' -Type 'Microsoft.DBforMariaDB/servers' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    $Assert.HasFieldValue($TargetObject, 'properties.minimalTlsVersion', 'TLS1_2')
}

# Synopsis: Azure Database for MariaDB servers should meet naming requirements.
Rule 'Azure.MariaDB.ServerName' -Ref 'AZR-000336' -Type 'Microsoft.DBforMariaDB/servers' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } -Labels @{ 'Azure.CAF' = 'naming' } {
    # https://learn.microsoft.com/nb-no/azure/azure-resource-manager/management/resource-name-rules#microsoftdbformariadb

    # Between 3 and 63 characters long
    $Assert.GreaterOrEqual($PSRule, 'TargetName', 3)
    $Assert.LessOrEqual($PSRule, 'TargetName', 63)

    # Lowercase letters, numbers, and hyphens
    # Can't start or end with a hyphen
    $Assert.Match($PSRule, 'TargetName', '^[a-z0-9]([a-z0-9-]*[a-z0-9]){2,62}$', $True)
}

# Synopsis: Azure Database for MariaDB databases should meet naming requirements.
Rule 'Azure.MariaDB.DatabaseName' -Ref 'AZR-000337' -Type 'Microsoft.DBforMariaDB/servers', 'Microsoft.DBforMariaDB/servers/databases' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } -Labels @{ 'Azure.CAF' = 'naming' } {
    # https://learn.microsoft.com/nb-no/azure/azure-resource-manager/management/resource-name-rules#microsoftdbformariadb

    $databases = @(GetMariaDBDatabaseName)
    if ($databases.Length -eq 0) {
        $Assert.Pass()
    }

    foreach ($database in $databases) {
        # Between 1 and 63 characters long
        $Assert.GreaterOrEqual($database, '.', 1)
        $Assert.LessOrEqual($database, '.', 63)

        # Alphanumerics and hyphens
        $Assert.Match($database, '.', '^[A-Za-z0-9-]{1,63}$', $True)
    }
}

# Synopsis: Azure Database for MariaDB firewall rules should meet naming requirements.
Rule 'Azure.MariaDB.FirewallRuleName' -Ref 'AZR-000338' -Type 'Microsoft.DBforMariaDB/servers', 'Microsoft.DBforMariaDB/servers/firewallRules' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } -Labels @{ 'Azure.CAF' = 'naming' } {
    $firewallRules = @(GetMariaDBFirewallRuleName)
    if ($firewallRules.Length -eq 0) {
        return $Assert.Pass()
    }

    foreach ($firewallRule in $firewallRules) {
        # Between 1 and 128 characters long
        $Assert.GreaterOrEqual($firewallRule, '.', 1)
        $Assert.LessOrEqual($firewallRule, '.', 128)

        # Alphanumerics, hyphens and underscores
        $Assert.Match($firewallRule, '.', '^[A-Za-z0-9-_]{1,128}$', $True)
    }
}

# Synopsis: Azure Database for MariaDB VNET rules should meet naming requirements.
Rule 'Azure.MariaDB.VNETRuleName' -Ref 'AZR-000339' -Type 'Microsoft.DBforMariaDB/servers', 'Microsoft.DBforMariaDB/servers/virtualNetworkRules' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Operational Excellence'; } -Labels @{ 'Azure.CAF' = 'naming' } {
    $virtualNetworkRules = @(GetMariaDBVNETRuleName)
    if ($virtualNetworkRules.Length -eq 0) {
        return $Assert.Pass()
    }

    foreach ($virtualNetworkRule in $virtualNetworkRules) {
        # Between 1 and 128 characters long
        $Assert.GreaterOrEqual($virtualNetworkRule, '.', 1)
        $Assert.LessOrEqual($virtualNetworkRule, '.', 128)

        # Alphanumerics and hyphens
        $Assert.Match($virtualNetworkRule, '.', '^[A-Za-z0-9-]{1,128}$', $True)
    }
}

# Synopsis: Determine if access from Azure services is required.
Rule 'Azure.MariaDB.AllowAzureAccess' -Ref 'AZR-000342' -Type 'Microsoft.DBforMariaDB/servers', 'Microsoft.DBforMariaDB/servers/firewallRules' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    $firewallAllowAzureServices = @(GetMariaDBFirewallRule |
        Where-Object { $_.properties.startIpAddress -eq '0.0.0.0' -and $_.properties.endIpAddress -eq '0.0.0.0' })

    $Assert.Less($firewallAllowAzureServices, '.', 1).Reason($LocalizedData.MariaDBFirewallAllowAzureServices)
}

# Synopsis: Determine if there is an excessive number of firewall rules.
Rule 'Azure.MariaDB.FirewallRuleCount'-Ref 'AZR-000343' -Type 'Microsoft.DBforMariaDB/servers' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    $firewallRules = @(GetSubResources -ResourceType 'Microsoft.DBforMariaDB/servers/firewallRules')

    $Assert.LessOrEqual($firewallRules, '.', 10).
    Reason($LocalizedData.ExceededFirewallRuleCount, $firewallRules.Length, 10).PathPrefix('resources')
}

# Synopsis: Determine if there is an excessive number of permitted IP addresses.
Rule 'Azure.MariaDB.FirewallIPRange' -Ref 'AZR-000344' -Type 'Microsoft.DBforMariaDB/servers' -Tag @{ release = 'GA'; ruleSet = '2022_12'; 'Azure.WAF/pillar' = 'Security'; } {
    $summary = GetIPAddressSummary

    [int]$public = [int]$summary.Public
    $Assert.LessOrEqual($public, '.', 10).
    Reason($LocalizedData.DBServerFirewallPublicIPRange, $summary.Public, 10).PathPrefix('resources')
}

#endregion Rules

#region Helper functions

function global:GetMariaDBDatabaseName {
    [CmdletBinding()]
    [OutputType([string])]
    param ()
    process {
        if ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers') {
            GetSubResources -ResourceType 'Microsoft.DBforMariaDB/servers/databases' |
            ForEach-Object { ($_.name -split '/')[-1] }
        }
        elseif ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers/databases') {
            ($PSRule.TargetName -split '/')[-1]
        }
    }
}

function global:GetMariaDBFirewallRuleName {
    [CmdletBinding()]
    [OutputType([string])]
    param ()
    process {
        if ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers') {
            GetSubResources -ResourceType 'Microsoft.DBforMariaDB/servers/firewallRules' |
            ForEach-Object { ($_.name -split '/')[-1] }
        }
        elseif ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers/firewallRules') {
            ($PSRule.TargetName -split '/')[-1]
        }
    }
}

function global:GetMariaDBVNETRuleName {
    [CmdletBinding()]
    [OutputType([string])]
    param ()
    process {
        if ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers') {
            GetSubResources -ResourceType 'Microsoft.DBforMariaDB/servers/virtualNetworkRules' |
            ForEach-Object { ($_.name -split '/')[-1] }
        }
        elseif ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers/virtualNetworkRules') {
            ($PSRule.TargetName -split '/')[-1]
        }
    }
}

function global:GetMariaDBFirewallRule {
    [CmdletBinding()]
    [OutputType([PSObject])]
    param ()
    process {
        if ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers') {
            GetSubResources -ResourceType 'Microsoft.DBforMariaDB/servers/firewallRules'
        }
        elseif ($PSRule.TargetType -eq 'Microsoft.DBforMariaDB/servers/firewallRules') {
            $TargetObject
        }
    }
}

#endregion Helper functions

# SIG # Begin signature block
# MIIoCwYJKoZIhvcNAQcCoIIn/DCCJ/gCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDOHF6WmGMfZpg6
# IGs1LEFRmJ9O90fH5r7DcJFVS/Kwp6CCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
# /Xmfwb1tbWrJUnMTDXpQzTGCGeswghnnAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
# BQCggZAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwLwYJKoZIhvcNAQkEMSIE
# IEjy1qXct6pwZ7RY6y5Ur5J042rSSJ/3nVWr2Wo1yUggMEIGCisGAQQBgjcCAQwx
# NDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29m
# dC5jb20wDQYJKoZIhvcNAQEBBQAEggEAjg95nSCZgc4iQ1EAdoiOjvqvP+VYxOBV
# C/JUqmHKP4GTm84NHtls8BdKcF1/G37jUg+bPb9Ff1qvRqgDDqPRQnjFgPvM08QS
# 2APGmL4iJUQAUlWtaO0ZG9AFufDfwlvzfqnrmDrgWBzXQMUzipvTC6+om56bNd0Z
# F/xBh8cav8c59VLiVLZiSMyd6fxwWBGsJ3J/nmnftFmXJR8WlGnMPfVpuZho4/Fn
# fHmddwdDCYKy3E+knVg58N0S/pnhI2jjIh9TP2ExY9ntietXu7Ymyn36mvFtiPnG
# qWspKLT3SXMomoC9qfjE3Bzi1Zs7sByIYeQFwD0eMgEyi60Rv8Qa8aGCF5MwgheP
# BgorBgEEAYI3AwMBMYIXfzCCF3sGCSqGSIb3DQEHAqCCF2wwghdoAgEDMQ8wDQYJ
# YIZIAWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYB
# BAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCAxMjN/U/IqD9Waw9+9QA50rfTzaYHk
# O8G7804d/hHa/wIGaBpm6GQ9GBIyMDI1MDUwNzA3NDc0MC4zMVowBIACAfSggdGk
# gc4wgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNV
# BAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGll
# bGQgVFNTIEVTTjozNzAzLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRp
# bWUtU3RhbXAgU2VydmljZaCCEeowggcgMIIFCKADAgECAhMzAAACCkeyFNnusrMP
# AAEAAAIKMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy
# MDEwMB4XDTI1MDEzMDE5NDI1N1oXDTI2MDQyMjE5NDI1N1owgcsxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBB
# bWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjozNzAz
# LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
# ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALLs3PASlvsGnACT0snT
# RerfRNxONzA1nzRPEC0BuFJonaTCckDUC78Oj398QGMAe/oya23d+Y8N4gmdDtUF
# 4irxFx+NyOts8iDfADm/kxB+U81IE069xdE/59mcDLQQsPN+ckecKRk2xBRnsYXs
# vFQtMo5hjZgnDhOuZweiGRjoOMJnLGGqYZDDB1uOg9ZFti7+jMV6b/J8k/KNUGqX
# XTrxtxWHnwDxzkIPpNY38ve743L7s7z4O96vqoFPjgTLul89kxnUeLvK8Iu/ksbN
# IHqjY4PkYhnLvPiSHxRgd3OOf1bH5BnbbfdIlAq1mGkju4d/egxODTNqdB/PuaC5
# 15+YYGtASDWjHef7dOLOHQP3NWY1A/2wWOw9C00Zn0gP0fwD6QUifHiatLEDZLIY
# w5BzGUYzfSS0gozeKoK4URT0IdUyk33j/V+XhPo+icn7+hYmoWVq1i4wq/Zny6Km
# ucVwDEKk6wMhUE70rW8d4AyJBBSVwT0IPnfojVgueY7aodqA8+ZeF04asdScJS2i
# nbV6W6QeHvmr/nMf46c16Snm52mNA1kK+JgBl0ewueRTQ19QCvqvVSoNxKrXJ/lG
# LCKYHxKOx2YeWXiA+OapWLT+uaczWgARCbc/JZxNBCJtguK4o3tjiKjlslNXCb69
# FFuknlQv8PfcL//uqcdt6hYFAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUAq8XQQSP
# gDI99jxb+quwC9+1nCQwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIw
# XwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3Js
# MGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3Nv
# ZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENB
# JTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEF
# BQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBALCTc9bQLKM5
# qpcIw66xN17t6nYLA//FXUnej0oCIpJ2rxrZRHlEIdiGcmx56bB4xQfaQ15+mcCH
# YGfwfaikPO0MmSPw5hF38pDKwTXY3Bpjco7ABbxGDw51e/l9Rkiw5aCmuQJAzRWg
# Ud1dgTGQk3cTMFtQJTDfJviAAU8rnpP7pw+kjwwkskJBcc0yC2LZBmFf0qR9EB98
# VgwVymxsj6jOILkGuuTffrVwkUeGAQlHQnjaeplMZKBSkMYdJkBEao1wBXmH45AM
# t4XandRHH8/oxxSDWcnaAw9gGwP5vB30HRz9chn0y3e6OUQs+mSKOMJ1JnGHO7Yz
# dJlYmvnu5j4UL4uym8g4fU6mh9qeHckYOiw1wAS73JQxYqwQEyeAPpVZBJBhnpf0
# XzTMKh5nBOrSL0C6OdjPPHlbZ8SBl6NG7orUYIBKbO02VgmUAKOpp9ZGh9OqQmFX
# 8na/3tfeu4O9+m465ChS1UDBesOwbY04G69Wyjkp1bniEFKzP/j45EHiouerj8Y2
# 1qNQeispEocY6AWjwMppcb5Q0A3CEY3EdsgtJrn0/ETEyAKMFE/fzbzIYqyq5ITP
# Ms1afPlp/1mZ4fjzT1/Ai20jjUmS6Jj1fqGYyYti/w5jfi+84r7PLGRL70FQtUA/
# qC37JodoGWuWfwaLj90GvbLpKuv/nqDQMIIHcTCCBVmgAwIBAgITMwAAABXF52ue
# AptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgz
# MjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcN
# AQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxO
# dcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQ
# GOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq
# /XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVW
# Te/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7
# mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De
# +JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM
# 9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEz
# OUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2
# ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqv
# UAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q
# 4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcV
# AgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXS
# ZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcC
# ARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRv
# cnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1
# AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaA
# FNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9j
# cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8y
# MDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAt
# MDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8
# qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7p
# Zmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2C
# DPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BA
# ljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJ
# eBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1
# MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz
# 138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1
# V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLB
# gqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0l
# lOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFx
# BmoQtB1VM1izoXBm8qGCA00wggI1AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l
# cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046MzcwMy0w
# NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Wi
# IwoBATAHBgUrDgMCGgMVANEAxUmUDpsqr3dWe7dSQmCbkeVhoIGDMIGApH4wfDEL
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWlj
# cm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDrxY4j
# MCIYDzIwMjUwNTA3MDc0NTM5WhgPMjAyNTA1MDgwNzQ1MzlaMHQwOgYKKwYBBAGE
# WQoEATEsMCowCgIFAOvFjiMCAQAwBwIBAAICFOswBwIBAAICEuMwCgIFAOvG36MC
# AQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEK
# MAgCAQACAwGGoDANBgkqhkiG9w0BAQsFAAOCAQEAiRW/OberJJ1rzE2GeFX3AcpV
# 5aDOftLoDB/rYaG1+1+s+fe9z0Yj2acapcHQKfllcdLlx9RY/P7dzYMatlENt2DG
# FfTh1j879UtrMgQAPRNUXpSjQjWfbtClPp5nVRmD0O3rDl2GgkSL4waVo0MfOedt
# vNJmHVKlAF/lTWMxvHuRcVOJq6w1ytYuIN5rKyzD3jlGjie225zkEjK2AL5ARE24
# vcjL1gaOijo3LplcTSQK9z/WBzImPrDxuVO7XHK4vregcAVUE7Oh8umxaE+R/sYi
# i46sgQB6uJXRhSLT295m67sPq1H6LMspybqcuwIjAovRur2qheL/fyODOdWmoDGC
# BA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAC
# CkeyFNnusrMPAAEAAAIKMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMx
# DQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIDFgi3I+c3Ul1JcE4u+z46iQ
# 45sGRTgNbmg/EKZV8xdPMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgTZrL
# /LR6kr9fdnTcpNyWioTy70hdG107sx7HSHD35JowgZgwgYCkfjB8MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
# VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAgpHshTZ7rKzDwABAAACCjAiBCCEt8gS
# JkVJrJB2jQ28TC2DkBC+fwxr6VNH6nOeBE6GJzANBgkqhkiG9w0BAQsFAASCAgA4
# k0BJdr9eDHX+MhKQSS/qpuC8Wx6vRwTkjrvyzlRQc0BG7nCE9XFe/FmbDJ0r9Ris
# eTUrG4jA5JVyEVes2WGTaBfUAh8igk4fbIlzxM47+njjf9UOJTQ/IVNbtTepy0W3
# RQE0f9gNdivPgtU/C5+4q782mNsi5/CujBCdopLneNJK+k1s8HQywBO3/8J304Kn
# saoDywKLYz1yvkCBolBQIuKfy14KQmpdQeoz6vyRcHZ/AexhGoLvhMaY5UfZhe7s
# HAivdyf2ULvIreJm9v9OP2+ZBB6c3/rf0daRaY0MNT+I+SH6d1ogR2zFX9lZlmfn
# dHgdVXJjE8+OpqcBPbq1j7r4iVsaIBLpYMgFWtbZHKN2RFYpolSXM6TgN4fANIWH
# JNx0rwhK+nGU5WH9Lz3WsY2aQLPdP0ZGRTYV8VD5F1Bz2/aYYJ3IZ8jC5zHkIGXw
# SZo39XjBUpcCgwZpSP6xKT6MdMBQ4z6oWywt96xAvXi5ZO2qU48hTyEyoAZs3RAM
# e3BO62Vh0aW/8TrZP7BP6l4iTqR94emLEz27+PZTmYN+1AEfNpoN0CeEsoWMfDzO
# G1WaW76DZej/ewYkbXDMOm4RbnfJMaeKCXMifrDnZJhuNVmQgTPvqDv4PdkLSCeD
# FpzQ3CWmeVrzokeZITUAWJ9/CXYcLidYQhXdG41Vqw==
# SIG # End signature block