diff --git a/providers/os/resources/os.lr b/providers/os/resources/os.lr index 0422828dd7..924b383272 100644 --- a/providers/os/resources/os.lr +++ b/providers/os/resources/os.lr @@ -62,6 +62,7 @@ platform { vulnerabilityReport() dict } +// Vulnerability Information extend vulnmgmt { // List of all CVEs affecting the asset cves() []vuln.cve diff --git a/providers/os/resources/vulnmgmt.go b/providers/os/resources/vulnmgmt.go index 1de5a1acf0..99e1f86adf 100644 --- a/providers/os/resources/vulnmgmt.go +++ b/providers/os/resources/vulnmgmt.go @@ -184,12 +184,6 @@ func (v *mqlVulnmgmt) getReport() (*gql.VulnReport, error) { } func (v *mqlVulnmgmt) getIncognitoReport(mondooClient *gql.MondooClient) (*gql.VulnReport, error) { - // FIXCME: when we don't have a MRN, we need to: - // - creeate asset - // - create packages - // - get "incognito" vulnReport - // - procede as usual - conn := v.MqlRuntime.Connection.(shared.Connection) platform := conn.Asset().Platform diff --git a/providers/vsphere/resources/vsphere.lr b/providers/vsphere/resources/vsphere.lr index f6d61fa232..93b0fff920 100644 --- a/providers/vsphere/resources/vsphere.lr +++ b/providers/vsphere/resources/vsphere.lr @@ -9,7 +9,8 @@ extend asset { // Common Platform Enumeration (CPE) for the asset cpes() []core.cpe // Advisory & vulnerability report - // Will be deprecated; Full advisory & vulnerability report + // Will be deprecated in version 10.0; Full advisory & vulnerability report + // use vulnmgmt instead vulnerabilityReport() dict } @@ -19,6 +20,72 @@ platform { vulnerabilityReport() dict } +// Vulnerability Information +extend vulnmgmt { + // List of all CVEs affecting the asset + cves() []vuln.cve + // List of all Advisories affecting the asset + advisories() []vuln.advisory + // List of all packages affected by vulnerabilities + packages() []vuln.package + // Last time the vulnerability information was updated + lastAssessment() time +} + +// CVE information +private vuln.cve @defaults("id") { + // CVE ID + id string + // CVE state + state string + // Summary description + summary string + // Whether the CVE has a CVSS score + unscored bool + // Publication date + published time + // Last modification date + modified time + // Worst CVSS score of all assigned CVEs + worstScore audit.cvss +} + +// Advisory information +private vuln.advisory @defaults("id") { + // Advisory ID + id string + // Title of the advisory + title string + // Description of the advisory + description string + // Advisory publication date + published time + // Last modification date + modified time + // Worst CVSS score of all assigned CVEs + worstScore audit.cvss +} + +// Package information relevant for vulnerability management +private vuln.package @defaults("name version") { + // Package name + name string + // Package version + version string + // Available package version + available string + // Architecture of this package + arch string +} + +// Common Vulnerability Scoring System (CVSS) score +private audit.cvss { + // CVSS score ranging from 0.0 to 10.0 + score float + // CVSS score represented as a vector string + vector string +} + // VMware vSphere resource vsphere { // System information including the name, type, version, and build number diff --git a/providers/vsphere/resources/vsphere.lr.go b/providers/vsphere/resources/vsphere.lr.go index 32d2324e4e..ee667f57d5 100644 --- a/providers/vsphere/resources/vsphere.lr.go +++ b/providers/vsphere/resources/vsphere.lr.go @@ -26,6 +26,26 @@ func init() { // to override args, implement: initPlatform(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) Create: createPlatform, }, + "vulnmgmt": { + // to override args, implement: initVulnmgmt(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createVulnmgmt, + }, + "vuln.cve": { + // to override args, implement: initVulnCve(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createVulnCve, + }, + "vuln.advisory": { + // to override args, implement: initVulnAdvisory(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createVulnAdvisory, + }, + "vuln.package": { + // to override args, implement: initVulnPackage(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createVulnPackage, + }, + "audit.cvss": { + // to override args, implement: initAuditCvss(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) + Create: createAuditCvss, + }, "vsphere": { // to override args, implement: initVsphere(runtime *plugin.Runtime, args map[string]*llx.RawData) (map[string]*llx.RawData, plugin.Resource, error) Create: createVsphere, @@ -171,6 +191,75 @@ var getDataFields = map[string]func(r plugin.Resource) *plugin.DataRes{ "platform.vulnerabilityReport": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlPlatform).GetVulnerabilityReport()).ToDataRes(types.Dict) }, + "vulnmgmt.cves": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnmgmt).GetCves()).ToDataRes(types.Array(types.Resource("vuln.cve"))) + }, + "vulnmgmt.advisories": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnmgmt).GetAdvisories()).ToDataRes(types.Array(types.Resource("vuln.advisory"))) + }, + "vulnmgmt.packages": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnmgmt).GetPackages()).ToDataRes(types.Array(types.Resource("vuln.package"))) + }, + "vulnmgmt.lastAssessment": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnmgmt).GetLastAssessment()).ToDataRes(types.Time) + }, + "vuln.cve.id": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetId()).ToDataRes(types.String) + }, + "vuln.cve.state": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetState()).ToDataRes(types.String) + }, + "vuln.cve.summary": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetSummary()).ToDataRes(types.String) + }, + "vuln.cve.unscored": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetUnscored()).ToDataRes(types.Bool) + }, + "vuln.cve.published": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetPublished()).ToDataRes(types.Time) + }, + "vuln.cve.modified": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetModified()).ToDataRes(types.Time) + }, + "vuln.cve.worstScore": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnCve).GetWorstScore()).ToDataRes(types.Resource("audit.cvss")) + }, + "vuln.advisory.id": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnAdvisory).GetId()).ToDataRes(types.String) + }, + "vuln.advisory.title": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnAdvisory).GetTitle()).ToDataRes(types.String) + }, + "vuln.advisory.description": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnAdvisory).GetDescription()).ToDataRes(types.String) + }, + "vuln.advisory.published": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnAdvisory).GetPublished()).ToDataRes(types.Time) + }, + "vuln.advisory.modified": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnAdvisory).GetModified()).ToDataRes(types.Time) + }, + "vuln.advisory.worstScore": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnAdvisory).GetWorstScore()).ToDataRes(types.Resource("audit.cvss")) + }, + "vuln.package.name": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnPackage).GetName()).ToDataRes(types.String) + }, + "vuln.package.version": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnPackage).GetVersion()).ToDataRes(types.String) + }, + "vuln.package.available": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnPackage).GetAvailable()).ToDataRes(types.String) + }, + "vuln.package.arch": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlVulnPackage).GetArch()).ToDataRes(types.String) + }, + "audit.cvss.score": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAuditCvss).GetScore()).ToDataRes(types.Float) + }, + "audit.cvss.vector": func(r plugin.Resource) *plugin.DataRes { + return (r.(*mqlAuditCvss).GetVector()).ToDataRes(types.String) + }, "vsphere.about": func(r plugin.Resource) *plugin.DataRes { return (r.(*mqlVsphere).GetAbout()).ToDataRes(types.Dict) }, @@ -482,6 +571,118 @@ var setDataFields = map[string]func(r plugin.Resource, v *llx.RawData) bool { r.(*mqlPlatform).VulnerabilityReport, ok = plugin.RawToTValue[interface{}](v.Value, v.Error) return }, + "vulnmgmt.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnmgmt).__id, ok = v.Value.(string) + return + }, + "vulnmgmt.cves": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnmgmt).Cves, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) + return + }, + "vulnmgmt.advisories": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnmgmt).Advisories, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) + return + }, + "vulnmgmt.packages": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnmgmt).Packages, ok = plugin.RawToTValue[[]interface{}](v.Value, v.Error) + return + }, + "vulnmgmt.lastAssessment": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnmgmt).LastAssessment, ok = plugin.RawToTValue[*time.Time](v.Value, v.Error) + return + }, + "vuln.cve.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).__id, ok = v.Value.(string) + return + }, + "vuln.cve.id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).Id, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.cve.state": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).State, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.cve.summary": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).Summary, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.cve.unscored": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).Unscored, ok = plugin.RawToTValue[bool](v.Value, v.Error) + return + }, + "vuln.cve.published": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).Published, ok = plugin.RawToTValue[*time.Time](v.Value, v.Error) + return + }, + "vuln.cve.modified": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).Modified, ok = plugin.RawToTValue[*time.Time](v.Value, v.Error) + return + }, + "vuln.cve.worstScore": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnCve).WorstScore, ok = plugin.RawToTValue[*mqlAuditCvss](v.Value, v.Error) + return + }, + "vuln.advisory.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).__id, ok = v.Value.(string) + return + }, + "vuln.advisory.id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).Id, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.advisory.title": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).Title, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.advisory.description": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).Description, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.advisory.published": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).Published, ok = plugin.RawToTValue[*time.Time](v.Value, v.Error) + return + }, + "vuln.advisory.modified": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).Modified, ok = plugin.RawToTValue[*time.Time](v.Value, v.Error) + return + }, + "vuln.advisory.worstScore": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnAdvisory).WorstScore, ok = plugin.RawToTValue[*mqlAuditCvss](v.Value, v.Error) + return + }, + "vuln.package.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnPackage).__id, ok = v.Value.(string) + return + }, + "vuln.package.name": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnPackage).Name, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.package.version": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnPackage).Version, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.package.available": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnPackage).Available, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "vuln.package.arch": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlVulnPackage).Arch, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, + "audit.cvss.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAuditCvss).__id, ok = v.Value.(string) + return + }, + "audit.cvss.score": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAuditCvss).Score, ok = plugin.RawToTValue[float64](v.Value, v.Error) + return + }, + "audit.cvss.vector": func(r plugin.Resource, v *llx.RawData) (ok bool) { + r.(*mqlAuditCvss).Vector, ok = plugin.RawToTValue[string](v.Value, v.Error) + return + }, "vsphere.__id": func(r plugin.Resource, v *llx.RawData) (ok bool) { r.(*mqlVsphere).__id, ok = v.Value.(string) return @@ -1055,6 +1256,354 @@ func (c *mqlPlatform) GetVulnerabilityReport() *plugin.TValue[interface{}] { }) } +// mqlVulnmgmt for the vulnmgmt resource +type mqlVulnmgmt struct { + MqlRuntime *plugin.Runtime + __id string + // optional: if you define mqlVulnmgmtInternal it will be used here + Cves plugin.TValue[[]interface{}] + Advisories plugin.TValue[[]interface{}] + Packages plugin.TValue[[]interface{}] + LastAssessment plugin.TValue[*time.Time] +} + +// createVulnmgmt creates a new instance of this resource +func createVulnmgmt(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlVulnmgmt{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("vulnmgmt", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlVulnmgmt) MqlName() string { + return "vulnmgmt" +} + +func (c *mqlVulnmgmt) MqlID() string { + return c.__id +} + +func (c *mqlVulnmgmt) GetCves() *plugin.TValue[[]interface{}] { + return plugin.GetOrCompute[[]interface{}](&c.Cves, func() ([]interface{}, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("vulnmgmt", c.__id, "cves") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.([]interface{}), nil + } + } + + return c.cves() + }) +} + +func (c *mqlVulnmgmt) GetAdvisories() *plugin.TValue[[]interface{}] { + return plugin.GetOrCompute[[]interface{}](&c.Advisories, func() ([]interface{}, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("vulnmgmt", c.__id, "advisories") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.([]interface{}), nil + } + } + + return c.advisories() + }) +} + +func (c *mqlVulnmgmt) GetPackages() *plugin.TValue[[]interface{}] { + return plugin.GetOrCompute[[]interface{}](&c.Packages, func() ([]interface{}, error) { + if c.MqlRuntime.HasRecording { + d, err := c.MqlRuntime.FieldResourceFromRecording("vulnmgmt", c.__id, "packages") + if err != nil { + return nil, err + } + if d != nil { + return d.Value.([]interface{}), nil + } + } + + return c.packages() + }) +} + +func (c *mqlVulnmgmt) GetLastAssessment() *plugin.TValue[*time.Time] { + return plugin.GetOrCompute[*time.Time](&c.LastAssessment, func() (*time.Time, error) { + return c.lastAssessment() + }) +} + +// mqlVulnCve for the vuln.cve resource +type mqlVulnCve struct { + MqlRuntime *plugin.Runtime + __id string + // optional: if you define mqlVulnCveInternal it will be used here + Id plugin.TValue[string] + State plugin.TValue[string] + Summary plugin.TValue[string] + Unscored plugin.TValue[bool] + Published plugin.TValue[*time.Time] + Modified plugin.TValue[*time.Time] + WorstScore plugin.TValue[*mqlAuditCvss] +} + +// createVulnCve creates a new instance of this resource +func createVulnCve(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlVulnCve{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("vuln.cve", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlVulnCve) MqlName() string { + return "vuln.cve" +} + +func (c *mqlVulnCve) MqlID() string { + return c.__id +} + +func (c *mqlVulnCve) GetId() *plugin.TValue[string] { + return &c.Id +} + +func (c *mqlVulnCve) GetState() *plugin.TValue[string] { + return &c.State +} + +func (c *mqlVulnCve) GetSummary() *plugin.TValue[string] { + return &c.Summary +} + +func (c *mqlVulnCve) GetUnscored() *plugin.TValue[bool] { + return &c.Unscored +} + +func (c *mqlVulnCve) GetPublished() *plugin.TValue[*time.Time] { + return &c.Published +} + +func (c *mqlVulnCve) GetModified() *plugin.TValue[*time.Time] { + return &c.Modified +} + +func (c *mqlVulnCve) GetWorstScore() *plugin.TValue[*mqlAuditCvss] { + return &c.WorstScore +} + +// mqlVulnAdvisory for the vuln.advisory resource +type mqlVulnAdvisory struct { + MqlRuntime *plugin.Runtime + __id string + // optional: if you define mqlVulnAdvisoryInternal it will be used here + Id plugin.TValue[string] + Title plugin.TValue[string] + Description plugin.TValue[string] + Published plugin.TValue[*time.Time] + Modified plugin.TValue[*time.Time] + WorstScore plugin.TValue[*mqlAuditCvss] +} + +// createVulnAdvisory creates a new instance of this resource +func createVulnAdvisory(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlVulnAdvisory{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("vuln.advisory", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlVulnAdvisory) MqlName() string { + return "vuln.advisory" +} + +func (c *mqlVulnAdvisory) MqlID() string { + return c.__id +} + +func (c *mqlVulnAdvisory) GetId() *plugin.TValue[string] { + return &c.Id +} + +func (c *mqlVulnAdvisory) GetTitle() *plugin.TValue[string] { + return &c.Title +} + +func (c *mqlVulnAdvisory) GetDescription() *plugin.TValue[string] { + return &c.Description +} + +func (c *mqlVulnAdvisory) GetPublished() *plugin.TValue[*time.Time] { + return &c.Published +} + +func (c *mqlVulnAdvisory) GetModified() *plugin.TValue[*time.Time] { + return &c.Modified +} + +func (c *mqlVulnAdvisory) GetWorstScore() *plugin.TValue[*mqlAuditCvss] { + return &c.WorstScore +} + +// mqlVulnPackage for the vuln.package resource +type mqlVulnPackage struct { + MqlRuntime *plugin.Runtime + __id string + // optional: if you define mqlVulnPackageInternal it will be used here + Name plugin.TValue[string] + Version plugin.TValue[string] + Available plugin.TValue[string] + Arch plugin.TValue[string] +} + +// createVulnPackage creates a new instance of this resource +func createVulnPackage(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlVulnPackage{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("vuln.package", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlVulnPackage) MqlName() string { + return "vuln.package" +} + +func (c *mqlVulnPackage) MqlID() string { + return c.__id +} + +func (c *mqlVulnPackage) GetName() *plugin.TValue[string] { + return &c.Name +} + +func (c *mqlVulnPackage) GetVersion() *plugin.TValue[string] { + return &c.Version +} + +func (c *mqlVulnPackage) GetAvailable() *plugin.TValue[string] { + return &c.Available +} + +func (c *mqlVulnPackage) GetArch() *plugin.TValue[string] { + return &c.Arch +} + +// mqlAuditCvss for the audit.cvss resource +type mqlAuditCvss struct { + MqlRuntime *plugin.Runtime + __id string + // optional: if you define mqlAuditCvssInternal it will be used here + Score plugin.TValue[float64] + Vector plugin.TValue[string] +} + +// createAuditCvss creates a new instance of this resource +func createAuditCvss(runtime *plugin.Runtime, args map[string]*llx.RawData) (plugin.Resource, error) { + res := &mqlAuditCvss{ + MqlRuntime: runtime, + } + + err := SetAllData(res, args) + if err != nil { + return res, err + } + + // to override __id implement: id() (string, error) + + if runtime.HasRecording { + args, err = runtime.ResourceFromRecording("audit.cvss", res.__id) + if err != nil || args == nil { + return res, err + } + return res, SetAllData(res, args) + } + + return res, nil +} + +func (c *mqlAuditCvss) MqlName() string { + return "audit.cvss" +} + +func (c *mqlAuditCvss) MqlID() string { + return c.__id +} + +func (c *mqlAuditCvss) GetScore() *plugin.TValue[float64] { + return &c.Score +} + +func (c *mqlAuditCvss) GetVector() *plugin.TValue[string] { + return &c.Vector +} + // mqlVsphere for the vsphere resource type mqlVsphere struct { MqlRuntime *plugin.Runtime diff --git a/providers/vsphere/resources/vsphere.lr.manifest.yaml b/providers/vsphere/resources/vsphere.lr.manifest.yaml index 5fa1551ffa..c92ec18d63 100644 --- a/providers/vsphere/resources/vsphere.lr.manifest.yaml +++ b/providers/vsphere/resources/vsphere.lr.manifest.yaml @@ -7,6 +7,12 @@ resources: cpes: {} vulnerabilityReport: {} min_mondoo_version: latest + audit.cvss: + fields: + score: {} + vector: {} + is_private: true + min_mondoo_version: latest esxi: docs: desc: | @@ -290,3 +296,39 @@ resources: name: - vmware-esxi - vmware-vsphere + vuln.advisory: + fields: + description: {} + id: {} + modified: {} + published: {} + title: {} + worstScore: {} + is_private: true + min_mondoo_version: latest + vuln.cve: + fields: + id: {} + modified: {} + published: {} + state: {} + summary: {} + unscored: {} + worstScore: {} + is_private: true + min_mondoo_version: latest + vuln.package: + fields: + arch: {} + available: {} + name: {} + version: {} + is_private: true + min_mondoo_version: latest + vulnmgmt: + fields: + advisories: {} + cves: {} + lastAssessment: {} + packages: {} + min_mondoo_version: latest diff --git a/providers/vsphere/resources/vulnmgmt.go b/providers/vsphere/resources/vulnmgmt.go new file mode 100644 index 0000000000..b0b777ab39 --- /dev/null +++ b/providers/vsphere/resources/vulnmgmt.go @@ -0,0 +1,189 @@ +// Copyright (c) Mondoo, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package resources + +import ( + "errors" + "time" + + "github.com/rs/zerolog/log" + "go.mondoo.com/cnquery/v9/llx" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/plugin" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/resources" + "go.mondoo.com/cnquery/v9/providers-sdk/v1/upstream/gql" + "go.mondoo.com/cnquery/v9/providers/os/connection/shared" + mondoogql "go.mondoo.com/mondoo-go" +) + +func (v *mqlVulnmgmt) lastAssessment() (*time.Time, error) { + mcc := v.MqlRuntime.Upstream + if mcc == nil || mcc.ApiEndpoint == "" { + return nil, resources.MissingUpstreamError{} + } + + // get new gql client + mondooClient, err := gql.NewClient(mcc.UpstreamConfig, mcc.HttpClient) + if err != nil { + return nil, err + } + + if v.MqlRuntime.Upstream.AssetMrn == "" { + return nil, errors.New("no asset mrn available") + } + lastUpdate, err := mondooClient.LastAssessment(v.MqlRuntime.Upstream.AssetMrn) + if err != nil { + return nil, err + } + + log.Debug().Str("time", lastUpdate).Msg("search for package last update") + if lastUpdate == "" { + return nil, errors.New("no update time available") + } + + var lastUpdateTime *time.Time + if lastUpdate != "" { + parsedLastUpdateTime, err := time.Parse(time.RFC3339, lastUpdate) + if err != nil { + return nil, errors.New("could not parse last update time: " + lastUpdate) + } + lastUpdateTime = &parsedLastUpdateTime + } else { + lastUpdateTime = &llx.NeverFutureTime + } + + return lastUpdateTime, nil +} + +func (v *mqlVulnmgmt) cves() ([]interface{}, error) { + return nil, v.populateData() +} + +func (v *mqlVulnmgmt) advisories() ([]interface{}, error) { + return nil, v.populateData() +} + +func (v *mqlVulnmgmt) packages() ([]interface{}, error) { + return nil, v.populateData() +} + +func (v *mqlVulnmgmt) populateData() error { + vulnReport, err := v.getReport() + if err != nil { + return err + } + + mqlVulAdvisories := make([]interface{}, len(vulnReport.Advisories)) + for i, a := range vulnReport.Advisories { + parsedPublished, err := time.Parse(time.RFC3339, a.PublishedAt) + if err != nil { + return err + } + parsedModifed, err := time.Parse(time.RFC3339, a.ModifiedAt) + if err != nil { + return err + } + cvssScore, err := CreateResource(v.MqlRuntime, "audit.cvss", map[string]*llx.RawData{ + "score": llx.FloatData(float64(a.CvssScore.Value) / 10), + "vector": llx.StringData(a.CvssScore.Vector), + }) + if err != nil { + return err + } + mqlVulnAdvisory, err := CreateResource(v.MqlRuntime, "vuln.advisory", map[string]*llx.RawData{ + "id": llx.StringData(a.Id), + "title": llx.StringData(a.Title), + "description": llx.StringData(a.Description), + "published": llx.TimeData(parsedPublished), + "modified": llx.TimeData(parsedModifed), + "worstScore": llx.ResourceData(cvssScore, "audit.cvss"), + }) + if err != nil { + return err + } + mqlVulAdvisories[i] = mqlVulnAdvisory + } + + mqlVulnCves := make([]interface{}, len(vulnReport.Cves)) + for i, c := range vulnReport.Cves { + parsedPublished, err := time.Parse(time.RFC3339, c.PublishedAt) + if err != nil { + return err + } + parsedModifed, err := time.Parse(time.RFC3339, c.ModifiedAt) + if err != nil { + return err + } + cvssScore, err := CreateResource(v.MqlRuntime, "audit.cvss", map[string]*llx.RawData{ + "score": llx.FloatData(float64(c.CvssScore.Value) / 10), + "vector": llx.StringData(c.CvssScore.Vector), + }) + if err != nil { + return err + } + mqlVulnCve, err := CreateResource(v.MqlRuntime, "vuln.cve", map[string]*llx.RawData{ + "id": llx.StringData(c.Id), + "worstScore": llx.ResourceData(cvssScore, "audit.cvss"), + "published": llx.TimeData(parsedPublished), + "modified": llx.TimeData(parsedModifed), + }) + if err != nil { + return err + } + mqlVulnCves[i] = mqlVulnCve + } + + v.Advisories = plugin.TValue[[]interface{}]{Data: mqlVulAdvisories, State: plugin.StateIsSet} + v.Cves = plugin.TValue[[]interface{}]{Data: mqlVulnCves, State: plugin.StateIsSet} + + return nil +} + +func (v *mqlVulnmgmt) getReport() (*gql.VulnReport, error) { + mcc := v.MqlRuntime.Upstream + if mcc == nil || mcc.ApiEndpoint == "" { + return nil, resources.MissingUpstreamError{} + } + + // get new gql client + mondooClient, err := gql.NewClient(mcc.UpstreamConfig, mcc.HttpClient) + if err != nil { + return nil, err + } + + if v.MqlRuntime.Upstream.AssetMrn == "" { + log.Debug().Msg("no asset mrn available") + return v.getIncognitoReport(mondooClient) + } + gqlVulnReport, err := mondooClient.GetVulnCompactReport(v.MqlRuntime.Upstream.AssetMrn) + if err != nil { + return nil, err + } + + log.Debug().Interface("gqlReport", gqlVulnReport).Msg("search for asset vuln report") + if gqlVulnReport == nil { + return nil, errors.New("no vulnerability report available") + } + + return gqlVulnReport, nil +} + +func (v *mqlVulnmgmt) getIncognitoReport(mondooClient *gql.MondooClient) (*gql.VulnReport, error) { + conn := v.MqlRuntime.Connection.(shared.Connection) + platform := conn.Asset().Platform + + gqlVulnReport, err := mondooClient.GetIncognitoVulnReport(mondoogql.PlatformInput{ + Name: mondoogql.NewStringPtr(mondoogql.String(platform.Name)), + Release: mondoogql.NewStringPtr(mondoogql.String(platform.Version)), + }, []mondoogql.PackageInput{}) + if err != nil { + return nil, err + } + + log.Debug().Interface("gqlReport", gqlVulnReport).Msg("search for asset vuln report") + if gqlVulnReport == nil { + return nil, errors.New("no vulnerability report available") + } + + return gqlVulnReport, nil +}