From 1c73764d4699498474833de990c2bd97426ba80f Mon Sep 17 00:00:00 2001 From: Christian Zunker Date: Mon, 26 Feb 2024 15:12:18 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20origin=20version=20to=20debia?= =?UTF-8?q?n=20packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some packages contain the version information for the source package. Where we can find it, we add it. Signed-off-by: Christian Zunker --- providers/os/resources/os.lr | 3 ++ providers/os/resources/os.lr.go | 14 ++++++++ providers/os/resources/os.lr.manifest.yaml | 2 ++ providers/os/resources/packages.go | 33 +++++++++++-------- .../os/resources/packages/dpkg_packages.go | 16 ++++++--- providers/os/resources/packages/packages.go | 5 +-- 6 files changed, 53 insertions(+), 20 deletions(-) diff --git a/providers/os/resources/os.lr b/providers/os/resources/os.lr index 847e84ed9d..3e83e912ae 100644 --- a/providers/os/resources/os.lr +++ b/providers/os/resources/os.lr @@ -616,6 +616,9 @@ package @defaults("name version") { // Package origin (optional) origin() string + // Package origin version (optional) + originVersion() string + // Available version available string diff --git a/providers/os/resources/os.lr.go b/providers/os/resources/os.lr.go index 4fa6a15853..dfcaa99017 100644 --- a/providers/os/resources/os.lr.go +++ b/providers/os/resources/os.lr.go @@ -1132,6 +1132,9 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "package.origin": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlPackage).GetOrigin()).ToDataRes(types.String) }, + "package.originVersion": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlPackage).GetOriginVersion()).ToDataRes(types.String) + }, "package.available": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlPackage).GetAvailable()).ToDataRes(types.String) }, @@ -3094,6 +3097,10 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlPackage).Origin, ok = plugin.RawToTValue[string](v.Value, v.Error) return }, + "package.originVersion": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlPackage).OriginVersion, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, "package.available": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlPackage).Available, ok = plugin.RawToTValue[string](v.Value, v.Error) return @@ -8121,6 +8128,7 @@ type mqlPackage struct { Purl plugin.TValue[string] Cpes plugin.TValue[[]interface{}] Origin plugin.TValue[string] + OriginVersion plugin.TValue[string] Available plugin.TValue[string] Installed plugin.TValue[bool] Outdated plugin.TValue[bool] @@ -8208,6 +8216,12 @@ func (c *mqlPackage) GetOrigin() *plugin.TValue[string] { }) } +func (c *mqlPackage) GetOriginVersion() *plugin.TValue[string] { + return plugin.GetOrCompute[string](&c.OriginVersion, func() (string, error) { + return c.originVersion() + }) +} + func (c *mqlPackage) GetAvailable() *plugin.TValue[string] { return &c.Available } diff --git a/providers/os/resources/os.lr.manifest.yaml b/providers/os/resources/os.lr.manifest.yaml index 757dd6c27e..be6122a145 100644 --- a/providers/os/resources/os.lr.manifest.yaml +++ b/providers/os/resources/os.lr.manifest.yaml @@ -587,6 +587,8 @@ resources: installed: {} name: {} origin: {} + originVersion: + min_mondoo_version: latest outdated: {} purl: min_mondoo_version: latest diff --git a/providers/os/resources/packages.go b/providers/os/resources/packages.go index cf1896d22a..23c8af5ff7 100644 --- a/providers/os/resources/packages.go +++ b/providers/os/resources/packages.go @@ -5,10 +5,11 @@ package resources import ( "errors" - "go.mondoo.com/cnquery/v10/types" "regexp" "sync" + "go.mondoo.com/cnquery/v10/types" + "github.com/rs/zerolog/log" "go.mondoo.com/cnquery/v10/llx" "go.mondoo.com/cnquery/v10/providers-sdk/v1/plugin" @@ -74,6 +75,7 @@ func initPackage(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[str res.Arch.State = plugin.StateIsSet | plugin.StateIsNull res.Format.State = plugin.StateIsSet | plugin.StateIsNull res.Origin.State = plugin.StateIsSet | plugin.StateIsNull + res.OriginVersion.State = plugin.StateIsSet | plugin.StateIsNull res.Status.State = plugin.StateIsSet | plugin.StateIsNull res.Files.State = plugin.StateIsSet | plugin.StateIsNull return nil, res, nil @@ -94,6 +96,10 @@ func (p *mqlPackage) origin() (string, error) { return "", nil } +func (p *mqlPackage) originVersion() (string, error) { + return "", nil +} + func (p *mqlPackage) files() ([]interface{}, error) { if p.filesState == packages.PkgFilesNotAvailable { return nil, nil @@ -189,18 +195,19 @@ func (x *mqlPackages) list() ([]interface{}, error) { } pkg, err := CreateResource(x.MqlRuntime, "package", map[string]*llx.RawData{ - "name": llx.StringData(osPkg.Name), - "version": llx.StringData(osPkg.Version), - "available": llx.StringData(available), - "arch": llx.StringData(osPkg.Arch), - "status": llx.StringData(osPkg.Status), - "description": llx.StringData(osPkg.Description), - "format": llx.StringData(osPkg.Format), - "installed": llx.BoolData(true), - "origin": llx.StringData(osPkg.Origin), - "epoch": llx.StringData(osPkg.Epoch), - "purl": llx.StringData(osPkg.PUrl), - "cpes": llx.ArrayData(cpes, types.Resource("cpe")), + "name": llx.StringData(osPkg.Name), + "version": llx.StringData(osPkg.Version), + "available": llx.StringData(available), + "arch": llx.StringData(osPkg.Arch), + "status": llx.StringData(osPkg.Status), + "description": llx.StringData(osPkg.Description), + "format": llx.StringData(osPkg.Format), + "installed": llx.BoolData(true), + "origin": llx.StringData(osPkg.Origin), + "originVersion": llx.StringData(osPkg.OriginVersion), + "epoch": llx.StringData(osPkg.Epoch), + "purl": llx.StringData(osPkg.PUrl), + "cpes": llx.ArrayData(cpes, types.Resource("cpe")), }) if err != nil { return nil, err diff --git a/providers/os/resources/packages/dpkg_packages.go b/providers/os/resources/packages/dpkg_packages.go index 5a0c299277..36529ff9e3 100644 --- a/providers/os/resources/packages/dpkg_packages.go +++ b/providers/os/resources/packages/dpkg_packages.go @@ -6,15 +6,16 @@ package packages import ( "bufio" "fmt" - "github.com/package-url/packageurl-go" - "go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory" - "go.mondoo.com/cnquery/v10/providers/os/resources/cpe" - "go.mondoo.com/cnquery/v10/providers/os/resources/purl" "io" "os" "regexp" "strings" + "github.com/package-url/packageurl-go" + "go.mondoo.com/cnquery/v10/providers-sdk/v1/inventory" + "go.mondoo.com/cnquery/v10/providers/os/resources/cpe" + "go.mondoo.com/cnquery/v10/providers/os/resources/purl" + "github.com/rs/zerolog/log" "github.com/spf13/afero" "go.mondoo.com/cnquery/v10/providers/os/connection/shared" @@ -25,7 +26,8 @@ const ( ) var ( - DPKG_REGEX = regexp.MustCompile(`^(.+):\s(.+)$`) + DPKG_REGEX = regexp.MustCompile(`^(.+):\s(.+)$`) + // e.g. source with version: samba (2:4.17.12+dfsg-0+deb12u1) DPKG_ORIGIN_REGEX = regexp.MustCompile(`^\s*([^\(]*)(?:\((.*)\))?\s*$`) ) @@ -85,6 +87,10 @@ func ParseDpkgPackages(pf *inventory.Platform, input io.Reader) ([]Package, erro } else { log.Error().Str("origin", m[2]).Msg("cannot parse dpkg origin") } + // Some packages also have a version as part of the Source field + if o != nil && len(o) >= 2 { + pkg.OriginVersion = strings.TrimSpace(o[2]) + } // description supports multi-line statements, start desc case key == "Description": pkg.Description = strings.TrimSpace(m[2]) diff --git a/providers/os/resources/packages/packages.go b/providers/os/resources/packages/packages.go index 4b9566d39e..de5c6add9c 100644 --- a/providers/os/resources/packages/packages.go +++ b/providers/os/resources/packages/packages.go @@ -33,8 +33,9 @@ type Package struct { // this may be the source package or an origin // e.g. on alpine it is used for parent packages // o Package Origin - https://wiki.alpinelinux.org/wiki/Apk_spec - Origin string `json:"origin"` - Format string `json:"format"` + Origin string `json:"origin"` + OriginVersion string `json:"originVersion"` + Format string `json:"format"` // Package Url follows https://github.com/package-url/purl-spec PUrl string `json:"purl,omitempty"`