diff --git a/internal/distro/fedora/distro.go b/internal/distro/fedora/distro.go index 3d739b6e6..56affff1d 100644 --- a/internal/distro/fedora/distro.go +++ b/internal/distro/fedora/distro.go @@ -14,6 +14,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/environment" "github.com/osbuild/osbuild-composer/internal/image" "github.com/osbuild/osbuild-composer/internal/manifest" + "github.com/osbuild/osbuild-composer/internal/oscap" "github.com/osbuild/osbuild-composer/internal/platform" "github.com/osbuild/osbuild-composer/internal/rpmmd" "github.com/osbuild/osbuild-composer/internal/runner" @@ -49,6 +50,12 @@ var ( "/", "/var", "/opt", "/srv", "/usr", "/app", "/data", "/home", "/tmp", } + oscapProfileAllowList = []oscap.Profile{ + oscap.Ospp, + oscap.PciDss, + oscap.Standard, + } + // Services iotServices = []string{ "NetworkManager.service", @@ -704,6 +711,22 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio return fmt.Errorf("The following custom mountpoints are not supported %+q", invalidMountpoints) } + if osc := customizations.GetOpenSCAP(); osc != nil { + supported := oscap.IsProfileAllowed(osc.ProfileID, oscapProfileAllowList) + if !supported { + return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported profile: %s", osc.ProfileID)) + } + if t.rpmOstree { + return fmt.Errorf("OpenSCAP customizations are not supported for ostree types") + } + if osc.DataStream == "" { + return fmt.Errorf("OpenSCAP datastream cannot be empty") + } + if osc.ProfileID == "" { + return fmt.Errorf("OpenSCAP profile cannot be empty") + } + } + return nil } diff --git a/internal/distro/rhel7/distro.go b/internal/distro/rhel7/distro.go index 17ded1f02..00726e639 100644 --- a/internal/distro/rhel7/distro.go +++ b/internal/distro/rhel7/distro.go @@ -448,6 +448,10 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio return fmt.Errorf("The following custom mountpoints are not supported %+q", invalidMountpoints) } + if osc := customizations.GetOpenSCAP(); osc != nil { + return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported os version: %s", t.arch.distro.osVersion)) + } + return nil } diff --git a/internal/distro/rhel8/distro.go b/internal/distro/rhel8/distro.go index 39971dd4d..a21e0838c 100644 --- a/internal/distro/rhel8/distro.go +++ b/internal/distro/rhel8/distro.go @@ -14,6 +14,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/distro" "github.com/osbuild/osbuild-composer/internal/osbuild" + "github.com/osbuild/osbuild-composer/internal/oscap" "github.com/osbuild/osbuild-composer/internal/ostree" "github.com/osbuild/osbuild-composer/internal/rpmmd" ) @@ -67,9 +68,31 @@ const ( blueprintPkgsKey = "blueprint" ) -var mountpointAllowList = []string{ - "/", "/var", "/opt", "/srv", "/usr", "/app", "/data", "/home", "/tmp", -} +var ( + mountpointAllowList = []string{ + "/", "/var", "/opt", "/srv", "/usr", "/app", "/data", "/home", "/tmp", + } + + // rhel8 allow all + oscapProfileAllowList = []oscap.Profile{ + oscap.AnssiBp28Enhanced, + oscap.AnssiBp28High, + oscap.AnssiBp28Intermediary, + oscap.AnssiBp28Minimal, + oscap.Cis, + oscap.CisServerL1, + oscap.CisWorkstationL1, + oscap.CisWorkstationL2, + oscap.Cui, + oscap.E8, + oscap.Hippa, + oscap.IsmO, + oscap.Ospp, + oscap.PciDss, + oscap.Stig, + oscap.StigGui, + } +) type distribution struct { name string @@ -646,6 +669,26 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio return fmt.Errorf("The following custom mountpoints are not supported %+q", invalidMountpoints) } + if osc := customizations.GetOpenSCAP(); osc != nil { + // only add support for RHEL 8.7 and above. centos not supported. + if !t.arch.distro.isRHEL() || versionLessThan(t.arch.distro.osVersion, "8.7") { + return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported os version: %s", t.arch.distro.osVersion)) + } + supported := oscap.IsProfileAllowed(osc.ProfileID, oscapProfileAllowList) + if !supported { + return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported profile: %s", osc.ProfileID)) + } + if t.rpmOstree { + return fmt.Errorf("OpenSCAP customizations are not supported for ostree types") + } + if osc.DataStream == "" { + return fmt.Errorf("OpenSCAP datastream cannot be empty") + } + if osc.ProfileID == "" { + return fmt.Errorf("OpenSCAP profile cannot be empty") + } + } + return nil } diff --git a/internal/distro/rhel90/distro.go b/internal/distro/rhel90/distro.go index f4c60efb3..9784523c8 100644 --- a/internal/distro/rhel90/distro.go +++ b/internal/distro/rhel90/distro.go @@ -14,6 +14,7 @@ import ( "github.com/osbuild/osbuild-composer/internal/disk" "github.com/osbuild/osbuild-composer/internal/distro" "github.com/osbuild/osbuild-composer/internal/osbuild" + "github.com/osbuild/osbuild-composer/internal/oscap" "github.com/osbuild/osbuild-composer/internal/ostree" "github.com/osbuild/osbuild-composer/internal/rpmmd" ) @@ -37,9 +38,33 @@ const ( blueprintPkgsKey = "blueprint" ) -var mountpointAllowList = []string{ - "/", "/var", "/opt", "/srv", "/usr", "/app", "/data", "/home", "/tmp", -} +var ( + mountpointAllowList = []string{ + "/", "/var", "/opt", "/srv", "/usr", "/app", "/data", "/home", "/tmp", + } + + // rhel9 & cs9 share the same list + // of allowed profiles so a single + // allow list can be used + oscapProfileAllowList = []oscap.Profile{ + oscap.AnssiBp28Enhanced, + oscap.AnssiBp28High, + oscap.AnssiBp28Intermediary, + oscap.AnssiBp28Minimal, + oscap.Cis, + oscap.CisServerL1, + oscap.CisWorkstationL1, + oscap.CisWorkstationL2, + oscap.Cui, + oscap.E8, + oscap.Hippa, + oscap.IsmO, + oscap.Ospp, + oscap.PciDss, + oscap.Stig, + oscap.StigGui, + } +) type distribution struct { name string @@ -580,6 +605,24 @@ func (t *imageType) checkOptions(customizations *blueprint.Customizations, optio return fmt.Errorf("The following custom mountpoints are not supported %+q", invalidMountpoints) } + if osc := customizations.GetOpenSCAP(); osc != nil { + if t.arch.distro.osVersion == "9.0" { + return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported os version: %s", t.arch.distro.osVersion)) + } + if !oscap.IsProfileAllowed(osc.ProfileID, oscapProfileAllowList) { + return fmt.Errorf(fmt.Sprintf("OpenSCAP unsupported profile: %s", osc.ProfileID)) + } + if t.rpmOstree { + return fmt.Errorf("OpenSCAP customizations are not supported for ostree types") + } + if osc.DataStream == "" { + return fmt.Errorf("OpenSCAP datastream cannot be empty") + } + if osc.ProfileID == "" { + return fmt.Errorf("OpenSCAP profile cannot be empty") + } + } + return nil }