Framework/Core/SVT/Services/CloudService.ps1
# # CloudServices.ps1 # Set-StrictMode -Version Latest class CloudService: SVTBase { hidden [PSCloudService] $ResourceObject; hidden [bool] $hasClassicPermissions = $true; hidden [string] $cloudServiceAPIVersion = "2016-04-01" CloudService([string] $subscriptionId, [string] $resourceGroupName, [string] $resourceName): Base($subscriptionId, $resourceGroupName, $resourceName) { $this.GetResourceObject(); } CloudService([string] $subscriptionId, [SVTResource] $svtResource): Base($subscriptionId, $svtResource) { $this.GetResourceObject(); } hidden [PSObject] GetResourceObject() { if (-not $this.ResourceObject) { $this.UpdateCloudServiceInstance() } return $this.ResourceObject; } hidden [void] UpdateCloudServiceInstance() { #step 1: load data from ARM model $this.ResourceObject = [PSCloudService]::new($this.ResourceContext.ResourceName, $this.ResourceContext.ResourceGroupName) $this.ResourceObject.LoadCloudConfiguration(); #step 2: load from classic config model try { $ResourceAppIdURI = [WebRequestHelper]::ClassicManagementUri; $ClassicAccessToken = [Helpers]::GetAccessToken($ResourceAppIdURI) if($null -ne $ClassicAccessToken) { $header = "Bearer " + $ClassicAccessToken $headers = @{"Authorization"=$header;"Content-Type"="application/json"; "x-ms-version" ="2013-08-01"} $uri = [string]::Format("{0}/{1}/services/hostedservices/{2}?embed-detail=true","https://management.core.windows.net", $this.SubscriptionContext.SubscriptionId ,$this.ResourceContext.ResourceName) $cloudServiceResponse = Invoke-WebRequest -Method GET -Uri $uri -Headers $headers if($cloudServiceResponse.StatusCode -ge 200 -and $cloudServiceResponse.StatusCode -le 399) { if($null -ne $cloudServiceResponse.Content) { [xml] $cloudService = $cloudServiceResponse.Content $this.ResourceObject.LoadCloudConfigurationFromClassicConfig($cloudServiceResponse.Content); } } } } catch { $this.hasClassicPermissions = $false; } } hidden [ControlResult] CheckCloudServiceHttpCertificateSSLOnInstanceEndpoints([ControlResult] $controlResult) { if($this.hasClassicPermissions) { $isCompliant = $true; $nonCompliantInstanceEndpoints = @(); if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.RoleInstances) { $this.ResourceObject.RoleInstances | Foreach-Object{ $roleInstance = $_; if($null -ne $roleInstance) { $roleInstance.InstanceEndpoints | ForEach-Object { $instanceEndpoint = $_ if($instanceEndpoint.Protocol -eq "http") { $isCompliant = $false; $nonCompliantInstanceEndpoints += $_ } } } } } if($isCompliant) { $controlResult.VerificationResult = [VerificationResult]::Passed; } else { #$controlResult.AddMessage([VerificationResult]::Failed, "Instance endpoints of cloud service must have http disabled.",$nonCompliantInstanceEndpoints, $true, "InstanceEndpoints"); $controlResult.AddMessage([VerificationResult]::Failed, "Instance endpoints of cloud service must have http disabled.",$nonCompliantInstanceEndpoints); } } else { $controlResult.AddMessage([VerificationResult]::Manual, "Don't have the required permissions to scan the cloud service."); } return $controlResult; } hidden [ControlResult] CheckCloudServiceHttpCertificateSSLOnInputEndpoints([ControlResult] $controlResult) { $InputEndpoints = @(); if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.InputEndpoints) { $Role.InputEndpoints | ForEach-Object { $inpEp = $_; $inputEndpoint = "" | SELECT SlotName, RoleName, PublicIpAddress, PrivatePort, PublicPort, Protocol, VirtualIpName, IsCompliant $inputEndpoint.SlotName = $DeploymentSlot.SlotName; $inputEndpoint.RoleName = $Role.RoleName; $inputEndpoint.PublicIpAddress = $inpEp.PublicIpAddress; $inputEndpoint.PrivatePort = $inpEp.PrivatePort; $inputEndpoint.PublicPort = $inpEp.PublicPort; $inputEndpoint.Protocol = $inpEp.Protocol; $inputEndpoint.VirtualIpName = $inpEp.VirtualIpName; $inputEndpoint.IsCompliant = "False" if($inpEp.protocol -eq "https") { $inputEndpoint.IsCompliant = "True" } $InputEndpoints += $inputEndpoint } } } } } } if(($InputEndpoints | Where-Object { $_.IsCompliant -eq "False"} | Measure-Object).Count -gt 0) { $controlResult.AddMessage([VerificationResult]::Failed, "There are active non SSL enabled input endpoints.", $InputEndpoints); } else { $controlResult.AddMessage([VerificationResult]::Passed, "There are no active non SSL enabled input endpoints.", $InputEndpoints); } return $controlResult; } hidden [ControlResult] CheckCloudServiceInstanceEndpoints([ControlResult] $controlResult) { if($this.hasClassicPermissions) { $instanceEndpoints = @(); if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.RoleInstances) { $Role.RoleInstances | ForEach-Object { $instanceEndpoints += $_ } } } } } } #$controlResult.AddMessage([VerificationResult]::Verify, "Validate the IP Settings configured for the instance endpoints on cloud service.", $instanceEndpoints, $true, "InstanceEndpoints" ); $controlResult.AddMessage([VerificationResult]::Verify, "Validate the IP Settings configured for the instance endpoints on cloud service.", $instanceEndpoints); } else { $controlResult.AddMessage([VerificationResult]::Manual, "Don't have the required permissions to scan the cloud service."); } return $controlResult; } hidden [ControlResult] CheckCloudServiceInputEndpoints([ControlResult] $controlResult) { $InputEndpoints = @(); if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.InputEndpoints) { $Role.InputEndpoints | ForEach-Object { $InputEndpoints += $_ } } } } } } #$controlResult.AddMessage([VerificationResult]::Verify, "Remove any un-used internal endpoints from your cloud service.", $inputEndpoints, $true, "InputEndpoints" ); $controlResult.AddMessage([VerificationResult]::Verify, "Remove any un-used input endpoints from your cloud service.", $InputEndpoints); return $controlResult; } hidden [ControlResult] CheckCloudServiceRemoteDebuggingStatus([ControlResult] $controlResult) { if($this.hasClassicPermissions) { $isCompliant = $true; $nonCompliantInstanceEndpoints = @(); if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.RoleInstances) { $Role.RoleInstances | ForEach-Object { $roleInstance = $_; if($null -ne $roleInstance) { $roleInstance.InstanceEndpoints | ForEach-Object { $instanceEndpoint = $_ if($instanceEndpoint.Name -like "Microsoft.WindowsAzure.Plugins.RemoteDebugger*") { $isCompliant = $false; $nonCompliantInstanceEndpoints += $_ } } } } } } } } } if($isCompliant) { $controlResult.VerificationResult = [VerificationResult]::Passed; } else { #$controlResult.AddMessage([VerificationResult]::Failed, "Remote debugging endpoints enabled on cloud service.", $nonCompliantInstanceEndpoints, $true, "InstanceEndpoints"); $controlResult.AddMessage([VerificationResult]::Failed, "Remote debugging endpoints enabled on cloud service.", $nonCompliantInstanceEndpoints); } } else { $controlResult.AddMessage([VerificationResult]::Manual, "Don't have the required permissions to scan the cloud service."); } return $controlResult; } hidden [ControlResult] CheckCloudServiceAntiMalwareStatus([ControlResult] $controlResult) { if($this.hasClassicPermissions) { $isCompliant = $false; $extensions = @{}; if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.Extensions) { $Role.Extensions | ForEach-Object { $extension = $_; $extensions.Add($DeploymentSlot.SlotName + "->" + $extension.RoleName,"Disabled"); if($null -ne $extension -and $null -ne $extension.ExtensionId) { $extension.ExtensionId | ForEach-Object { $extensionId = $_ if($extensionId.Id -like "*Antimalware*") { $extensions[$DeploymentSlot.SlotName + "->" + $extension.RoleName] = "Enabled" } } } } } } } } } if($extensions.Count -gt 0) { if(($extensions.Values | Where-Object { $_ -eq "Disabled"} | Measure-Object).Count -le 0) { $controlResult.VerificationResult = [VerificationResult]::Passed; } else { $controlResult.AddMessage([VerificationResult]::Failed, "Antimalware extension is not enabled on cloud service.", $extensions); } } else { $controlResult.VerificationResult = [VerificationResult]::Passed; } } else { $controlResult.AddMessage([VerificationResult]::Manual, "Don't have the required permissions to scan the cloud service."); } return $controlResult; } hidden [ControlResult] CheckCloudServiceOSPatchStatus([ControlResult] $controlResult) { $OSPatchVersions = @(); $isCompliant = $true; if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if(-not $DeploymentSlot.IsOSAutoUpdateTurnedOn) { $isCompliant = $false; } } } if(-not $isCompliant) { $controlResult.AddMessage([VerificationResult]::Failed, "Cloud service is not set up for automatic OS updates."); } else { $controlResult.AddMessage([VerificationResult]::Passed, "Cloud service is enabled with automatic OS updates"); } return $controlResult; } hidden [ControlResult] CheckCloudServiceRemoteDesktopAccess([ControlResult] $controlResult) { if($this.hasClassicPermissions) { $extensions = @{}; if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.Extensions) { $Role.Extensions | ForEach-Object { $extension = $_; $extensions.Add($DeploymentSlot.SlotName + "->" + $extension.RoleName,"Disabled"); if($null -ne $extension -and $null -ne $extension.ExtensionId) { $extension.ExtensionId | ForEach-Object { $extensionId = $_ if($extensionId.Id -like "*RDP*") { $extensions[$DeploymentSlot.SlotName + "->" + $extension.RoleName] = "Enabled" } } } } } } } } } if($extensions.Count -gt 0) { if(($extensions.Values | Where-Object { $_ -eq "Enabled"} | Measure-Object).Count -le 0) { $isCompliant = $true; } else { $isCompliant = $false; $controlResult.AddMessage("Remote desktop endpoints are enabled on cloud service.", $extensions); } } else { $isCompliant = $true; } #$b.ServiceConfiguration.Role[0].ConfigurationSettings.Setting.SyncRoot["Microsoft.WindowsAzure.Plugins.RemoteAccess.Enabled"] $nonCompliantInstanceEndpoints = @(); if($isCompliant) { if($null -ne $this.ResourceObject -and $null -ne $this.ResourceObject.DeploymentSlots) { $this.ResourceObject.DeploymentSlots | ForEach-Object { $DeploymentSlot = $_; if($null -ne $DeploymentSlot -and $null -ne $DeploymentSlot.Roles) { $DeploymentSlot.Roles | ForEach-Object { $Role = $_; if($null -ne $Role.RoleInstances) { $Role.RoleInstances | ForEach-Object { $roleInstance = $_; if($null -ne $roleInstance) { $roleInstance.InstanceEndpoints | ForEach-Object { $instanceEndpoint = $_ if($instanceEndpoint.Name -like "Microsoft.WindowsAzure.Plugins.RemoteForwarder*") { $isCompliant = $false; $nonCompliantInstanceEndpoints += $_ } } } } } } } } } } if($isCompliant) { $controlResult.VerificationResult = [VerificationResult]::Passed; } else { $controlResult.VerificationResult = [VerificationResult]::Failed; } } else { $controlResult.AddMessage([VerificationResult]::Manual, "Don't have the required permissions to scan the cloud service."); } return $controlResult; } } # SIG # Begin signature block # MIIkAgYJKoZIhvcNAQcCoIIj8zCCI+8CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBpZpxxqg5EKsZb # gsrLjLzkpOSczK7JiggM3RVipLqHkqCCDZMwggYRMIID+aADAgECAhMzAAAAjoeR # pFcaX8o+AAAAAACOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTYxMTE3MjIwOTIxWhcNMTgwMjE3MjIwOTIxWjCBgzEL # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q # UjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA0IfUQit+ndnGetSiw+MVktJTnZUXyVI2+lS/qxCv # 6cnnzCZTw8Jzv23WAOUA3OlqZzQw9hYXtAGllXyLuaQs5os7efYjDHmP81LfQAEc # wsYDnetZz3Pp2HE5m/DOJVkt0slbCu9+1jIOXXQSBOyeBFOmawJn+E1Zi3fgKyHg # 78CkRRLPA3sDxjnD1CLcVVx3Qv+csuVVZ2i6LXZqf2ZTR9VHCsw43o17lxl9gtAm # +KWO5aHwXmQQ5PnrJ8by4AjQDfJnwNjyL/uJ2hX5rg8+AJcH0Qs+cNR3q3J4QZgH # uBfMorFf7L3zUGej15Tw0otVj1OmlZPmsmbPyTdo5GPHzwIDAQABo4IBgDCCAXww # HwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0OBBYEFKvI1u2y # FdKqjvHM7Ww490VK0Iq7MFIGA1UdEQRLMEmkRzBFMQ0wCwYDVQQLEwRNT1BSMTQw # MgYDVQQFEysyMzAwMTIrYjA1MGM2ZTctNzY0MS00NDFmLWJjNGEtNDM0ODFlNDE1 # ZDA4MB8GA1UdIwQYMBaAFEhuZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEsw # SaBHoEWGQ2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0Nv # ZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsG # AQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p # Y0NvZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkq # hkiG9w0BAQsFAAOCAgEARIkCrGlT88S2u9SMYFPnymyoSWlmvqWaQZk62J3SVwJR # avq/m5bbpiZ9CVbo3O0ldXqlR1KoHksWU/PuD5rDBJUpwYKEpFYx/KCKkZW1v1rO # qQEfZEah5srx13R7v5IIUV58MwJeUTub5dguXwJMCZwaQ9px7eTZ56LadCwXreUM # tRj1VAnUvhxzzSB7pPrI29jbOq76kMWjvZVlrkYtVylY1pLwbNpj8Y8zon44dl7d # 8zXtrJo7YoHQThl8SHywC484zC281TllqZXBA+KSybmr0lcKqtxSCy5WJ6PimJdX # jrypWW4kko6C4glzgtk1g8yff9EEjoi44pqDWLDUmuYx+pRHjn2m4k5589jTajMW # UHDxQruYCen/zJVVWwi/klKoCMTx6PH/QNf5mjad/bqQhdJVPlCtRh/vJQy4njpI # BGPveJiiXQMNAtjcIKvmVrXe7xZmw9dVgh5PgnjJnlQaEGC3F6tAE5GusBnBmjOd # 7jJyzWXMT0aYLQ9RYB58+/7b6Ad5B/ehMzj+CZrbj3u2Or2FhrjMvH0BMLd7Hald # G73MTRf3bkcz1UDfasouUbi1uc/DBNM75ePpEIzrp7repC4zaikvFErqHsEiODUF # he/CBAANa8HYlhRIFa9+UrC4YMRStUqCt4UqAEkqJoMnWkHevdVmSbwLnHhwCbww # ggd6MIIFYqADAgECAgphDpDSAAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv # ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5 # MDlaFw0yNjA3MDgyMTA5MDlaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIw # MTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQ # TTS68rZYIZ9CGypr6VpQqrgGOBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULT # iQ15ZId+lGAkbK+eSZzpaF7S35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYS # L+erCFDPs0S3XdjELgN1q2jzy23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494H # DdVceaVJKecNvqATd76UPe/74ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZ # PrGMXeiJT4Qa8qEvWeSQOy2uM1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5 # bmR/U7qcD60ZI4TL9LoDho33X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGS # rhwjp6lm7GEfauEoSZ1fiOIlXdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADh # vKwCgl/bwBWzvRvUVUvnOaEP6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON # 7E1JMKerjt/sW5+v/N2wZuLBl4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xc # v3coKPHtbcMojyyPQDdPweGFRInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqw # iBfenk70lrC8RqBsmNLg1oiMCwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMC # AQAwHQYDVR0OBBYEFEhuZOVQBdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQM # HgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud # IwQYMBaAFHItOgIxkEO5FAVO4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0 # dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0Nl # ckF1dDIwMTFfMjAxMV8wM18yMi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUF # BzAChkJodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl # ckF1dDIwMTFfMjAxMV8wM18yMi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGC # Ny4DMIGDMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # b3BzL2RvY3MvcHJpbWFyeWNwcy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcA # YQBsAF8AcABvAGwAaQBjAHkAXwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZI # hvcNAQELBQADggIBAGfyhqWY4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4s # PvjDctFtg/6+P+gKyju/R6mj82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKL # UtCw/WvjPgcuKZvmPRul1LUdd5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7 # pKkFDJvtaPpoLpWgKj8qa1hJYx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft # 0N3zDq+ZKJeYTQ49C/IIidYfwzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4 # MnEnGn+x9Cf43iw6IGmYslmJaG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxv # FX1Fp3blQCplo8NdUmKGwx1jNpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG # 0QaxdR8UvmFhtfDcxhsEvt9Bxw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf # 0AApxbGbpT9Fdx41xtKiop96eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkY # S//WsyNodeav+vyL6wuA6mk7r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrv # QQqxP/uozKRdwaGIm1dxVk5IRcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIV # xTCCFcECAQEwgZUwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAA # AI6HkaRXGl/KPgAAAAAAjjANBglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMx # DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq # hkiG9w0BCQQxIgQg2t0M18Svt+lt9N13lIp19JFR6aYHoRW+xHMC2eQBpvUwRAYK # KwYBBAGCNwIBDDE2MDSgEoAQAEEAegBTAEQASwAyADUAMqEegBxodHRwczovL2Fr # YS5tcy9henNka29zc2RvY3MgMA0GCSqGSIb3DQEBAQUABIIBADXtDv/X75KxGCfK # dg32NY8zANdvH1f6dkD7N/Be54Xa3JIuAQEXQzL33yf0bgiH7qXejRbhlWJlW7h9 # X3DFbz8EibWnKaHAByYppXfFHDdUGRZ9SKRyBD9Y/mXMAeL7tZbtNvgnGXZx16gb # vw6PUm0b4DCqDZcSRbTnXsEkC/YZfTnkLsqSeOhwcUZSC6s42zW9wf690PJcRj9Q # 8cSpS5nlx+IctGUe4W6HKDEk8b9OccnIvOPKPSGOgJ/odpyzTY2IA10BQxYdYlVu # bdC2XcVVWlS3c9fi5Fjkf94d5goSzyTxealaizp7qGjwcCpqha9eoz/dZBKa8rjy # Ji4lwtyhghNNMIITSQYKKwYBBAGCNwMDATGCEzkwghM1BgkqhkiG9w0BBwKgghMm # MIITIgIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBPQYLKoZIhvcNAQkQAQSgggEsBIIB # KDCCASQCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQgy4MQ3Jqj7VuP # 5i3NmlBHJhMTAAwE5INVEMxsuaNOTKwCBlmSONxRDhgTMjAxNzA5MDUwOTM3MTUu # NDE5WjAHAgEBgAIB9KCBuaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh # c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD # b3Jwb3JhdGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0Ug # RVNOOjdEMkUtMzc4Mi1CMEY3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt # cCBTZXJ2aWNloIIO0DCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcN # AQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAw # BgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEw # MB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIxNDY1NVowfDELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt # U3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp # HQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF++18aEssX8XD5WHCdrc+Zitb8BVT # JwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRDDNdNuDgIs0Ldk6zWczBXJoKjRQ3Q # 6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSxz5NMksHEpl3RYRNuKMYa+YaAu99h # /EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1rL2KQk1AUdEPnAY+Z3/1ZsADlkR+ # 79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16HgcsOmZzTznL0S6p/TcZL2kAcEgCZN4 # zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB4jAQBgkrBgEEAYI3FQEEAwIBADAd # BgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqFbVUwGQYJKwYBBAGCNxQCBAweCgBT # AHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw # FoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov # L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0 # XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAx # MC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCBkjCBjwYJKwYBBAGCNy4DMIGBMD0G # CCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3MvQ1BT # L2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAAbwBs # AGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4IC # AQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUxvs8F4qn++ldtGTCzwsVmyWrf9efw # eL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GASinbMQEBBm9xcF/9c+V4XNZgkVkt0 # 70IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1L3mBZdmptWvkx872ynoAb0swRCQi # PM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWOM7tiX5rbV0Dp8c6ZZpCM/2pif93F # SguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4pm3S4Zz5Hfw42JT0xqUKloakvZ4a # rgRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45V3aicaoGig+JFrphpxHLmtgOR5qA # xdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir995y # fmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7COaY # LeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7dDJL # 32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+mdHhk4 # L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJEjCCBNowggPCoAMCAQIC # EzMAAACiTI4d2qkhfIQAAAAAAKIwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp # bWUtU3RhbXAgUENBIDIwMTAwHhcNMTYwOTA3MTc1NjQ5WhcNMTgwOTA3MTc1NjQ5 # WjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UE # CxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjdEMkUtMzc4Mi1CMEY3 # MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjANBgkq # hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApgF3BXvDfQ52aL3GqIPGgnsBcKiwaoRy # T1SObb5nIGq+7C3dL0dx4ZL9dGJrvnTbhTbbNMjHaQrmNhJJQEe4QTRZYj3xE6eu # CQEo0RRYYx85sGg2BNhZ2k1b4JFxEvxBsw3OwXKhFSb285lb6OCKrhB1qjnX8Q7y # CcExdQwpKind7I43Kt9rquMyuNhNe8hxEJDBvjqGGQvo6a0fuDQjrWGMli77Pkwv # QmXGCx6xsFjCa5vnz4sEx5NBneZ5uOX3llfcgMUFBQCmQSI3Fvm060esLzmt0MXT # DETXCVtp0QnzAytjJ1oHkPTvjKMzJY03LD8lmbPzFT6mkur5URjl1QIDAQABo4IB # GzCCARcwHQYDVR0OBBYEFG672cHC2hawfK3CU3/n0BcTPbxXMB8GA1UdIwQYMBaA # FNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9j # cmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0YVBDQV8y # MDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENBXzIwMTAt # MDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJ # KoZIhvcNAQELBQADggEBADWZV20z9kidnkHczKlg7lxHSFQRCoa5Vz+nbZiOynxp # pmqWg845sr1kDpkwu77c4HWCa0Ip4YVEjjF7c2hZeZidV7QWB/yiKbyjcIIhJh1l # SxnmiSpVza+6kmreyJoJAlslFpfHq7la2vTzoBuCcKpKxka1eoDEYkKD93FaZCsm # /fOOIwtOFvIb8tA1CkPaPPOpGpGKxDV42RCoYwajZH+svyjuqBwVeI+g98Jxxdi4 # ks6ql3I5TA9oZEROyoblLcuyArEoPf0ZvwDWSNPfDbTtDCSQRRS8lXk6A+xjhjw0 # 7nGyPS5qeZCCtusbGlm7r4uLefGp/Uox8jxqGxVdOsahggN5MIICYQIBATCB46GB # uaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsG # A1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjdEMkUtMzc4Mi1C # MEY3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiUKAQEw # CQYFKw4DAhoFAAMVAF4vF+lxhNIyy+zXXko7+E63h+n1oIHCMIG/pIG8MIG5MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BS # MScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NTdGNi1DMUUwLTU1NEMxKzApBgNV # BAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcN # AQEFBQACBQDdWK1sMCIYDzIwMTcwOTA1MDQ1ODIwWhgPMjAxNzA5MDYwNDU4MjBa # MHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAN1YrWwCAQAwCgIBAAICDnkCAf8wBwIB # AAICGLQwCgIFAN1Z/uwCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoD # AaAKMAgCAQACAxbjYKEKMAgCAQACAwehIDANBgkqhkiG9w0BAQUFAAOCAQEAcmGj # BBTr+m5dd4eEDdc2UUFm4Al/CGHzZYgdOFKvfZ1/YnsnH6MMuoUgAwG6+EhEWyMD # oFUbsyNGdUyXXN9eQPDmjT4Gk1Tl7cQHgHEKVmqElgVAyDISE3V3CvqYlypCasYl # iuOt/aE+EiBterVmkPPEB+XFz1M+WMFEjjA/l/9zTQj9XYjey4415ox5/k4TT02B # GUr+0OcU1/7BzL3CqEHRpal9ES6i7+8jFsm8xgi7ifMZSTVeFlcw0AzO38+YUc7T # +othjWn50Ll0INYWIE1uHMP6M+hGN9fD8TK0WdhaKP59pbcMpd9d3kjG+sNeggSh # bwcVPJiNzcVIaGbjxDGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w # IFBDQSAyMDEwAhMzAAAAokyOHdqpIXyEAAAAAACiMA0GCWCGSAFlAwQCAQUAoIIB # MjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEILIS # we3quvQdDjFEXVS+LvwZ85N9xaQkTOSzI1pFfsCaMIHiBgsqhkiG9w0BCRACDDGB # 0jCBzzCBzDCBsQQUXi8X6XGE0jLL7NdeSjv4TreH6fUwgZgwgYCkfjB8MQswCQYD # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv # ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAKJMjh3aqSF8hAAAAAAAojAWBBTM # BEq1o6Nbw5EBNOEoqaWczrIaQDANBgkqhkiG9w0BAQsFAASCAQCjIEN4Hy0YawgJ # DwE0kz8Q1jjb/1xws/4EiB7r21PrHVWtqXlOvsytuqABD/c/Ra9TwJVwKIaik91r # DlIowEr63eYQhpMyWUuMravag9CC3LN8OdDkpIF2l3ePzSaakTlcE9tfTkueIp10 # 1srTXWRa7Lkqj8WU58+FrGBlbyboCHsgDh+G616CBOVu73RXzVlYX9pSiIewXDnY # E0OxF0fwJc3gbbq9ACI4POrhGVtpoA2PkJ0FcA4mj6W/4nvZ4px6mjdbOO2mcCLX # sUeHUoZYFCTGNrJh3qOY7lv0EkrYLyeL7y5aB3VlVWT+aQKhoodkqlKG5xVu5tYC # tOt9BiGq # SIG # End signature block |