Skip to content

Commit

Permalink
Add foundations for Windows FIPS flavor (#31466)
Browse files Browse the repository at this point in the history
  • Loading branch information
clarkb7 authored Dec 4, 2024
1 parent 30859e8 commit de9798b
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 29 deletions.
14 changes: 14 additions & 0 deletions .gitlab/package_build/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
-e PIP_INDEX_URL=${PIP_INDEX_URL}
-e API_KEY_ORG2=${API_KEY_ORG2}
-e OMNIBUS_GIT_CACHE_DIR=${Env:TEMP}/${CI_PIPELINE_ID}/omnibus-git-cache
-e AGENT_FLAVOR=${AGENT_FLAVOR}
registry.ddbuild.io/ci/datadog-agent-buildimages/windows_1809_${ARCH}${Env:DATADOG_AGENT_WINBUILDIMAGES_SUFFIX}:${Env:DATADOG_AGENT_WINBUILDIMAGES}
c:\mnt\tasks\winbuildscripts\buildwin.bat
- If ($lastExitCode -ne "0") { throw "Previous command returned $lastExitCode" }
Expand Down Expand Up @@ -65,6 +66,19 @@ windows_msi_and_bosh_zip_x64-a7:
- set RELEASE_VERSION $RELEASE_VERSION_7
timeout: 2h

windows_msi_and_bosh_zip_x64-a7-fips:
extends: .windows_main_agent_base
rules:
- !reference [.except_mergequeue]
- when: on_success
variables:
ARCH: "x64"
AGENT_FLAVOR: fips
before_script:
- set RELEASE_VERSION $RELEASE_VERSION_7
timeout: 2h


# cloudfoundry IoT build for Windows
windows_zip_agent_binaries_x64-a7:
stage: package_build
Expand Down
22 changes: 17 additions & 5 deletions omnibus/config/software/datadog-agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@

# set GOPATH on the omnibus source dir for this software
gopath = Pathname.new(project_dir) + '../../../..'
msgoroot = "/usr/local/msgo"
flavor_arg = ENV['AGENT_FLAVOR']
fips_args = fips_mode? ? "--fips-mode" : ""
if windows_target?
Expand Down Expand Up @@ -62,9 +61,22 @@
env = with_standard_compiler_flags(with_embedded_path(env))

# Use msgo toolchain when fips mode is enabled
if fips_mode? && !windows_target?
env["GOROOT"] = msgoroot
env["PATH"] = "#{msgoroot}/bin:#{env['PATH']}"
if fips_mode?
if windows_target?
msgoroot = ENV['MSGO_ROOT']
if msgoroot.nil? || msgoroot.empty?
raise "MSGO_ROOT not set"
end
if !File.exist?("#{msgoroot}\\bin\\go.exe")
raise "msgo go.exe not found at #{msgoroot}\\bin\\go.exe"
end
env["GOROOT"] = msgoroot
env["PATH"] = "#{msgoroot}\\bin;#{env['PATH']}"
else
msgoroot = "/usr/local/msgo"
env["GOROOT"] = msgoroot
env["PATH"] = "#{msgoroot}/bin:#{env['PATH']}"
end
end

# we assume the go deps are already installed before running omnibus
Expand Down Expand Up @@ -141,7 +153,7 @@
# System-probe
if sysprobe_enabled? || (windows_target? && do_windows_sysprobe != "")
if windows_target?
command "invoke -e system-probe.build", env: env
command "invoke -e system-probe.build #{fips_args}", env: env
elsif linux_target?
command "invoke -e system-probe.build-sysprobe-binary #{fips_args} --install-path=#{install_dir}", env: env
end
Expand Down
1 change: 1 addition & 0 deletions tasks/build_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"zlib",
"zstd",
"test", # used for unit-tests
"goexperiment.systemcrypto", # used for FIPS mode
}

### Tag inclusion lists
Expand Down
19 changes: 16 additions & 3 deletions tasks/msi.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,17 @@ def _get_env(ctx, major_version='7', release_version='nightly'):
env['PACKAGE_VERSION'] = get_version(
ctx, include_git=True, url_safe=True, major_version=major_version, include_pipeline_id=True
)
env['AGENT_INSTALLER_OUTPUT_DIR'] = f'{BUILD_OUTPUT_DIR}'
env['NUGET_PACKAGES_DIR'] = f'{NUGET_PACKAGES_DIR}'
env['AGENT_FLAVOR'] = os.getenv("AGENT_FLAVOR", "")
env['AGENT_INSTALLER_OUTPUT_DIR'] = BUILD_OUTPUT_DIR
env['NUGET_PACKAGES_DIR'] = NUGET_PACKAGES_DIR

return env


def _is_fips_mode(env):
return env['AGENT_FLAVOR'] == "fips"


def _msbuild_configuration(debug=False):
return "Debug" if debug else "Release"

Expand Down Expand Up @@ -264,6 +270,13 @@ def _build_msi(ctx, env, outdir, name, allowlist):
sign_file(ctx, out_file)


def _msi_output_name(env):
if _is_fips_mode(env):
return f"datadog-fips-agent-{env['PACKAGE_VERSION']}-1-x86_64"
else:
return f"datadog-agent-{env['PACKAGE_VERSION']}-1-x86_64"


@task
def build(ctx, vstudio_root=None, arch="x64", major_version='7', release_version='nightly', debug=False):
"""
Expand Down Expand Up @@ -301,7 +314,7 @@ def build(ctx, vstudio_root=None, arch="x64", major_version='7', release_version

# Run WiX to turn the WXS into an MSI
with timed("Building MSI"):
msi_name = f"datadog-agent-{env['PACKAGE_VERSION']}-1-x86_64"
msi_name = _msi_output_name(env)
_build_msi(ctx, env, build_outdir, msi_name, DATADOG_AGENT_MSI_ALLOW_LIST)

# And copy it to the final output path as a build artifact
Expand Down
14 changes: 14 additions & 0 deletions tasks/omnibus.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from tasks.flavor import AgentFlavor
from tasks.go import deps
from tasks.libs.common.check_tools_version import expected_go_repo_v
from tasks.libs.common.omnibus import (
install_dir_for_project,
omnibus_compute_cache_key,
Expand Down Expand Up @@ -136,6 +137,19 @@ def get_omnibus_env(

if fips_mode:
env['FIPS_MODE'] = 'true'
if sys.platform == 'win32' and not os.environ.get('MSGO_ROOT'):
# Point omnibus at the msgo root
# TODO: idk how to do this in omnibus datadog-agent.rb
# because `File.read` is executed when the script is loaded,
# not when the `command`s are run and the source tree is not
# available at that time.
# Comments from the Linux FIPS PR discussed wanting to centralize
# the msgo root logic, so this can be updated then.
go_version = expected_go_repo_v()
env['MSGO_ROOT'] = f'C:\\msgo\\{go_version}\\go'
gobinpath = f"{env['MSGO_ROOT']}\\bin\\go.exe"
if not os.path.exists(gobinpath):
raise Exit(f"msgo go.exe not found at {gobinpath}")

# We need to override the workers variable in omnibus build when running on Kubernetes runners,
# otherwise, ohai detect the number of CPU on the host and run the make jobs with all the CPU.
Expand Down
2 changes: 2 additions & 0 deletions tasks/system_probe.py
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ def build(
with_unit_test=False,
ebpf_compiler='clang',
static=False,
fips_mode=False,
):
"""
Build the system-probe
Expand All @@ -714,6 +715,7 @@ def build(
strip_binary=strip_binary,
arch=arch,
static=static,
fips_mode=fips_mode,
)


Expand Down
25 changes: 13 additions & 12 deletions tasks/winbuildscripts/dobuild.bat
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ if "%OMNIBUS_TARGET%" == "" set OMNIBUS_TARGET=main
if "%OMNIBUS_TARGET%" == "iot" set OMNIBUS_ARGS=--flavor iot
if "%OMNIBUS_TARGET%" == "dogstatsd" set OMNIBUS_ARGS=--target-project dogstatsd
if "%OMNIBUS_TARGET%" == "agent_binaries" set OMNIBUS_ARGS=%OMNIBUS_ARGS% --target-project agent-binaries
if "%AGENT_FLAVOR%" == "fips" set OMNIBUS_ARGS=--flavor fips

if DEFINED GOMODCACHE set OMNIBUS_ARGS=%OMNIBUS_ARGS% --go-mod-cache %GOMODCACHE%
if DEFINED USE_S3_CACHING set OMNIBUS_ARGS=%OMNIBUS_ARGS% %USE_S3_CACHING%

SET PATH=%PATH%;%GOPATH%/bin
set REPO_ROOT=%~p0\..\..
pushd .
cd %REPO_ROOT% || exit /b 100

SET PATH=%PATH%;%GOPATH%\bin

@echo GOPATH %GOPATH%
@echo PATH %PATH%
Expand All @@ -32,25 +37,21 @@ if "%TARGET_ARCH%" == "x64" (
call ridk enable
)

set REPO_ROOT=%~p0\..\..
pushd .
cd %REPO_ROOT% || exit /b 101


pip3 install -r requirements.txt || exit /b 102
pip3 install -r requirements.txt || exit /b 120

inv -e deps || exit /b 103
inv -e deps || exit /b 130
if "%GO_VERSION_CHECK%" == "true" (
inv -e check-go-version || exit /b 104
inv -e check-go-version || exit /b 140
)

@echo "inv -e %OMNIBUS_BUILD% %OMNIBUS_ARGS% --skip-deps --major-version %MAJOR_VERSION% --release-version %RELEASE_VERSION%"
inv -e %OMNIBUS_BUILD% %OMNIBUS_ARGS% --skip-deps --major-version %MAJOR_VERSION% --release-version %RELEASE_VERSION% || exit /b 105
@echo "inv -e %OMNIBUS_BUILD% %OMNIBUS_ARGS% --skip-deps --release-version %RELEASE_VERSION%"
inv -e %OMNIBUS_BUILD% %OMNIBUS_ARGS% --skip-deps --release-version %RELEASE_VERSION% || exit /b 150

REM only build MSI for main targets for now.
if "%OMNIBUS_TARGET%" == "main" (
@echo "inv -e msi.build --major-version %MAJOR_VERSION% --release-version %RELEASE_VERSION%
inv -e msi.build --major-version %MAJOR_VERSION% --release-version %RELEASE_VERSION% || exit /b 106
@echo "inv -e msi.build --release-version %RELEASE_VERSION%
inv -e msi.build --release-version %RELEASE_VERSION% || exit /b 160
)

REM Build the OCI package for the Agent 7 only.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System;

namespace WixSetup.Datadog_Agent
{
internal static class AgentFlavorFactory
{
public static IAgentFlavor New(AgentVersion agentVersion)
{
var flavor = Environment.GetEnvironmentVariable("AGENT_FLAVOR");

return flavor switch
{
"fips" => new FIPSAgent(agentVersion),
"base" => new BaseAgent(agentVersion),
_ => new BaseAgent(agentVersion) // Default to BaseAgent if no valid value is provided
};
}
}

internal interface IAgentFlavor
{
string ProductFullName { get; }
Guid UpgradeCode { get; }
string ProductDescription { get; }
string PackageOutFileName { get; }
}

internal class FIPSAgent : IAgentFlavor
{
private readonly AgentVersion _agentVersion;

public FIPSAgent(AgentVersion agentVersion)
{
_agentVersion = agentVersion;
}

public string ProductFullName => "Datadog FIPS Agent";
public Guid UpgradeCode => new("de421174-9615-4fe9-b8a8-2b3f123bdc4f");
public string ProductDescription => $"Datadog FIPS Agent {_agentVersion.PackageVersion}";
public string PackageOutFileName => $"datadog-fips-agent-{_agentVersion.PackageVersion}-1-x86_64";
}

internal class BaseAgent : IAgentFlavor
{
private readonly AgentVersion _agentVersion;

public BaseAgent(AgentVersion agentVersion)
{
_agentVersion = agentVersion;
}

public string ProductFullName => "Datadog Agent";
public Guid UpgradeCode => new("0c50421b-aefb-4f15-a809-7af256d608a5");
public string ProductDescription => $"Datadog Agent {_agentVersion.PackageVersion}";
public string PackageOutFileName => $"datadog-agent-{_agentVersion.PackageVersion}-1-x86_64";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,12 @@ public class AgentInstaller : IWixProjectEvents, IMsiInstallerProject
private const string CompanyFullName = "Datadog, Inc.";

// Product
private const string ProductFullName = "Datadog Agent";
private const string ProductDescription = "Datadog Agent {0}";
private const string ProductHelpUrl = @"https://help.datadoghq.com/hc/en-us";
private const string ProductAboutUrl = @"https://www.datadoghq.com/about/";
private const string ProductComment = @"Copyright 2015 - Present Datadog";
private const string ProductContact = @"https://www.datadoghq.com/about/contact/";

// same value for all versions; must not be changed
private static readonly Guid ProductUpgradeCode = new("0c50421b-aefb-4f15-a809-7af256d608a5");
private static readonly string ProductLicenceRtfFilePath = Path.Combine("assets", "LICENSE.rtf");
private static readonly string ProductIconFilePath = Path.Combine("assets", "project.ico");
private static readonly string InstallerBackgroundImagePath = Path.Combine("assets", "dialog_background.bmp");
Expand All @@ -40,6 +37,7 @@ public class AgentInstaller : IWixProjectEvents, IMsiInstallerProject
private readonly AgentVersion _agentVersion;
private readonly AgentCustomActions _agentCustomActions = new();
private readonly AgentInstallerUI _agentInstallerUi;
private readonly IAgentFlavor _agentFlavor;

public AgentInstaller()
: this(null)
Expand All @@ -60,11 +58,13 @@ public AgentInstaller(string version)

_agentBinaries = new AgentBinaries(BinSource, InstallerSource);
_agentInstallerUi = new AgentInstallerUI(this, _agentCustomActions);
_agentFlavor = AgentFlavorFactory.New(_agentVersion);
}

public Project Configure()
{
var project = new ManagedProject("Datadog Agent",

var project = new ManagedProject(_agentFlavor.ProductFullName,
// Use 2 LaunchConditions, one for server versions,
// one for client versions.
MinimumSupportedWindowsVersion.WindowsServer2016 |
Expand Down Expand Up @@ -145,9 +145,9 @@ public Project Configure()
project
.SetCustomActions(_agentCustomActions)
.SetProjectInfo(
upgradeCode: ProductUpgradeCode,
name: ProductFullName,
description: string.Format(ProductDescription, _agentVersion.Version),
upgradeCode: _agentFlavor.UpgradeCode,
name: _agentFlavor.ProductFullName,
description: _agentFlavor.ProductDescription,
// This version is overridden below because SetProjectInfo throws an Exception if Revision is != 0
version: new Version(
_agentVersion.Version.Major,
Expand All @@ -156,7 +156,7 @@ public Project Configure()
0)
)
.SetControlPanelInfo(
name: ProductFullName,
name: _agentFlavor.ProductFullName,
manufacturer: CompanyFullName,
readme: ProductHelpUrl,
comment: ProductComment,
Expand Down Expand Up @@ -220,7 +220,7 @@ public Project Configure()
// Set custom output directory (WixSharp defaults to current directory)
project.OutDir = Environment.GetEnvironmentVariable("AGENT_MSI_OUTDIR");
}
project.OutFileName = $"datadog-agent-{_agentVersion.PackageVersion}-1-x86_64";
project.OutFileName = _agentFlavor.PackageOutFileName;
project.Package.AttributesDefinition = $"Comments={ProductComment}";

// clear default media as we will add it via MediaTemplate
Expand Down

0 comments on commit de9798b

Please sign in to comment.