diff --git a/.families.yaml b/.families.yaml index 54d2a91ef..6e584cca4 100644 --- a/.families.yaml +++ b/.families.yaml @@ -3,9 +3,12 @@ sbom: analyzers_list: - "syft" - "gomod" +# - "windows" inputs: - input: "node:slim" input_type: "image" +# - input: "/mnt" +# input_type: "rootfs" # - input: "nginx:1.10" # input_type: "image" # merge_with: diff --git a/README.md b/README.md index ec30a886f..319f93aa2 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,7 @@ These tools include: - SBOM Generation and Analysis - [Syft](https://github.com/anchore/syft) - [Trivy](https://github.com/aquasecurity/trivy) + - [Windows Registry](cli/analyzer/windows) - Vulnerability detection - [Grype](https://github.com/anchore/grype) - [Trivy](https://github.com/aquasecurity/trivy) diff --git a/api/types/families.go b/api/types/families.go index b540d4def..abf66a2a5 100644 --- a/api/types/families.go +++ b/api/types/families.go @@ -52,7 +52,7 @@ func (c *SBOMConfig) GetAnalyzersList() []string { return *c.Analyzers } - return []string{"syft", "trivy"} + return []string{"syft", "trivy", "windows"} } func (c *RootkitsConfig) IsEnabled() bool { diff --git a/cli/analyzer/job/job.go b/cli/analyzer/job/job.go index cc2efac0e..cbd11ff42 100644 --- a/cli/analyzer/job/job.go +++ b/cli/analyzer/job/job.go @@ -18,6 +18,7 @@ package job import ( "github.com/openclarity/vmclarity/cli/analyzer/syft" "github.com/openclarity/vmclarity/cli/analyzer/trivy" + "github.com/openclarity/vmclarity/cli/analyzer/windows" "github.com/openclarity/vmclarity/cli/job_manager" ) @@ -26,4 +27,5 @@ var Factory = job_manager.NewJobFactory() func init() { Factory.Register(trivy.AnalyzerName, trivy.New) Factory.Register(syft.AnalyzerName, syft.New) + Factory.Register(windows.AnalyzerName, windows.New) } diff --git a/cli/analyzer/windows/registry.go b/cli/analyzer/windows/registry.go new file mode 100644 index 000000000..ea8398250 --- /dev/null +++ b/cli/analyzer/windows/registry.go @@ -0,0 +1,430 @@ +// Copyright © 2024 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package windows + +import ( + "errors" + "fmt" + "os" + "path" + "path/filepath" + "regexp" + "strconv" + "strings" + + "github.com/openclarity/vmclarity/core/to" + + cdx "github.com/CycloneDX/cyclonedx-go" + "github.com/google/uuid" + log "github.com/sirupsen/logrus" + + "www.velocidex.com/golang/regparser" +) + +// Documentation about registries, its structure and further details can be found at: +// - https://en.wikipedia.org/wiki/Windows_Registry +// - https://github.com/msuhanov/regf/blob/master/Windows%20registry%20file%20format%20specification.md +// - https://techdirectarchive.com/2020/02/07/how-to-check-if-windows-updates-were-installed-on-your-device-via-the-registry-editor/ +// - https://jgmes.com/webstart/library/qr_windowsxp.htm#:~:text=In%20Windows%20XP%2C%20the%20registry,corresponding%20location%20of%20each%20hive. +// +// System SOFTWARE registry keys accessed: +// - system info: Microsoft\Windows NT\CurrentVersion +// - updates: Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages\* +// - profiles: Microsoft\Windows NT\CurrentVersion\ProfileList\* +// - system apps: Microsoft\Windows\CurrentVersion\Uninstall\* +// - system apps: Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* +// - system apps: WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* +// +// User NTUSER.DAT registry keys accessed: +// - user apps: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* + +var defaultRegistryRootPaths = []string{ + "/Windows/System32/config/SOFTWARE", // Windows Vista and newer + "/WINDOWS/system32/config/software", // Windows XP and older +} + +type Registry struct { + mountPath string // root path to Windows drive + softwareReg *regparser.Registry // HKEY_LOCAL_MACHINE/SOFTWARE registry + cleanup func() error + logger *log.Entry +} + +func NewRegistryForMount(mountPath string, logger *log.Entry) (*Registry, error) { + // The registry key structure is identical for all Windows NT distributions, so + // try all registry combinations. If the registry is not found under any default + // paths, it might be a custom system installation or unsupported version. + var errs error + for _, defaultRootPath := range defaultRegistryRootPaths { + registryFilePath := path.Join(mountPath, defaultRootPath) + registry, err := NewRegistry(registryFilePath, logger) + if err == nil { + return registry, nil // found, return + } + errs = errors.Join(errs, err) // collect errors, might be file-related + } + + return nil, fmt.Errorf("cannot find registry in mount %s: %w", mountPath, errs) +} + +func NewRegistry(registryFilePath string, logger *log.Entry) (*Registry, error) { + // Use filepath clean to ensure path is platform-independent + registryFile, err := os.Open(filepath.Clean(registryFilePath)) + if err != nil { + return nil, fmt.Errorf("cannot open registry file: %w", err) + } + + // Registry file must remain open as it is read on-the-fly + softwareReg, err := regparser.NewRegistry(registryFile) + if err != nil { + return nil, fmt.Errorf("cannot create registry reader: %w", err) + } + + // Extract mount path from registry path by removing the default root paths. For + // registry under /var/snapshot/Windows/System32/config/SOFTWARE, this should + // extract /var/snapshot mount path + mountPath := registryFilePath + for _, defaultRootPath := range defaultRegistryRootPaths { + mountPath = strings.TrimSuffix(mountPath, defaultRootPath) + } + + return &Registry{ + mountPath: mountPath, + softwareReg: softwareReg, + cleanup: registryFile.Close, + logger: logger, + }, nil +} + +// Close needs to be called when done to free up resources. Registry is not +// usable once closed. +func (r *Registry) Close() error { + if err := r.cleanup(); err != nil { + return fmt.Errorf("unable to close registry: %w", err) + } + return nil +} + +// GetPlatform returns OS-specific data from the registry. +func (r *Registry) GetPlatform() (map[string]string, error) { + // Open key to fetch operating system version and configuration data + platformKey, err := openKey(r.softwareReg, "Microsoft/Windows NT/CurrentVersion") + if err != nil { + return nil, err + } + + // Extract all platform data from the registry + platform := getValuesMap(platformKey) + + // Strip information about the product key hash + delete(platform, "DigitalProductId") + delete(platform, "DigitalProductId4") + + return platform, nil +} + +// GetUpdates returns a slice of all installed system updates from the registry. +func (r *Registry) GetUpdates() ([]string, error) { + // Open key to fetch CBS data about packages (updates and components) + packagesKey, err := openKey(r.softwareReg, "Microsoft/Windows/CurrentVersion/Component Based Servicing/Packages") + if err != nil { + return nil, err + } + + // Extract all updates from installed packages + updates := map[string]string{} + updateRegex := regexp.MustCompile("KB[0-9]{7,}") + for _, pkgKey := range packagesKey.Subkeys() { + pkgName := pkgKey.Name() + pkgValues := getValuesMap(pkgKey) + + // Ignore packages that were not installed as system components or via updates + _, isComponent := pkgValues["InstallClient"] + _, isUpdate := pkgValues["UpdateAgentLCU"] + if !isComponent && !isUpdate { + continue + } + + // Install location value for a given package can contain update identifier such + // as "C:\Windows\CbsTemp\31075171_2144217839\Windows10.0-KB5032189-x64.cab\" + if location, ok := pkgValues["InstallLocation"]; ok { + if kb := updateRegex.FindString(location); kb != "" { + updates[kb] = kb + } + } + + // If the installed package contains state value, it indicates a potential system + // update. We are only curious about "112" state code which translates to + // successful package installation. When this is the case, package registry key + // contains update identifier such as "Package_10_for_KB5011048..." + if state, ok := pkgValues["CurrentState"]; ok && state == "112" { + if kb := updateRegex.FindString(pkgName); kb != "" { + updates[kb] = kb + } + } + } + + return to.Keys(updates), nil +} + +// GetUsersApps returns installed apps from the registry for all users. This +// method will not error in case user profile cannot be loaded. It only errors if +// the system registry cannot be accessed to get the list of user profiles. +func (r *Registry) GetUsersApps() ([]map[string]string, error) { + // Open key to fetch system user profiles in order to get profile dir paths + profilesKey, err := openKey(r.softwareReg, "Microsoft/Windows NT/CurrentVersion/ProfileList") + if err != nil { + return nil, err + } + + // Extract all installed applications for each user + apps := []map[string]string{} + for _, profileKey := range profilesKey.Subkeys() { + // Run in a function to allow cleanup + func(profileValues map[string]string) { + // Extract profile path from the registry key values. The path is + // Windows-specific, but the mount path must be Unix-specific. + profileLocation, ok := profileValues["ProfileImagePath"] + if !ok { + return // silent skip, not a user profile + } + profileLocation = strings.ReplaceAll(profileLocation, "\\", "/") + + // The actual user location in the registry is specified as "C:\Users\...". + // However, due to the mount location, the actual path could be + // "/var/mounts/Users/...". Strip everything before the "/Users/" to construct a + // valid mount path. + if prefixIdx := strings.Index(profileLocation, "/Users/"); prefixIdx >= 0 { + baseProfileLocation := profileLocation[prefixIdx:] + profileLocation = path.Join(r.mountPath, baseProfileLocation) + } else { + return // silent skip, not a user profile + } + + // Open profile registry file to access profile-specific registry. + // Use filepath clean to ensure path is platform-independent. + profileRegPath := path.Join(profileLocation, "NTUSER.DAT") + profileRegFile, err := os.Open(filepath.Clean(profileRegPath)) + if err != nil { + r.logger.Warnf("failed to open user profile: %v", err) + return + } + defer profileRegFile.Close() + + profileReg, err := regparser.NewRegistry(profileRegFile) + if err != nil { + r.logger.Warnf("failed to create user registry reader: %v", err) + return + } + + // Open key to fetch installed profile apps + profileAppsKey, err := openKey(profileReg, "SOFTWARE/Microsoft/Windows/CurrentVersion/Uninstall") + if err != nil { + r.logger.Warnf("failed to open key: %v", err) + return + } + + // Extract all apps from user registry key. When the application registry key + // values contain application name, add them to the result. + for _, appKey := range profileAppsKey.Subkeys() { + appValues := getValuesMap(appKey) + if _, ok := appValues["DisplayName"]; ok { + apps = append(apps, appValues) + } + } + }(getValuesMap(profileKey)) + } + + return apps, nil +} + +// GetSystemApps returns installed system-wide apps from the registry. +func (r *Registry) GetSystemApps() ([]map[string]string, error) { + // Try multiple keys to fetch installed system apps + apps := []map[string]string{} + for _, appsKey := range []string{ + "Microsoft/Windows/CurrentVersion/Uninstall", // for newer Windows NT + "Wow6432Node/Microsoft/Windows/CurrentVersion/Uninstall", // store for 32-bit apps on 64-bit systems + "WOW6432Node/Microsoft/Windows/CurrentVersion/Uninstall", // same as before, resolves compatibility issues + } { + appsKey, err := openKey(r.softwareReg, appsKey) + if err != nil { + r.logger.Warnf("failed to get installed system apps: %v", err) + continue + } + + // Extract all apps from system registry. When the application registry key + // values contain application name, add them to the result. + for _, appKey := range appsKey.Subkeys() { + appValues := getValuesMap(appKey) + if _, ok := appValues["DisplayName"]; ok { + apps = append(apps, appValues) + } + } + } + + return apps, nil +} + +// GetBOM returns cyclone database from the registry data. +// TODO(ramizpolic): Other registry fetch methods should return a struct instead of maps. +func (r *Registry) GetBOM() (*cdx.BOM, error) { + bom := cdx.NewBOM() + + // Inject platform data to BOM + { + // Get platform registry data + platformData, err := r.GetPlatform() + if err != nil { + return nil, fmt.Errorf("unable to get platform data: %w", err) + } + + // Extract manufacturer if available + var manufacturer *cdx.OrganizationalEntity + if name, ok := platformData["SystemManufacturer"]; ok { + manufacturer = &cdx.OrganizationalEntity{ + Name: name, + } + } + + // Set immutable serial number from the unique installation ID + bom.SerialNumber = uuid.NewSHA1(uuid.Nil, []byte(platformData["ProductId"])).URN() + + // Set BOM metadata + bom.Metadata = &cdx.Metadata{ + Timestamp: platformData["InstallDate"], + Component: &cdx.Component{ + Type: cdx.ComponentTypeOS, + Name: platformData["ProductName"], // Windows 10 Pro + Version: fmt.Sprintf("%s.%s.%s", // 10.0.22000 + platformData["CurrentMajorVersionNumber"], + platformData["CurrentMinorVersionNumber"], + platformData["CurrentBuildNumber"], + ), + }, + Manufacture: manufacturer, + Supplier: &cdx.OrganizationalEntity{ + Name: "Microsoft Corporation", + }, + Properties: &[]cdx.Property{ + { + Name: "analyzers", + Value: AnalyzerName, + }, + }, + } + } + + // Inject updates, system and user apps to BOM + { + var components []cdx.Component + + // Add applications to cyclonedx components + systemApps, err := r.GetSystemApps() + if err != nil { + return nil, fmt.Errorf("unable to get system apps: %w", err) + } + + usersApps, err := r.GetUsersApps() + if err != nil { + return nil, fmt.Errorf("unable to get users apps: %w", err) + } + + apps := append(systemApps, usersApps...) + for _, app := range apps { + components = append(components, cdx.Component{ + Type: cdx.ComponentTypeApplication, + Publisher: app["Publisher"], + Name: app["DisplayName"], + Version: app["DisplayVersion"], + }) + } + + // Add updates to cyclonedx components. This is optional since Windows XP stores + // update data in the system package registry. + // + // TODO(ramizpolic): Error skip should only happen when we know it is XP, + // otherwise this should continue regularly. + systemUpdates, err := r.GetUpdates() + if err == nil { + for _, update := range systemUpdates { + components = append(components, cdx.Component{ + Type: cdx.ComponentTypeApplication, + Publisher: "Microsoft Corporation", + Name: update, + }) + } + } else { + r.logger.Warnf("could not fetch updates from registry: %v", err) + } + + // Set BOM components + bom.Components = &components + } + + return bom, nil +} + +// openKey opens a given registry key from the given registry or returns an error. +// Returned key can have multiple sub-keys and values specified. +func openKey(registry *regparser.Registry, key string) (*regparser.CM_KEY_NODE, error) { + keyNode := registry.OpenKey(key) + if keyNode == nil { + return nil, fmt.Errorf("cannot open key %s", key) + } + return keyNode, nil +} + +// getValuesMap returns all registry key values for a given registry key as a map +// of value name and its data. +func getValuesMap(key *regparser.CM_KEY_NODE) map[string]string { + valuesMap := map[string]string{} + for _, keyValue := range key.Values() { + valuesMap[keyValue.ValueName()] = convertKVData(keyValue.ValueData()) + } + return valuesMap +} + +// convertKVData returns the registry key value data as a valid string. +func convertKVData(value *regparser.ValueData) string { + switch value.Type { + case regparser.REG_SZ, regparser.REG_EXPAND_SZ: // null-terminated string + return strings.TrimRightFunc(value.String, func(r rune) bool { + return r == 0 + }) + + case regparser.REG_MULTI_SZ: // multi-part string + return strings.Join(value.MultiSz, " ") + + case regparser.REG_DWORD, regparser.REG_DWORD_BIG_ENDIAN, regparser.REG_QWORD: // unsigned 32/64-bit value + return strconv.FormatUint(value.Uint64, 10) + + case regparser.REG_BINARY: // non-stringable binary value + // Return as hex to preserve buffer; we don't really care about this value + return fmt.Sprintf("%X", value.Data) + + case + regparser.REG_LINK, // unicode symbolic link + regparser.REG_RESOURCE_LIST, // device-driver resource list + regparser.REG_FULL_RESOURCE_DESCRIPTOR, // hardware setting + regparser.REG_RESOURCE_REQUIREMENTS_LIST, // hardware resource list + regparser.REG_UNKNOWN: // no-type + fallthrough + + default: + return "" + } +} diff --git a/cli/analyzer/windows/registry_test.go b/cli/analyzer/windows/registry_test.go new file mode 100644 index 000000000..816576baf --- /dev/null +++ b/cli/analyzer/windows/registry_test.go @@ -0,0 +1,66 @@ +// Copyright © 2024 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package windows + +import ( + "fmt" + "testing" + + log "github.com/sirupsen/logrus" + "gotest.tools/v3/assert" + "gotest.tools/v3/assert/cmp" +) + +// Windows 10 registry data was obtained from +// https://github.com/AndrewRathbun/VanillaWindowsRegistryHives. Older Windows +// distributions were tested locally and their registries not uploaded due to +// security reasons. +// +// TODO(ramizpolic): Add more test cases for other Windows versions. The testdata +// size will grow, so finding another way to fake the registry data could be +// useful to avoid size issues and manual per-distro registry creation/testing. + +func TestRegistry(t *testing.T) { + // from https://github.com/AndrewRathbun/VanillaWindowsRegistryHives/tree/d12ba60d8dd283a4a17b1a02295356a6bed093cf/Windows10/21H2/W10_21H2_Pro_20211012_19044.1288 + registryFilePath := "testdata/W10_21H2_Pro_20211012_19044.SOFTWARE" + + // when + reg, err := NewRegistry(registryFilePath, log.NewEntry(&log.Logger{})) + assert.NilError(t, err) + + bom, err := reg.GetBOM() + assert.NilError(t, err) + + // check basic details + assert.Equal(t, bom.SerialNumber, "urn:uuid:ec61c342-9f62-593b-8589-824ecc574a26") + assert.Equal(t, bom.Metadata.Component.Name, "Windows 10 Pro") + assert.Equal(t, bom.Metadata.Component.Version, "10.0.19044") + + // check apps and updates details + hasApp := func(reqAppName string) cmp.Comparison { + return func() cmp.Result { + for _, app := range *bom.Components { + if reqAppName == app.Name { + return cmp.ResultSuccess + } + } + return cmp.ResultFailure(fmt.Sprintf("BOM components do not contain app %q", reqAppName)) + } + } + + assert.Assert(t, hasApp("KB5003242")) + assert.Assert(t, hasApp("Microsoft Edge")) +} diff --git a/cli/analyzer/windows/testdata/W10_21H2_Pro_20211012_19044.SOFTWARE b/cli/analyzer/windows/testdata/W10_21H2_Pro_20211012_19044.SOFTWARE new file mode 100644 index 000000000..e2d37fb06 Binary files /dev/null and b/cli/analyzer/windows/testdata/W10_21H2_Pro_20211012_19044.SOFTWARE differ diff --git a/cli/analyzer/windows/windows.go b/cli/analyzer/windows/windows.go new file mode 100644 index 000000000..7621ac11f --- /dev/null +++ b/cli/analyzer/windows/windows.go @@ -0,0 +1,92 @@ +// Copyright © 2024 Cisco Systems, Inc. and its affiliates. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package windows + +import ( + "fmt" + + log "github.com/sirupsen/logrus" + + "github.com/openclarity/vmclarity/cli/analyzer" + "github.com/openclarity/vmclarity/cli/job_manager" + "github.com/openclarity/vmclarity/cli/utils" +) + +const AnalyzerName = "windows" + +type Analyzer struct { + name string + logger *log.Entry + resultChan chan job_manager.Result +} + +func New(_ job_manager.IsConfig, logger *log.Entry, resultChan chan job_manager.Result) job_manager.Job { + return &Analyzer{ + name: AnalyzerName, + logger: logger.Dup().WithField("analyzer", AnalyzerName), + resultChan: resultChan, + } +} + +// nolint:cyclop +func (a *Analyzer) Run(sourceType utils.SourceType, userInput string) error { + a.logger.Infof("Called %s analyzer on source %v %v", a.name, sourceType, userInput) + + go func() { + res := &analyzer.Results{} + + // Create Windows registry based on supported input types + var err error + var registry *Registry + switch sourceType { + case utils.FILE: // Use file location to the registry + registry, err = NewRegistry(userInput, a.logger) + case utils.ROOTFS, utils.DIR: // Use mount drive as input + registry, err = NewRegistryForMount(userInput, a.logger) + case utils.SBOM, utils.IMAGE, utils.DOCKERARCHIVE, utils.OCIARCHIVE, utils.OCIDIR: // Unsupported + fallthrough + default: + a.logger.Infof("Skipping analyzing unsupported source type: %s", sourceType) + a.resultChan <- res + return + } + if err != nil { + a.setError(res, fmt.Errorf("failed to open registry: %w", err)) + return + } + defer registry.Close() + + // Fetch BOM from registry details + bom, err := registry.GetBOM() + if err != nil { + a.setError(res, fmt.Errorf("failed to get bom from registry: %w", err)) + return + } + + // Return sbom + res = analyzer.CreateResults(bom, a.name, userInput, sourceType) + a.logger.Infof("Sending successful results") + a.resultChan <- res + }() + + return nil +} + +func (a *Analyzer) setError(res *analyzer.Results, err error) { + res.Error = err + a.logger.Error(res.Error) + a.resultChan <- res +} diff --git a/cli/go.mod b/cli/go.mod index ecb20c9e0..97bbc27bd 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -39,6 +39,7 @@ require ( gotest.tools v2.2.0+incompatible gotest.tools/v3 v3.5.1 k8s.io/client-go v0.29.1 + www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b ) require ( diff --git a/cli/go.sum b/cli/go.sum index a07e8e7f1..c82254ffc 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -1305,6 +1305,7 @@ github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcuc github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ= github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= @@ -2203,3 +2204,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77Vzej sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b h1:NrnjFXwjUi7vdLEDKgSxu6cs304UJLZE/H7pSXXakVA= +www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b/go.mod h1:pxSECT5mWM3goJ4sxB4HCJNKnKqiAlpyT8XnvBwkLGU= diff --git a/orchestrator/go.mod b/orchestrator/go.mod index 0062e9507..efb73ea54 100644 --- a/orchestrator/go.mod +++ b/orchestrator/go.mod @@ -449,6 +449,7 @@ require ( sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect + www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b // indirect ) // NOTE(chrisgacsal): remove this when the following PR is merged and new helm version is released: diff --git a/orchestrator/go.sum b/orchestrator/go.sum index 59d9af082..6ab46ee2a 100644 --- a/orchestrator/go.sum +++ b/orchestrator/go.sum @@ -1368,6 +1368,7 @@ github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcuc github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ= github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= @@ -2301,3 +2302,5 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b h1:NrnjFXwjUi7vdLEDKgSxu6cs304UJLZE/H7pSXXakVA= +www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b/go.mod h1:pxSECT5mWM3goJ4sxB4HCJNKnKqiAlpyT8XnvBwkLGU= diff --git a/provider/go.mod b/provider/go.mod index a8062ece7..263e5c784 100644 --- a/provider/go.mod +++ b/provider/go.mod @@ -445,6 +445,7 @@ require ( sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect + www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b // indirect ) // NOTE(chrisgacsal): remove this when the following PR is merged and new helm version is released: diff --git a/provider/go.sum b/provider/go.sum index dc24a555a..342a4dc2e 100644 --- a/provider/go.sum +++ b/provider/go.sum @@ -1322,6 +1322,7 @@ github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcuc github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ= github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y= github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI= github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA= @@ -2220,3 +2221,5 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77Vzej sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b h1:NrnjFXwjUi7vdLEDKgSxu6cs304UJLZE/H7pSXXakVA= +www.velocidex.com/golang/regparser v0.0.0-20221020153526-bbc758cbd18b/go.mod h1:pxSECT5mWM3goJ4sxB4HCJNKnKqiAlpyT8XnvBwkLGU=