SVT/BatchScan.ps1
Set-StrictMode -Version Latest function Get-AzSKADOSecurityStatusBatchMode { [OutputType([String])] [Alias("Get-AzSKAzureDevOpsSecurityStatusBatchMode")] Param ( [string] [Parameter(Mandatory = $true, HelpMessage="Organization name for which the security evaluation has to be performed.")] [ValidateNotNullOrEmpty()] [Alias("oz")] $OrganizationName, [string] [Parameter(Mandatory = $true, HelpMessage="Project name for which the security evaluation has to be performed.")] [ValidateNotNullOrEmpty()] [Alias("pns", "ProjectName", "pn")] $ProjectNames, [string] [Parameter(Mandatory =$false, HelpMessage = "Folder path of builds to be scanned.")] [ValidateNotNullOrEmpty()] [Alias("bp")] $BuildsFolderPath, [switch] [Parameter()] [Alias("ubc")] $UseBaselineControls, [string] [Parameter(Mandatory = $false)] [Alias("ft")] $FilterTags, [string] [Parameter(HelpMessage = "Comma separated control ids to filter the security controls. e.g.: ADO_Organization_AuthN_Use_AAD_Auth, ADO_Organization_SI_Review_InActive_Users etc.")] [Alias("cids")] $ControlIds, [string] [Parameter(Mandatory = $true, HelpMessage="KeyVault URL for PATToken")] [Alias("ptu")] $PATTokenURL, [int] [Parameter(HelpMessage = "Batch size for the scan.")] [ValidateRange(2,10000)] [Alias("bsz")] $BatchSize, [string] [Parameter(Mandatory = $true, HelpMessage = "Folder name where batch scan results are to be stored.")] [Alias("fn")] $FolderName, [string] [Parameter(Mandatory = $true)] [ValidateSet("Build","Release","Build_Release")] [Alias("rtn")] $ResourceTypeName, [string] [Parameter(HelpMessage = "Folder path of releases to be scanned.")] [ValidateNotNullOrEmpty()] [Alias("rfp")] $ReleasesFolderPath, [string] [Parameter(Mandatory = $false, HelpMessage="Name of the project hosting organization policy with which the scan should run.")] [ValidateNotNullOrEmpty()] [Alias("pp")] $PolicyProject, [switch] [Parameter(Mandatory = $false)] [Alias("dnof")] $DoNotOpenOutputFolder, [switch] [Parameter(Mandatory = $false)] [Alias("kco")] $KeepConsoleOpen, [ValidateSet("All","BaselineControls", "Custom")] [Parameter(Mandatory = $false)] [Alias("abl")] [string] $AutoBugLog = [BugLogForControls]::All, [switch] [Parameter(HelpMessage = "Switch to auto-close bugs after the scan.")] [Alias("acb")] $AutoCloseBugs, [string] [Parameter(Mandatory=$false, HelpMessage = "Specify the area path where bugs are to be logged.")] [Alias("apt")] $AreaPath, [string] [Parameter(Mandatory=$false, HelpMessage = "Specify the iteration path where bugs are to be logged.")] [Alias("ipt")] $IterationPath, [string] [Parameter(Mandatory = $false, HelpMessage = "Specify the security severity of bugs to be logged.")] [Alias("ssv")] $SecuritySeverity, [string] [Parameter(HelpMessage="Specify the custom field reference name for bug description.")] [ValidateNotNullOrEmpty()] [Alias("bdf")] $BugDescriptionField ) Begin { [CommandHelper]::BeginCommand($PSCmdlet.MyInvocation); [ListenerHelper]::RegisterListeners(); } Process { try { $projects=@() if(-not [string]::IsNullOrWhiteSpace($ProjectNames)) { $projects += $ProjectNames.Split(',', [StringSplitOptions]::RemoveEmptyEntries) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | ForEach-Object { $_.Trim() } | Select-Object -Unique; } if($ProjectNames -eq "*" -or $projects.Count -gt 1){ [BatchScanManagerForMultipleProjects]::ClearInstance() } else { [BatchScanManager]::ClearInstance() } if (-not [String]::IsNullOrEmpty($PATTokenURL)) { $Context = @(Get-AzContext -ErrorAction SilentlyContinue ) if ($Context.count -eq 0) { $KeyVaultToken=$null; try{ $Response = Invoke-RestMethod -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net' -Method GET -Headers @{Metadata="true"} $KeyVaultToken = $Response.access_token } catch { Write-Host "Either the current user or the Managed Identity of this device does not have access to the tenant hosting the Key Vault. Login as the correct user using Connect-AzAccount or add the Managed Identity of this device in Key Vault." -ForegroundColor Red return; } try { $KeyVaultURL=$PATTokenURL+"?api-version=2016-10-01" $KeyVaultResponse = Invoke-RestMethod -Uri $KeyVaultURL -Method GET -Headers @{Authorization="Bearer $KeyVaultToken"} $PATToken = ConvertTo-SecureString -AsPlainText -Force -String "$($KeyVaultResponse.value)" } catch { Write-Host "Could not extract PATToken from the given key vault URL.`r`nStopping scan command." -ForegroundColor Red return; } } else { if ($PATTokenURL -match "^https://(?<kv>[\w]+)(?:[\.\w+]*)/secrets/(?<sn>[\w]+)/?(?<sv>[\w]*)") { $kvName = $Matches["kv"] $secretName = $Matches["sn"] $secretVersion = $Matches["sv"] if (-not [String]::IsNullOrEmpty($secretVersion)) { $kvSecret = Get-AzKeyVaultSecret -VaultName $kvName -SecretName $secretName -Version $secretVersion } else { $kvSecret = Get-AzKeyVaultSecret -VaultName $kvName -SecretName $secretName } if ($null -eq $kvSecret) { Write-Host "Could not extract PATToken from the given key vault URL.`r`nStopping scan command." -ForegroundColor Red return; } $PATToken = $kvSecret.SecretValue; } else { Write-Host "Could not extract PATToken from the given key vault URL.`r`nStopping scan command." -ForegroundColor Red return; } } } $ContextHelper = [ContextHelper]::new($true); $Context = $null if($PATToken) { $Context = $ContextHelper.SetContext($OrganizationName,$PATToken) } else { Write-Host "Could not access PATToken of the user. Stopping the command. " -ForegroundColor Red; return; } if($ProjectNames -eq "*" -or $projects.Count -gt 1){ [BatchScanManagerForMultipleProjects] $batchScanMngr = [BatchScanManagerForMultipleProjects]:: GetInstance($Context.OrganizationName) } else { [BatchScanManager] $batchScanMngr = [BatchScanManager]:: GetInstance($Context.OrganizationName,$ProjectNames) } if($ProjectNames -eq "*" -or $projects.Count -gt 1){ if($batchScanMngr.isBatchScanInProgress($Context.OrganizationName) -eq $false){ $batchScanMngr.CreateBatchMasterList(); } else { $batchScanMngr.UpdateBatchMasterList(); } } else { if($batchScanMngr.isBatchScanInProgress($Context.OrganizationName,$ProjectNames) -eq $false){ $batchScanMngr.CreateBatchMasterList(); } else { $batchScanMngr.UpdateBatchMasterList(); } } $AzSKContents = [BatchScanManager]::LoadFrameworkConfigFile("AzSKSettings.json", $true); $ModulePath= $AzSKContents.BatchScanModule $commandForNextBatch ='ipmo \"{0}\"; gadsbm ' -f $ModulePath; $PSCmdlet.MyInvocation.BoundParameters.GetEnumerator() | foreach-object { if($_.value -eq $true){ $commandForNextBatch += '-{0} ' -f $_.key } else { $commandForNextBatch += '-{0} \"{1}\" ' -f $_.key, $_.value } } $parametersForGads = $PSCmdlet.MyInvocation.BoundParameters; $parametersForGads.Add("UsePartialCommits", $true); $parametersForGads.Add("AllowLongRunningScan", $true); $parametersForGads.Add("BatchScan",$true); $parametersForGads.Remove("BatchSize") | Out-Null; $parametersForGads.Remove("ModulePath") | Out-Null; $parametersForGads.Remove("PATTokenURL") | Out-Null; $parametersForGads.Remove("KeepConsoleOpen") | Out-Null; #Whether to keep each console open after gads completes. if ($KeepConsoleOpen.IsPresent) { $commandForNextBatch+= '; Read-Host ' } if($ProjectNames -eq "*" -or $projects.Count -gt 1){ $projects = $batchScanMngr.GetProjectsForCurrentScan(); if([string]::IsNullOrEmpty($projects)){ $batchScanMngr.RemoveBatchScanData(); Write-Host 'No unscanned resources found. All projects have been fully scanned. You can use GADSBMR command to combine CSVs from all batch results.'; Read-Host return; } $parametersForGads.Remove("ProjectNames") | Out-Null; $parametersForGads.Add("ProjectNames",$projects) $parametersForGads.Add("BatchScanMultipleProjects",$true) } GADS @parametersForGads if($batchScanMngr.IsScanComplete()){ $batchScanMngr.RemoveBatchScanData(); start-process powershell.exe -argument "Write-Host 'No unscanned resources found. Scan is fully complete. You can use GADSBMR command to combine CSVs from all batch results.'; Read-Host" } else { start-process powershell.exe -argument $commandForNextBatch } } catch { [EventBase]::PublishGenericException($_); if($_.FullyQualifiedErrorId -eq "VariableIsUndefined"){ Write-Host "Two different versions of the same module seems to have been imported in the same session. Close this session and import the correct module." } } } End { [ListenerHelper]::UnregisterListeners(); } } # SIG # Begin signature block # MIIjnQYJKoZIhvcNAQcCoIIjjjCCI4oCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDKFqfVBIGW3Ia4 # RBwuuIwrGIITkBJhKQUmiZyIy9GuE6CCDYEwggX/MIID56ADAgECAhMzAAAB32vw # LpKnSrTQAAAAAAHfMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ1WhcNMjExMjAyMjEzMTQ1WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQC2uxlZEACjqfHkuFyoCwfL25ofI9DZWKt4wEj3JBQ48GPt1UsDv834CcoUUPMn # s/6CtPoaQ4Thy/kbOOg/zJAnrJeiMQqRe2Lsdb/NSI2gXXX9lad1/yPUDOXo4GNw # PjXq1JZi+HZV91bUr6ZjzePj1g+bepsqd/HC1XScj0fT3aAxLRykJSzExEBmU9eS # yuOwUuq+CriudQtWGMdJU650v/KmzfM46Y6lo/MCnnpvz3zEL7PMdUdwqj/nYhGG # 3UVILxX7tAdMbz7LN+6WOIpT1A41rwaoOVnv+8Ua94HwhjZmu1S73yeV7RZZNxoh # EegJi9YYssXa7UZUUkCCA+KnAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUOPbML8IdkNGtCfMmVPtvI6VZ8+Mw # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDYzMDA5MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAnnqH # tDyYUFaVAkvAK0eqq6nhoL95SZQu3RnpZ7tdQ89QR3++7A+4hrr7V4xxmkB5BObS # 0YK+MALE02atjwWgPdpYQ68WdLGroJZHkbZdgERG+7tETFl3aKF4KpoSaGOskZXp # TPnCaMo2PXoAMVMGpsQEQswimZq3IQ3nRQfBlJ0PoMMcN/+Pks8ZTL1BoPYsJpok # t6cql59q6CypZYIwgyJ892HpttybHKg1ZtQLUlSXccRMlugPgEcNZJagPEgPYni4 # b11snjRAgf0dyQ0zI9aLXqTxWUU5pCIFiPT0b2wsxzRqCtyGqpkGM8P9GazO8eao # mVItCYBcJSByBx/pS0cSYwBBHAZxJODUqxSXoSGDvmTfqUJXntnWkL4okok1FiCD # Z4jpyXOQunb6egIXvkgQ7jb2uO26Ow0m8RwleDvhOMrnHsupiOPbozKroSa6paFt # VSh89abUSooR8QdZciemmoFhcWkEwFg4spzvYNP4nIs193261WyTaRMZoceGun7G # CT2Rl653uUj+F+g94c63AhzSq4khdL4HlFIP2ePv29smfUnHtGq6yYFDLnT0q/Y+ # Di3jwloF8EWkkHRtSuXlFUbTmwr/lDDgbpZiKhLS7CBTDj32I0L5i532+uHczw82 # oZDmYmYmIUSMbZOgS65h797rj5JJ6OkeEUJoAVwwggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVcjCCFW4CAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAd9r8C6Sp0q00AAAAAAB3zAN # BglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgI+xNHKg6 # IcuDQuZkPDMkWJMSZy2mYA2vL2voozJ02vswRAYKKwYBBAGCNwIBDDE2MDSgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRyAGmh0dHBzOi8vd3d3Lm1pY3Jvc29mdC5jb20g # MA0GCSqGSIb3DQEBAQUABIIBAJ0Xr6X86dVMbd3oqEahXIdr+vVHErl01LhhE1Iw # n9C1jLNnkzFKn4U1vBYwoBiWuF8YdZw9X8wY8Uy+60A2D17sjoU7OwDSNU0ZS3TP # pIjJj0tvyzUaOHj+PtY+nYIcG3TSo/r2Itr+nOzSlDeGNVYECz28DHe+/V0v9GY9 # 3mHEuxqQ327mxR3Rj9PBTK3P0VfZOAFYX4NkedsJh/9luJMIifQq9G8RTgTOPANO # +O3oCJt/5KpcvZ1Doo0JNm2tC6RR2LONjCCeyMOW0DjBJwN9gegQ2kA2NpwYpS/u # y0l1rTZO0CmA3ZAT9X1HEVO7S2fUEG6V/ga8EcscZedBydChghL6MIIS9gYKKwYB # BAGCNwMDATGCEuYwghLiBgkqhkiG9w0BBwKgghLTMIISzwIBAzEPMA0GCWCGSAFl # AwQCAQUAMIIBWAYLKoZIhvcNAQkQAQSgggFHBIIBQzCCAT8CAQEGCisGAQQBhFkK # AwEwMTANBglghkgBZQMEAgEFAAQgQ+TvPn4s1Q9A3VVZ0z0ohImXbxYBpHUB7MeT # pCwa+8kCBmExNlUOqRgSMjAyMTA5MTMwOTIyMDcuMjNaMASAAgH0oIHYpIHVMIHS # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRN # aWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRo # YWxlcyBUU1MgRVNOOjE3OUUtNEJCMC04MjQ2MSUwIwYDVQQDExxNaWNyb3NvZnQg # VGltZS1TdGFtcCBTZXJ2aWNloIIOSjCCBPkwggPhoAMCAQICEzMAAAE8i/25sz9H # l/0AAAAAATwwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTAwHhcNMjAxMDE1MTcyODIzWhcNMjIwMTEyMTcyODIzWjCB0jELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0 # IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNT # IEVTTjoxNzlFLTRCQjAtODI0NjElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgU2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJgQKulp # A6r2OQ4GkLfjl9DQi86lGorycR76Oiklz/lc02rNqermGt33CJvhF2+m4+PryfkO # b9dm7a8KqdajGHLeLGtuBL+uDcJLduqnwCDVRCD/EDPfZO555M5jVw56VxdFqGiw # hyOWuuS/XcBpwVebgBtgwKBgzoHN1koBF5tzrMS/7hALLj7UBXxEdAcQ52iPjY4m # lsVaUe9grNe4zUAfi+aNP2j98KraZYPsiDb8Kloh3aAcrpH5L3T2Irbu5WSNVqnb # 9JvgBM4sltpVD5fT6FhsRwJ6x/3eD60BBe68Dx0frd2grkjnN1kIXlT/cOJt+Xtk # IWxTqSz6mHiMmtsCAwEAAaOCARswggEXMB0GA1UdDgQWBBThoWfiyhL6NrNhPyUY # 6hi/Jmc8RjAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8E # TzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9k # dWN0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBM # MEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRz # L01pY1RpbVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1Ud # JQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAy9xCMlN2XeW5IzMWp # GTFGSUn4pZFRSUHcjYolVZvgafp5Z0lOJZ0LW7F6MXag9fRv5f1AiGLy7UBpXv3Z # 4SK3aVDOpWA+J/JNkYuPMrY6i7g+P8Xnw+naboe6kZ+40B6GWf6FK+8gTmCAScKK # /2VWQAk4yUscXfwNs+/unJazQvO/ayNnA8e92G1XyUG05iwTw3HOeVuzJzzS9GdF # 6qbwlArpnzEAPhJ5jx24UVeFyIRMbYTRuH783ebAafNcnMxtIoAqTMjDpjGp/7Mf # NY8WKb0MZnCZyGr7okEq1vgQZPQQW1+oYKs48Pk7u4/BJ2PVqmBeqjsdy3HuFyzm # qOnCMIIGcTCCBFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDEL # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWlj # cm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAx # MjEzNjU1WhcNMjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg # MjAxMDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8 # E5f1+n9plGt0VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3O # CROOfGEwWbEwRA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJY # YEbyWEeGMoQedGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIa # IYqvS2SJUGKxXf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo # 8noqCjHw2k4GkbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhac # AQVPIk0CAwEAAaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTV # YzpcijGQ80N7fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+ii # XGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jv # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0y # My5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNy # dDCBoAYDVR0gAQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEW # MWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5o # dG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBT # AHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbg # mD+BcQM9naOhIW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzt # a1RXCCtRgkQS+7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/y # N31aPxzymXlKkVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8 # tv0E4XCfMkon/VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpx # Y517IW3DnKOiPPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4 # ILUl5WTs9/S/fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/Dh # O3EJ3110mCIIYdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJ # rDm77MbL2IK0cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXA # L1QnIffIrE7aKLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8ch # r1m1rtxEPJdQcdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQ # NdrvCScc1bN+NR4Iuto229Nfj950iEkSoYIC1DCCAj0CAQEwggEAoYHYpIHVMIHS # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRN # aWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRo # YWxlcyBUU1MgRVNOOjE3OUUtNEJCMC04MjQ2MSUwIwYDVQQDExxNaWNyb3NvZnQg # VGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQAdS3R6Wd5o8ttrXop7 # rdFHcHrk5qCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n # dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y # YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0G # CSqGSIb3DQEBBQUAAgUA5OmMJjAiGA8yMDIxMDkxMzE2MzY1NFoYDzIwMjEwOTE0 # MTYzNjU0WjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDk6YwmAgEAMAcCAQACAg14 # MAcCAQACAhMzMAoCBQDk6t2mAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQB # hFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEA # IiOC64czzyFgyYkbE54h+O6QJLBL5N2uPgKIBnTNKH+zQKPmaQYT/tWUPXY2Akgo # 736CeY1xz9iJTdTRTG2V+74sHRrf47LqlLZwQw65iKJyzwOVq19wozritEMRC44l # wfWI0REWvV9ZCsFSM+gmyoasobjoT0z2VvlD83D72vwxggMNMIIDCQIBATCBkzB8 # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N # aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAATyL/bmzP0eX/QAAAAAB # PDANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE # MC8GCSqGSIb3DQEJBDEiBCDh4Yrxu9+FBJPOWuUTdDilcH8gXj0lP2w1cT0teP3a # YjCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIKBJArpNJL/A5zqpt9R8Ea/t # iGw98ZiFuBUhiuEm6FpGMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTACEzMAAAE8i/25sz9Hl/0AAAAAATwwIgQg+49aU97v+05TIG0l1ugGPkYg # AAZmwIPT6GU+2Y7ytOUwDQYJKoZIhvcNAQELBQAEggEAUFZLIoWT13nqsXnTQt7U # HNb5veqwTLCTSV6sJTzy+gWDnOFvqCXnDumvl3x1iyIrGrH+/UA1SEN0a2BWLfKG # 5B5WHSUwveMHmMxWYQBSS1lML3huXzDRM8kmQ3QuhL2g2Lq6heSyXByNL1EO3sEH # 14LAtaP+07ljq85cWifybFnAsCOnb5tNXZ/Bz2iOn4oJ7cnBKK7vew4Yk0J86fnT # vtJaJrrfPHFuPlMSiMbpQxAVwELavbVvRC2XtxmNJgrSR1JIeL6SO9xxXy3h/aR5 # rPeDQpM4NufxAPReVDefOsURjQx477Mi/k3BcYHxnCHVW+MXW/FI4mamQ6ab5WuH # 7w== # SIG # End signature block |