diff --git a/.github/actions/spelling/expect/expect.txt b/.github/actions/spelling/expect/expect.txt
index 32c182c8e4..ee8d15ee8f 100644
--- a/.github/actions/spelling/expect/expect.txt
+++ b/.github/actions/spelling/expect/expect.txt
@@ -943,6 +943,7 @@ gset
gsl
GTP
GTR
+guardxfg
guc
gui
guidatom
@@ -1802,6 +1803,7 @@ PNTSTATUS
POBJECT
Podcast
POINTSLIST
+Poli
POLYTEXTW
popd
POPF
@@ -2826,6 +2828,7 @@ xdy
XEncoding
xes
xff
+xfg
XFile
XFORM
XManifest
diff --git a/build/config/PolicheckExclusions.xml b/build/config/PolicheckExclusions.xml
new file mode 100644
index 0000000000..a30447631c
--- /dev/null
+++ b/build/config/PolicheckExclusions.xml
@@ -0,0 +1,11 @@
+
+
+
+ winrt|.git|oss|packages
+
+
+
+ .PNG|.SVG|.BMP|.ICO
+
+
+
\ No newline at end of file
diff --git a/build/pipelines/release.yml b/build/pipelines/release.yml
index 3dd772210b..1bcf0c601b 100644
--- a/build/pipelines/release.yml
+++ b/build/pipelines/release.yml
@@ -18,6 +18,10 @@ parameters:
displayName: "Build Windows Terminal MSIX"
type: boolean
default: true
+ - name: runCompliance
+ displayName: "Run Compliance and Security Build"
+ type: boolean
+ default: true
- name: buildTerminalVPack
displayName: "Build Windows Terminal VPack"
type: boolean
@@ -34,7 +38,6 @@ parameters:
- Optimize
- Instrument
- None
-
- name: buildConfigurations
type: object
default:
@@ -65,11 +68,11 @@ jobs:
BuildConfiguration: ${{ config }}
BuildPlatform: ${{ platform }}
displayName: Build
+ timeoutInMinutes: 240
cancelTimeoutInMinutes: 1
steps:
- checkout: self
clean: true
- fetchDepth: 1
submodules: true
persistCredentials: True
- task: PkgESSetupBuild@12
@@ -90,6 +93,7 @@ jobs:
displayName: Use NuGet 5.10
inputs:
versionSpec: 5.10
+ - task: NuGetAuthenticate@0
# In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
# This should be `task: NuGetCommand@2`
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
@@ -156,6 +160,7 @@ jobs:
- ${{ if eq(parameters.buildTerminal, true) }}:
- task: VSBuild@1
displayName: Build solution **\OpenConsole.sln
+ condition: true
inputs:
solution: '**\OpenConsole.sln'
vsVersion: 16.0
@@ -196,8 +201,6 @@ jobs:
filePath: build\scripts\Index-Pdbs.ps1
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
errorActionPreference: silentlyContinue
- - task: ComponentGovernanceComponentDetection@0
- displayName: Component Detection
- task: PowerShell@2
displayName: Run Unit Tests
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
@@ -254,6 +257,7 @@ jobs:
inputs:
PathtoPublish: $(Build.ArtifactStagingDirectory)/wpf
ArtifactName: wpf-dll-$(BuildPlatform)-$(BuildConfiguration)
+
- task: PublishSymbols@2
displayName: Publish symbols path
continueOnError: True
@@ -265,6 +269,9 @@ jobs:
IndexSources: false
SymbolServerType: TeamServices
+- ${{ if eq(parameters.runCompliance, true) }}:
+ - template: ./templates/build-console-compliance-job.yml
+
- ${{ if eq(parameters.buildTerminal, true) }}:
- job: BundleAndSign
displayName: Create and sign AppX/MSIX bundles
diff --git a/build/pipelines/templates/build-console-compliance-job.yml b/build/pipelines/templates/build-console-compliance-job.yml
new file mode 100644
index 0000000000..ea42382193
--- /dev/null
+++ b/build/pipelines/templates/build-console-compliance-job.yml
@@ -0,0 +1,224 @@
+jobs:
+- job: Compliance
+ # We don't *need* a matrix but there's no other way to set parameters on a "job"
+ # in the AzDO YAML syntax. It would have to be a "stage" or a "template".
+ # Doesn't matter. We're going to do compliance on Release x64 because
+ # that's the one all the tooling works against for sure.
+ strategy:
+ matrix:
+ Release_x64:
+ BuildConfiguration: Release
+ BuildPlatform: x64
+ displayName: Validate Security and Compliance
+ timeoutInMinutes: 240
+ steps:
+ - checkout: self
+ clean: true
+ submodules: true
+ persistCredentials: True
+ - task: PkgESSetupBuild@12
+ displayName: Package ES - Setup Build
+ inputs:
+ disableOutputRedirect: true
+ - task: PowerShell@2
+ displayName: Rationalize Build Platform
+ inputs:
+ targetType: inline
+ script: >-
+ $Arch = "$(BuildPlatform)"
+
+ If ($Arch -Eq "x86") { $Arch = "Win32" }
+
+ Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
+ - task: NuGetToolInstaller@1
+ displayName: Use NuGet 5.10
+ inputs:
+ versionSpec: 5.10
+ - task: NuGetAuthenticate@0
+ # In the Microsoft Azure DevOps tenant, NuGetCommand is ambiguous.
+ # This should be `task: NuGetCommand@2`
+ - task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
+ displayName: Restore NuGet packages for extraneous build actions
+ inputs:
+ command: restore
+ feedsToUse: config
+ configPath: NuGet.config
+ restoreSolution: build/packages.config
+ restoreDirectory: '$(Build.SourcesDirectory)\packages'
+ - task: NuGetCommand@2
+ displayName: NuGet custom
+ inputs:
+ command: custom
+ selectOrConfig: config
+ nugetConfigPath: NuGet.Config
+ arguments: restore OpenConsole.sln -SolutionDirectory $(Build.SourcesDirectory)
+ - task: UniversalPackages@0
+ displayName: Download terminal-internal Universal Package
+ inputs:
+ feedListDownload: 2b3f8893-a6e8-411f-b197-a9e05576da48
+ packageListDownload: e82d490c-af86-4733-9dc4-07b772033204
+ versionListDownload: $(TerminalInternalPackageVersion)
+ - task: TouchdownBuildTask@1
+ displayName: Download Localization Files
+ inputs:
+ teamId: 7105
+ authId: $(TouchdownAppId)
+ authKey: $(TouchdownAppKey)
+ resourceFilePath: >-
+ src\cascadia\TerminalApp\Resources\en-US\Resources.resw
+
+ src\cascadia\TerminalControl\Resources\en-US\Resources.resw
+
+ src\cascadia\TerminalConnection\Resources\en-US\Resources.resw
+
+ src\cascadia\TerminalSettingsModel\Resources\en-US\Resources.resw
+
+ src\cascadia\TerminalSettingsEditor\Resources\en-US\Resources.resw
+
+ src\cascadia\WindowsTerminalUniversal\Resources\en-US\Resources.resw
+
+ src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw
+ appendRelativeDir: true
+ localizationTarget: false
+ pseudoSetting: Included
+ - task: PowerShell@2
+ displayName: Move Loc files one level up
+ inputs:
+ targetType: inline
+ script: >-
+ $Files = Get-ChildItem . -R -Filter 'Resources.resw' | ? FullName -Like '*en-US\*\Resources.resw'
+
+ $Files | % { Move-Item -Verbose $_.Directory $_.Directory.Parent.Parent -EA:Ignore }
+ pwsh: true
+
+ # 1ES Component Governance onboarding (Detects open source components). See https://docs.opensource.microsoft.com/tools/cg.html
+ - task: ms.vss-governance-buildtask.governance-build-task-component-detection.ComponentGovernanceComponentDetection@0
+ displayName: Component Detection
+
+ # # PREfast and PoliCheck need Node. Install that first.
+ - task: NodeTool@0
+
+ # !!! NOTE !!! Run PREfast first. Some of the other tasks are going to run on a completed build.
+ # PREfast is going to build the code as a part of its analysis and the generated sources
+ # and output binaries will be sufficient for the rest of the analysis.
+ # If you disable this, the other tasks won't likely work. You would have to add a build
+ # step instead that builds the code normally before calling them.
+ # Also... PREfast will rebuild anyway so that's why we're not running a normal build first.
+ # Waste of time to build twice.
+ # PREfast. See https://www.1eswiki.com/wiki/SDL_Native_Rules_Build_Task
+
+ # The following 1ES tasks all operate completely differently and have a different syntax for usage.
+ # Most notable is every one of them has a different way of excluding things.
+ # Go see their 1eswiki.com pages to figure out how to exclude things.
+ # When writing exclusions, try to make them narrow so when new projects/binaries are added, they
+ # cause an error here and have to be explicitly pulled out. Don't write an exclusion so broad
+ # that it will catch other new stuff.
+
+ # https://www.1eswiki.com/wiki/PREfast_Build_Task
+ # Builds the project with C/C++ static analysis tools to find coding flaws and vulnerabilities
+ # !!! WARNING !!! It doesn't work with WAPPROJ packaging projects. Build the sub-projects instead.
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-prefast.SDLNativeRules@3
+ displayName: 'Run the PREfast SDL Native Rules for MSBuild'
+ condition: succeededOrFailed()
+ inputs:
+ msBuildCommandline: msbuild.exe /nologo /m /p:WindowsTerminalOfficialBuild=true /p:WindowsTerminalBranding=${{ parameters.branding }} /p:WindowsTerminalReleaseBuild=true /p:platform=$(BuildPlatform) /p:configuration=$(BuildConfiguration) /t:Terminal\Window\WindowsTerminal /p:VisualStudioVersion=16.0 $(Build.SourcesDirectory)\OpenConsole.sln
+
+ # Copies output from PREfast SDL Native Rules task to expected location for consumption by PkgESSecComp
+ - task: CopyFiles@1
+ displayName: 'Copy PREfast xml files to SDLNativeRulesDir'
+ inputs:
+ SourceFolder: '$(Agent.BuildDirectory)'
+ Contents: |
+ **\*.nativecodeanalysis.xml
+ TargetFolder: '$(Agent.BuildDirectory)\_sdt\logs\SDLNativeRules'
+
+ # https://www.1eswiki.com/index.php?title=PoliCheck_Build_Task
+ # Scans the text of source code, comments, and content for terminology that could be sensitive for legal, cultural, or geopolitical reasons.
+ # (Also finds vulgarities... takes all the fun out of everything.)
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-policheck.PoliCheck@2
+ displayName: 'Run PoliCheck'
+ inputs:
+ targetType: F
+ targetArgument: $(Build.SourcesDirectory)
+ result: PoliCheck.xml
+ optionsFC: 1
+ optionsXS: 1
+ optionsUEPath: $(Build.SourcesDirectory)\build\config\PolicheckExclusions.xml
+ optionsHMENABLE: 0
+ continueOnError: true
+
+ # https://www.1eswiki.com/wiki/CredScan_Azure_DevOps_Build_Task
+ # Searches through source code and build outputs for a credential left behind in the open
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-credscan.CredScan@3
+ displayName: 'Run CredScan'
+ inputs:
+ outputFormat: pre
+ # suppressionsFile: LocalSuppressions.json
+ batchSize: 20
+ debugMode: false
+ continueOnError: true
+
+ # https://www.1eswiki.com/wiki/BinSkim_Build_Task
+ # Searches managed and unmanaged binaries for known security vulnerabilities.
+ - task: securedevelopmentteam.vss-secure-development-tools.build-task-binskim.BinSkim@4
+ displayName: 'Run BinSkim'
+ inputs:
+ TargetPattern: guardianGlob
+ # See https://aka.ms/gdn-globs for how to do match patterns
+ AnalyzeTargetGlob: $(Build.SourcesDirectory)\bin\**\*.dll;$(Build.SourcesDirectory)\bin\**\*.exe;-:file|**\Microsoft.UI.Xaml.dll;-:file|**\Microsoft.Toolkit.Win32.UI.XamlHost.dll;-:file|**\vcruntime*.dll;-:file|**\vcomp*.dll;-:file|**\vccorlib*.dll;-:file|**\vcamp*.dll;-:file|**\msvcp*.dll;-:file|**\concrt*.dll;-:file|**\TerminalThemeHelpers*.dll;-:file|**\cpprest*.dll
+ continueOnError: true
+
+ # Set XES_SERIALPOSTBUILDREADY to run Security and Compliance task once per build
+ - powershell: Write-Host “##vso[task.setvariable variable=XES_SERIALPOSTBUILDREADY;]true”
+ displayName: 'Set XES_SERIALPOSTBUILDREADY Vars'
+
+ # https://www.osgwiki.com/wiki/Package_ES_Security_and_Compliance
+ # Does a few things:
+ # - Ensures that Windows-required compliance tasks are run either inside this task
+ # or were run as a previous step prior to this one
+ # (PREfast, PoliCheck, Credscan)
+ # - Runs Windows-specific compliance tasks inside the task
+ # + CheckCFlags - ensures that compiler and linker flags meet Windows standards
+ # + CFGCheck/XFGCheck - ensures that Control Flow Guard (CFG) or
+ # eXtended Flow Guard (XFG) are enabled on binaries
+ # NOTE: CFG is deprecated and XFG isn't fully ready yet.
+ # NOTE2: CFG fails on an XFG'd binary
+ # - Brokers all security/compliance task logs to "Trust Services Automation (TSA)" (https://aka.ms/tsa)
+ # which is a system that maps all errors into the appropriate bug database
+ # template for each organization since they all vary. It should also suppress
+ # new bugs when one already exists for the product.
+ # This one is set up to go to the OS repository and use the given parameters
+ # to file bugs to our AzDO product path.
+ # If we don't use PkgESSecComp to do this for us, we need to install the TSA task
+ # ourselves in this pipeline to finalize data upload and bug creation.
+ # !!! NOTE !!! This task goes *LAST* after any other compliance tasks so it catches their logs
+ - task: PkgESSecComp@10
+ displayName: 'Security and Compliance tasks'
+ inputs:
+ fileNewBugs: false
+ areaPath: 'OS\WDX\DXP\WinDev\Terminal'
+ teamProject: 'OS'
+ iterationPath: 'OS\Future'
+ bugTags: 'TerminalReleaseCompliance'
+ scanAll: true
+ errOnBugs: false
+ failOnStdErr: true
+ taskLogVerbosity: Diagnostic
+ secCompConfigFromTask: |
+ # Overrides default build sources directory
+ sourceTargetOverrideAll: $(Build.SourcesDirectory)
+ # Overrides default build binaries directory when "Scan all" option is specified
+ binariesTargetOverrideAll: $(Build.SourcesDirectory)\bin
+
+ # Set the tools to false if they should not run in the build
+ tools:
+ - toolName: CheckCFlags
+ enable: true
+ - toolName: CFGCheck
+ enable: true
+ - toolName: Policheck
+ enable: false
+ - toolName: CredScan
+ enable: false
+ - toolName: XFGCheck
+ enable: false
\ No newline at end of file
diff --git a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
index 5c6d91a4d8..96ecaa9ac5 100644
--- a/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
+++ b/src/cascadia/TerminalSettingsModel/CascadiaSettings.cpp
@@ -219,6 +219,18 @@ Model::Profile CascadiaSettings::CreateNewProfile()
return *newProfile;
}
+template
+static bool isProfilesDefaultsOrigin(const T& profile)
+{
+ return profile && profile.Origin() != winrt::Microsoft::Terminal::Settings::Model::OriginTag::ProfilesDefaults;
+}
+
+template
+static bool isProfilesDefaultsOriginSub(const T& sub)
+{
+ return sub && isProfilesDefaultsOrigin(sub.SourceProfile());
+}
+
// Method Description:
// - Duplicate a new profile based off another profile's settings
// - This differs from Profile::Copy because it also copies over settings
@@ -250,14 +262,6 @@ Model::Profile CascadiaSettings::DuplicateProfile(const Model::Profile& source)
const auto duplicated = _createNewProfile(newName);
- static constexpr auto isProfilesDefaultsOrigin = [](const auto& profile) -> bool {
- return profile && profile.Origin() != OriginTag::ProfilesDefaults;
- };
-
- static constexpr auto isProfilesDefaultsOriginSub = [](const auto& sub) -> bool {
- return sub && isProfilesDefaultsOrigin(sub.SourceProfile());
- };
-
#define NEEDS_DUPLICATION(settingName) source.Has##settingName() || isProfilesDefaultsOrigin(source.settingName##OverrideSource())
#define NEEDS_DUPLICATION_SUB(source, settingName) source.Has##settingName() || isProfilesDefaultsOriginSub(source.settingName##OverrideSource())
diff --git a/src/common.build.pre.props b/src/common.build.pre.props
index fa65813ee6..30d7fb285f 100644
--- a/src/common.build.pre.props
+++ b/src/common.build.pre.props
@@ -168,6 +168,7 @@
true
NDEBUG;%(PreprocessorDefinitions)
false
+ %(AdditionalOptions)
true