Compare commits
	
		
			16 Commits
		
	
	
		
			v0.23.2
			...
			MaineK00n/
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bbb8fcbb42 | ||
| 
						 | 
					a23abf48fd | ||
| 
						 | 
					6e14a2dee6 | ||
| 
						 | 
					e12fa0ba64 | ||
| 
						 | 
					fa5b875c34 | ||
| 
						 | 
					f9276a7ea8 | ||
| 
						 | 
					457a3a9627 | ||
| 
						 | 
					4253550c99 | ||
| 
						 | 
					97cf033ed6 | ||
| 
						 | 
					5a6980436a | ||
| 
						 | 
					6271ec522e | ||
| 
						 | 
					83681ad4f0 | ||
| 
						 | 
					779833872b | ||
| 
						 | 
					5c79720f56 | ||
| 
						 | 
					b2c5b79672 | ||
| 
						 | 
					b0cc908b73 | 
@@ -127,7 +127,7 @@ func GetEOL(family, release string) (eol EOL, found bool) {
 | 
			
		||||
			"9":  {StandardSupportUntil: time.Date(2022, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"10": {StandardSupportUntil: time.Date(2024, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"11": {StandardSupportUntil: time.Date(2026, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			// "12": {StandardSupportUntil: time.Date(2028, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"12": {StandardSupportUntil: time.Date(2028, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			// "13": {StandardSupportUntil: time.Date(2030, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			// "14": {StandardSupportUntil: time.Date(2032, 6, 30, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
		}[major(release)]
 | 
			
		||||
@@ -317,6 +317,7 @@ func GetEOL(family, release string) (eol EOL, found bool) {
 | 
			
		||||
			"35": {StandardSupportUntil: time.Date(2022, 12, 12, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"36": {StandardSupportUntil: time.Date(2023, 5, 16, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"37": {StandardSupportUntil: time.Date(2023, 12, 15, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
			"38": {StandardSupportUntil: time.Date(2024, 5, 14, 23, 59, 59, 0, time.UTC)},
 | 
			
		||||
		}[major(release)]
 | 
			
		||||
	case constant.Windows:
 | 
			
		||||
		// https://learn.microsoft.com/ja-jp/lifecycle/products/?products=windows
 | 
			
		||||
 
 | 
			
		||||
@@ -364,6 +364,14 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) {
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
		},
 | 
			
		||||
		//Debian
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 8 supported",
 | 
			
		||||
			fields:   fields{family: Debian, release: "8"},
 | 
			
		||||
			now:      time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: true,
 | 
			
		||||
			extEnded: true,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 9 supported",
 | 
			
		||||
			fields:   fields{family: Debian, release: "9"},
 | 
			
		||||
@@ -380,14 +388,6 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) {
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 8 supported",
 | 
			
		||||
			fields:   fields{family: Debian, release: "8"},
 | 
			
		||||
			now:      time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: true,
 | 
			
		||||
			extEnded: true,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 11 supported",
 | 
			
		||||
			fields:   fields{family: Debian, release: "11"},
 | 
			
		||||
@@ -397,8 +397,16 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) {
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 12 is not supported yet",
 | 
			
		||||
			name:     "Debian 12 supported",
 | 
			
		||||
			fields:   fields{family: Debian, release: "12"},
 | 
			
		||||
			now:      time.Date(2023, 6, 10, 0, 0, 0, 0, time.UTC),
 | 
			
		||||
			stdEnded: false,
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Debian 13 is not supported yet",
 | 
			
		||||
			fields:   fields{family: Debian, release: "13"},
 | 
			
		||||
			now:      time.Date(2021, 1, 6, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: false,
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
@@ -616,9 +624,25 @@ func TestEOL_IsStandardSupportEnded(t *testing.T) {
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Fedora 38 not found",
 | 
			
		||||
			name:     "Fedora 38 supported",
 | 
			
		||||
			fields:   fields{family: Fedora, release: "38"},
 | 
			
		||||
			now:      time.Date(2023, 12, 15, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			now:      time.Date(2024, 5, 14, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: false,
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Fedora 38 eol since 2024-05-15",
 | 
			
		||||
			fields:   fields{family: Fedora, release: "38"},
 | 
			
		||||
			now:      time.Date(2024, 5, 15, 0, 0, 0, 0, time.UTC),
 | 
			
		||||
			stdEnded: true,
 | 
			
		||||
			extEnded: true,
 | 
			
		||||
			found:    true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name:     "Fedora 39 not found",
 | 
			
		||||
			fields:   fields{family: Fedora, release: "39"},
 | 
			
		||||
			now:      time.Date(2024, 5, 14, 23, 59, 59, 0, time.UTC),
 | 
			
		||||
			stdEnded: false,
 | 
			
		||||
			extEnded: false,
 | 
			
		||||
			found:    false,
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/cenkalti/backoff"
 | 
			
		||||
@@ -218,64 +219,85 @@ func DetectGitHubDependencyGraph(r *models.ScanResult, owner, repo, token string
 | 
			
		||||
	//TODO Proxy
 | 
			
		||||
	httpClient := oauth2.NewClient(context.Background(), src)
 | 
			
		||||
 | 
			
		||||
	return fetchDependencyGraph(r, httpClient, owner, repo, "", "")
 | 
			
		||||
	return fetchDependencyGraph(r, httpClient, owner, repo, "", "", 10, 100)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// recursive function
 | 
			
		||||
func fetchDependencyGraph(r *models.ScanResult, httpClient *http.Client, owner, repo, after, dependenciesAfter string) (err error) {
 | 
			
		||||
func fetchDependencyGraph(r *models.ScanResult, httpClient *http.Client, owner, repo, after, dependenciesAfter string, first, dependenciesFirst int) (err error) {
 | 
			
		||||
	const queryFmt = `{"query":
 | 
			
		||||
	"query { repository(owner:\"%s\", name:\"%s\") { url dependencyGraphManifests(first: %d, withDependencies: true%s) { pageInfo { endCursor hasNextPage } edges { node { blobPath filename repository { url } parseable exceedsMaxSize dependenciesCount dependencies(first: %d%s) { pageInfo { endCursor hasNextPage } edges { node { packageName packageManager repository { url } requirements hasDependencies } } } } } } } }"}`
 | 
			
		||||
 | 
			
		||||
	queryStr := fmt.Sprintf(queryFmt, owner, repo, 50, after, 100, dependenciesAfter)
 | 
			
		||||
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
 | 
			
		||||
	req, err := http.NewRequestWithContext(ctx, http.MethodPost,
 | 
			
		||||
		"https://api.github.com/graphql",
 | 
			
		||||
		bytes.NewBuffer([]byte(queryStr)),
 | 
			
		||||
	)
 | 
			
		||||
	defer cancel()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// https://docs.github.com/en/graphql/overview/schema-previews#access-to-a-repository-s-dependency-graph-preview
 | 
			
		||||
	// TODO remove this header if it is no longer preview status in the future.
 | 
			
		||||
	req.Header.Set("Accept", "application/vnd.github.hawkgirl-preview+json")
 | 
			
		||||
	req.Header.Set("Content-Type", "application/json")
 | 
			
		||||
 | 
			
		||||
	graph := DependencyGraph{}
 | 
			
		||||
	var graph DependencyGraph
 | 
			
		||||
	rateLimitRemaining := 5000
 | 
			
		||||
	count, retryMax := 0, 10
 | 
			
		||||
	countCheck := func(err error) error {
 | 
			
		||||
	retryCheck := func(err error) error {
 | 
			
		||||
		if count == retryMax {
 | 
			
		||||
			return backoff.Permanent(err)
 | 
			
		||||
		}
 | 
			
		||||
		if rateLimitRemaining == 0 {
 | 
			
		||||
			// The GraphQL API rate limit is 5,000 points per hour.
 | 
			
		||||
			// Terminate with an error on rate limit reached.
 | 
			
		||||
			return backoff.Permanent(errof.New(errof.ErrFailedToAccessGithubAPI,
 | 
			
		||||
				fmt.Sprintf("rate limit exceeded. error: %s", err.Error())))
 | 
			
		||||
		}
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	operation := func() error {
 | 
			
		||||
		count++
 | 
			
		||||
		queryStr := fmt.Sprintf(queryFmt, owner, repo, first, after, dependenciesFirst, dependenciesAfter)
 | 
			
		||||
		req, err := http.NewRequestWithContext(ctx, http.MethodPost,
 | 
			
		||||
			"https://api.github.com/graphql",
 | 
			
		||||
			bytes.NewBuffer([]byte(queryStr)),
 | 
			
		||||
		)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return retryCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// https://docs.github.com/en/graphql/overview/schema-previews#access-to-a-repository-s-dependency-graph-preview
 | 
			
		||||
		// TODO remove this header if it is no longer preview status in the future.
 | 
			
		||||
		req.Header.Set("Accept", "application/vnd.github.hawkgirl-preview+json")
 | 
			
		||||
		req.Header.Set("Content-Type", "application/json")
 | 
			
		||||
 | 
			
		||||
		resp, err := httpClient.Do(req)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return countCheck(err)
 | 
			
		||||
			return retryCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
		defer resp.Body.Close()
 | 
			
		||||
 | 
			
		||||
		body, err := io.ReadAll(resp.Body)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return countCheck(err)
 | 
			
		||||
		// https://docs.github.com/en/graphql/overview/resource-limitations#rate-limit
 | 
			
		||||
		if rateLimitRemaining, err = strconv.Atoi(resp.Header.Get("X-RateLimit-Remaining")); err != nil {
 | 
			
		||||
			// If the header retrieval fails, rateLimitRemaining will be set to 0,
 | 
			
		||||
			// preventing further retries. To enable retry, we reset it to 5000.
 | 
			
		||||
			rateLimitRemaining = 5000
 | 
			
		||||
			return retryCheck(errof.New(errof.ErrFailedToAccessGithubAPI, "Failed to get X-RateLimit-Remaining header"))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		body, err := io.ReadAll(resp.Body)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return retryCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		graph = DependencyGraph{}
 | 
			
		||||
		if err := json.Unmarshal(body, &graph); err != nil {
 | 
			
		||||
			return countCheck(err)
 | 
			
		||||
			return retryCheck(err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(graph.Errors) > 0 || graph.Data.Repository.URL == "" {
 | 
			
		||||
			return countCheck(errof.New(errof.ErrFailedToAccessGithubAPI,
 | 
			
		||||
				fmt.Sprintf("Failed to access to GitHub API. Response: %s", string(body))))
 | 
			
		||||
			// this mainly occurs on timeout
 | 
			
		||||
			// reduce the number of dependencies to be fetched for the next retry
 | 
			
		||||
			if dependenciesFirst > 50 {
 | 
			
		||||
				dependenciesFirst -= 5
 | 
			
		||||
			}
 | 
			
		||||
			return retryCheck(errof.New(errof.ErrFailedToAccessGithubAPI,
 | 
			
		||||
				fmt.Sprintf("Failed to access to GitHub API. Repository: %s/%s; Response: %s", owner, repo, string(body))))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	notify := func(err error, t time.Duration) {
 | 
			
		||||
		logging.Log.Warnf("Failed trial (count: %d). retrying in %s. err: %+v", count, t, err)
 | 
			
		||||
		logging.Log.Warnf("Failed attempts (count: %d). retrying in %s. err: %+v", count, t, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err = backoff.RetryNotify(operation, backoff.NewExponentialBackOff(), notify); err != nil {
 | 
			
		||||
@@ -308,12 +330,12 @@ func fetchDependencyGraph(r *models.ScanResult, httpClient *http.Client, owner,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if dependenciesAfter != "" {
 | 
			
		||||
		return fetchDependencyGraph(r, httpClient, owner, repo, after, dependenciesAfter)
 | 
			
		||||
		return fetchDependencyGraph(r, httpClient, owner, repo, after, dependenciesAfter, first, dependenciesFirst)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if graph.Data.Repository.DependencyGraphManifests.PageInfo.HasNextPage {
 | 
			
		||||
		after = fmt.Sprintf(`, after: \"%s\"`, graph.Data.Repository.DependencyGraphManifests.PageInfo.EndCursor)
 | 
			
		||||
		return fetchDependencyGraph(r, httpClient, owner, repo, after, dependenciesAfter)
 | 
			
		||||
		return fetchDependencyGraph(r, httpClient, owner, repo, after, dependenciesAfter, first, dependenciesFirst)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								go.mod
									
									
									
									
									
								
							@@ -4,14 +4,14 @@ go 1.20
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/Azure/azure-sdk-for-go v68.0.0+incompatible
 | 
			
		||||
	github.com/BurntSushi/toml v1.2.1
 | 
			
		||||
	github.com/BurntSushi/toml v1.3.2
 | 
			
		||||
	github.com/CycloneDX/cyclonedx-go v0.7.1
 | 
			
		||||
	github.com/Ullaakut/nmap/v2 v2.2.2
 | 
			
		||||
	github.com/aquasecurity/go-dep-parser v0.0.0-20221114145626-35ef808901e8
 | 
			
		||||
	github.com/aquasecurity/trivy v0.35.0
 | 
			
		||||
	github.com/aquasecurity/trivy-db v0.0.0-20220627104749-930461748b63
 | 
			
		||||
	github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
 | 
			
		||||
	github.com/aws/aws-sdk-go v1.44.259
 | 
			
		||||
	github.com/aws/aws-sdk-go v1.44.300
 | 
			
		||||
	github.com/c-robinson/iplib v1.0.6
 | 
			
		||||
	github.com/cenkalti/backoff v2.2.1+incompatible
 | 
			
		||||
	github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b
 | 
			
		||||
@@ -40,26 +40,26 @@ require (
 | 
			
		||||
	github.com/pkg/errors v0.9.1
 | 
			
		||||
	github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
 | 
			
		||||
	github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
 | 
			
		||||
	github.com/sirupsen/logrus v1.9.0
 | 
			
		||||
	github.com/sirupsen/logrus v1.9.3
 | 
			
		||||
	github.com/spf13/cobra v1.7.0
 | 
			
		||||
	github.com/vulsio/go-cti v0.0.3
 | 
			
		||||
	github.com/vulsio/go-cve-dictionary v0.8.4
 | 
			
		||||
	github.com/vulsio/go-exploitdb v0.4.5
 | 
			
		||||
	github.com/vulsio/go-kev v0.1.2
 | 
			
		||||
	github.com/vulsio/go-msfdb v0.2.2
 | 
			
		||||
	github.com/vulsio/gost v0.4.3
 | 
			
		||||
	github.com/vulsio/gost v0.4.4
 | 
			
		||||
	github.com/vulsio/goval-dictionary v0.9.2
 | 
			
		||||
	go.etcd.io/bbolt v1.3.7
 | 
			
		||||
	golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
 | 
			
		||||
	golang.org/x/oauth2 v0.7.0
 | 
			
		||||
	golang.org/x/oauth2 v0.8.0
 | 
			
		||||
	golang.org/x/sync v0.2.0
 | 
			
		||||
	golang.org/x/text v0.9.0
 | 
			
		||||
	golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	cloud.google.com/go v0.105.0 // indirect
 | 
			
		||||
	cloud.google.com/go/compute v1.14.0 // indirect
 | 
			
		||||
	cloud.google.com/go v0.107.0 // indirect
 | 
			
		||||
	cloud.google.com/go/compute v1.15.1 // indirect
 | 
			
		||||
	cloud.google.com/go/compute/metadata v0.2.3 // indirect
 | 
			
		||||
	cloud.google.com/go/iam v0.8.0 // indirect
 | 
			
		||||
	cloud.google.com/go/storage v1.27.0 // indirect
 | 
			
		||||
@@ -87,7 +87,7 @@ require (
 | 
			
		||||
	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 | 
			
		||||
	github.com/dnaeon/go-vcr v1.2.0 // indirect
 | 
			
		||||
	github.com/docker/cli v20.10.20+incompatible // indirect
 | 
			
		||||
	github.com/docker/distribution v2.8.1+incompatible // indirect
 | 
			
		||||
	github.com/docker/distribution v2.8.2+incompatible // indirect
 | 
			
		||||
	github.com/docker/docker v23.0.4+incompatible // indirect
 | 
			
		||||
	github.com/docker/docker-credential-helpers v0.7.0 // indirect
 | 
			
		||||
	github.com/dustin/go-humanize v1.0.1 // indirect
 | 
			
		||||
@@ -172,8 +172,8 @@ require (
 | 
			
		||||
	golang.org/x/tools v0.9.1 // indirect
 | 
			
		||||
	google.golang.org/api v0.107.0 // indirect
 | 
			
		||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
			
		||||
	google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
 | 
			
		||||
	google.golang.org/grpc v1.52.0 // indirect
 | 
			
		||||
	google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f // indirect
 | 
			
		||||
	google.golang.org/grpc v1.53.0 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.28.1 // indirect
 | 
			
		||||
	gopkg.in/ini.v1 v1.67.0 // indirect
 | 
			
		||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										40
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								go.sum
									
									
									
									
									
								
							@@ -32,8 +32,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
 | 
			
		||||
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
 | 
			
		||||
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
 | 
			
		||||
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
 | 
			
		||||
cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y=
 | 
			
		||||
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
 | 
			
		||||
cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww=
 | 
			
		||||
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
 | 
			
		||||
cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
 | 
			
		||||
cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
 | 
			
		||||
cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
 | 
			
		||||
@@ -70,8 +70,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz
 | 
			
		||||
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
 | 
			
		||||
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
 | 
			
		||||
cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
 | 
			
		||||
cloud.google.com/go/compute v1.14.0 h1:hfm2+FfxVmnRlh6LpB7cg1ZNU+5edAHmW679JePztk0=
 | 
			
		||||
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
 | 
			
		||||
cloud.google.com/go/compute v1.15.1 h1:7UGq3QknM33pw5xATlpzeoomNxsacIVvTqTTvbfajmE=
 | 
			
		||||
cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA=
 | 
			
		||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
 | 
			
		||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
 | 
			
		||||
cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=
 | 
			
		||||
@@ -217,8 +217,8 @@ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbt
 | 
			
		||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
 | 
			
		||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
 | 
			
		||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
			
		||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
 | 
			
		||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 | 
			
		||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
 | 
			
		||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 | 
			
		||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 | 
			
		||||
github.com/CycloneDX/cyclonedx-go v0.7.1 h1:5w1SxjGm9MTMNTuRbEPyw21ObdbaagTWF/KfF0qHTRE=
 | 
			
		||||
github.com/CycloneDX/cyclonedx-go v0.7.1/go.mod h1:N/nrdWQI2SIjaACyyDs/u7+ddCkyl/zkNs8xFsHF2Ps=
 | 
			
		||||
@@ -271,8 +271,8 @@ github.com/aquasecurity/trivy-db v0.0.0-20220627104749-930461748b63/go.mod h1:/n
 | 
			
		||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
 | 
			
		||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 | 
			
		||||
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
 | 
			
		||||
github.com/aws/aws-sdk-go v1.44.259 h1:7yDn1dcv4DZFMKpu+2exIH5O6ipNj9qXrKfdMUaIJwY=
 | 
			
		||||
github.com/aws/aws-sdk-go v1.44.259/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
			
		||||
github.com/aws/aws-sdk-go v1.44.300 h1:Zn+3lqgYahIf9yfrwZ+g+hq/c3KzUBaQ8wqY/ZXiAbY=
 | 
			
		||||
github.com/aws/aws-sdk-go v1.44.300/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 | 
			
		||||
github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk=
 | 
			
		||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
 | 
			
		||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 | 
			
		||||
@@ -330,8 +330,8 @@ github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
 | 
			
		||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
 | 
			
		||||
github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4=
 | 
			
		||||
github.com/docker/cli v20.10.20+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 | 
			
		||||
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
 | 
			
		||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
			
		||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
 | 
			
		||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 | 
			
		||||
github.com/docker/docker v23.0.4+incompatible h1:Kd3Bh9V/rO+XpTP/BLqM+gx8z7+Yb0AA2Ibj+nNo4ek=
 | 
			
		||||
github.com/docker/docker v23.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 | 
			
		||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
 | 
			
		||||
@@ -733,8 +733,8 @@ github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXY
 | 
			
		||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 | 
			
		||||
github.com/sigstore/rekor v1.0.0 h1:64IeShnl8n862APKu4MyDObAOjwNL//je6okig4uQw8=
 | 
			
		||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
 | 
			
		||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
 | 
			
		||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 | 
			
		||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
 | 
			
		||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
 | 
			
		||||
github.com/smartystreets/assertions v1.13.0 h1:Dx1kYM01xsSqKPno3aqLnrwac2LetPvN23diwyr69Qs=
 | 
			
		||||
github.com/smartystreets/assertions v1.13.0/go.mod h1:wDmR7qL282YbGsPy6H/yAsesrxfxaaSlJazyFLYVFx8=
 | 
			
		||||
github.com/smartystreets/goconvey v1.8.0 h1:Oi49ha/2MURE0WexF052Z0m+BNSGirfjg5RL+JXWq3w=
 | 
			
		||||
@@ -789,8 +789,8 @@ github.com/vulsio/go-kev v0.1.2 h1:ZWnRqXJy/PrfGs89s9W8ilgi/Qzfgb5x5R4knLdiSKo=
 | 
			
		||||
github.com/vulsio/go-kev v0.1.2/go.mod h1:xtrcsLfNO8xQI1jAjdIQell3/8ntCl8JBDd1fzEGPIk=
 | 
			
		||||
github.com/vulsio/go-msfdb v0.2.2 h1:rb82u++5QZyCjcTxqQLMHGe/Ngtp0SFCl4+VauY5DBM=
 | 
			
		||||
github.com/vulsio/go-msfdb v0.2.2/go.mod h1:lSpy43aBU6bdU09Kl+3531s2ihZbxdqw6hbTyqDzgIc=
 | 
			
		||||
github.com/vulsio/gost v0.4.3 h1:jr5HBRd7aPqChnFrW2zi0k9wJbng9Ss7P/IceEbP13A=
 | 
			
		||||
github.com/vulsio/gost v0.4.3/go.mod h1:HJJrb/9Q126yN5wDfwnkUVzRjOGotx1mllYDetLijDQ=
 | 
			
		||||
github.com/vulsio/gost v0.4.4 h1:nmYSaMjhW3V4gTtZ34O+/ZHSzXpLrhwO0EAHkCCmNgQ=
 | 
			
		||||
github.com/vulsio/gost v0.4.4/go.mod h1:HJJrb/9Q126yN5wDfwnkUVzRjOGotx1mllYDetLijDQ=
 | 
			
		||||
github.com/vulsio/goval-dictionary v0.9.2 h1:HTgCbrBsqDrI9lFb8CDpAdQrRaWr9BLG8IeQRHCAbmo=
 | 
			
		||||
github.com/vulsio/goval-dictionary v0.9.2/go.mod h1:SUhZkgjGkwdNyIJQRrXhQKbav3xaC8GEHqw3ojdVkrg=
 | 
			
		||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
 | 
			
		||||
@@ -964,8 +964,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
 | 
			
		||||
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
 | 
			
		||||
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
 | 
			
		||||
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
 | 
			
		||||
golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
 | 
			
		||||
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
 | 
			
		||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
			
		||||
@@ -1308,8 +1308,8 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw
 | 
			
		||||
google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef h1:uQ2vjV/sHTsWSqdKeLqmwitzgvjMl7o4IdtHwUDXSJY=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f h1:BWUVssLB0HVOSY78gIdvk1dTVYtT1y8SBWtPYuTJ/6w=
 | 
			
		||||
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
 | 
			
		||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 | 
			
		||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
 | 
			
		||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
 | 
			
		||||
@@ -1345,8 +1345,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
 | 
			
		||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 | 
			
		||||
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 | 
			
		||||
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
 | 
			
		||||
google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
 | 
			
		||||
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
 | 
			
		||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
 | 
			
		||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
 | 
			
		||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
 | 
			
		||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@ func (deb Debian) supported(major string) bool {
 | 
			
		||||
		"9":  "stretch",
 | 
			
		||||
		"10": "buster",
 | 
			
		||||
		"11": "bullseye",
 | 
			
		||||
		// "12": "bookworm",
 | 
			
		||||
		"12": "bookworm",
 | 
			
		||||
		// "13": "trixie",
 | 
			
		||||
		// "14": "forky",
 | 
			
		||||
	}[major]
 | 
			
		||||
 
 | 
			
		||||
@@ -45,9 +45,9 @@ func TestDebian_Supported(t *testing.T) {
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "12 is not supported yet",
 | 
			
		||||
			name: "12 is supported",
 | 
			
		||||
			args: "12",
 | 
			
		||||
			want: false,
 | 
			
		||||
			want: true,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "13 is not supported yet",
 | 
			
		||||
 
 | 
			
		||||
@@ -270,6 +270,7 @@ func (ubu Ubuntu) detect(cves map[string]gostmodels.UbuntuCVE, fixed bool, srcPk
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(c.fixStatuses) > 0 {
 | 
			
		||||
			c.fixStatuses.Sort()
 | 
			
		||||
			contents = append(contents, c)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -236,10 +236,13 @@ func (ps PackageFixStatuses) Store(pkg PackageFixStatus) PackageFixStatuses {
 | 
			
		||||
	return ps
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Sort by Name
 | 
			
		||||
// Sort by Name asc, FixedIn desc
 | 
			
		||||
func (ps PackageFixStatuses) Sort() {
 | 
			
		||||
	sort.Slice(ps, func(i, j int) bool {
 | 
			
		||||
		return ps[i].Name < ps[j].Name
 | 
			
		||||
		if ps[i].Name != ps[j].Name {
 | 
			
		||||
			return ps[i].Name < ps[j].Name
 | 
			
		||||
		}
 | 
			
		||||
		return ps[j].FixedIn < ps[i].FixedIn
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -991,6 +991,28 @@ func TestSortPackageStatues(t *testing.T) {
 | 
			
		||||
				{Name: "b"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: PackageFixStatuses{
 | 
			
		||||
				{
 | 
			
		||||
					Name:    "libzstd1",
 | 
			
		||||
					FixedIn: "1.3.1+dfsg-1~ubuntu0.16.04.1+esm1",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Name:    "libzstd1",
 | 
			
		||||
					FixedIn: "1.3.1+dfsg-1~ubuntu0.16.04.1+esm2",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			out: PackageFixStatuses{
 | 
			
		||||
				{
 | 
			
		||||
					Name:    "libzstd1",
 | 
			
		||||
					FixedIn: "1.3.1+dfsg-1~ubuntu0.16.04.1+esm2",
 | 
			
		||||
				},
 | 
			
		||||
				{
 | 
			
		||||
					Name:    "libzstd1",
 | 
			
		||||
					FixedIn: "1.3.1+dfsg-1~ubuntu0.16.04.1+esm1",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		tt.in.Sort()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								oval/util.go
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								oval/util.go
									
									
									
									
									
								
							@@ -113,24 +113,13 @@ func getDefsByPackNameViaHTTP(r *models.ScanResult, url string) (relatedDefs ova
 | 
			
		||||
		ovalRelease = strings.TrimPrefix(r.Release, "stream")
 | 
			
		||||
	case constant.Amazon:
 | 
			
		||||
		switch s := strings.Fields(r.Release)[0]; s {
 | 
			
		||||
		case "1":
 | 
			
		||||
			ovalRelease = "1"
 | 
			
		||||
		case "2":
 | 
			
		||||
			ovalRelease = "2"
 | 
			
		||||
		case "2022":
 | 
			
		||||
			ovalRelease = "2022"
 | 
			
		||||
		case "2023":
 | 
			
		||||
			ovalRelease = "2023"
 | 
			
		||||
		case "2025":
 | 
			
		||||
			ovalRelease = "2025"
 | 
			
		||||
		case "2027":
 | 
			
		||||
			ovalRelease = "2027"
 | 
			
		||||
		case "2029":
 | 
			
		||||
			ovalRelease = "2029"
 | 
			
		||||
		case "1", "2", "2022", "2023", "2025", "2027", "2029":
 | 
			
		||||
			ovalRelease = s
 | 
			
		||||
		default:
 | 
			
		||||
			if _, err := time.Parse("2006.01", s); err == nil {
 | 
			
		||||
				ovalRelease = "1"
 | 
			
		||||
			if _, err := time.Parse("2006.01", s); err != nil {
 | 
			
		||||
				return relatedDefs, xerrors.Errorf(`Failed to detect amazon version. err: unexpected Amazon Linux 1 version format. expected: "yyyy.MM", actual: "%s". err: %w`, s, err)
 | 
			
		||||
			}
 | 
			
		||||
			ovalRelease = "1"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -287,24 +276,13 @@ func getDefsByPackNameFromOvalDB(r *models.ScanResult, driver ovaldb.DB) (relate
 | 
			
		||||
		ovalRelease = strings.TrimPrefix(r.Release, "stream")
 | 
			
		||||
	case constant.Amazon:
 | 
			
		||||
		switch s := strings.Fields(r.Release)[0]; s {
 | 
			
		||||
		case "1":
 | 
			
		||||
			ovalRelease = "1"
 | 
			
		||||
		case "2":
 | 
			
		||||
			ovalRelease = "2"
 | 
			
		||||
		case "2022":
 | 
			
		||||
			ovalRelease = "2022"
 | 
			
		||||
		case "2023":
 | 
			
		||||
			ovalRelease = "2023"
 | 
			
		||||
		case "2025":
 | 
			
		||||
			ovalRelease = "2025"
 | 
			
		||||
		case "2027":
 | 
			
		||||
			ovalRelease = "2027"
 | 
			
		||||
		case "2029":
 | 
			
		||||
			ovalRelease = "2029"
 | 
			
		||||
		case "1", "2", "2022", "2023", "2025", "2027", "2029":
 | 
			
		||||
			ovalRelease = s
 | 
			
		||||
		default:
 | 
			
		||||
			if _, err := time.Parse("2006.01", s); err == nil {
 | 
			
		||||
				ovalRelease = "1"
 | 
			
		||||
			if _, err := time.Parse("2006.01", s); err != nil {
 | 
			
		||||
				return relatedDefs, xerrors.Errorf(`Failed to detect amazon version. err: unexpected Amazon Linux 1 version format. expected: "yyyy.MM", actual: "%s". err: %w`, s, err)
 | 
			
		||||
			}
 | 
			
		||||
			ovalRelease = "1"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -139,7 +139,6 @@ func (l *base) runningKernel() (release, version string, err error) {
 | 
			
		||||
			version = ss[6]
 | 
			
		||||
		}
 | 
			
		||||
		if _, err := debver.NewVersion(version); err != nil {
 | 
			
		||||
			l.log.Warnf("kernel running version is invalid. skip kernel vulnerability detection. actual kernel version: %s, err: %s", version, err)
 | 
			
		||||
			version = ""
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -1306,10 +1305,15 @@ func (l *base) parseGrepProcMap(stdout string) (soPaths []string) {
 | 
			
		||||
	return soPaths
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var errLSOFNoInternetFiles = xerrors.New("no Internet files located")
 | 
			
		||||
 | 
			
		||||
func (l *base) lsOfListen() (string, error) {
 | 
			
		||||
	cmd := `lsof -i -P -n`
 | 
			
		||||
	cmd := `lsof -i -P -n -V`
 | 
			
		||||
	r := l.exec(util.PrependProxyEnv(cmd), sudo)
 | 
			
		||||
	if !r.isSuccess() {
 | 
			
		||||
		if strings.TrimSpace(r.Stdout) == "lsof: no Internet files located" {
 | 
			
		||||
			return "", xerrors.Errorf("Failed to lsof: %w", errLSOFNoInternetFiles)
 | 
			
		||||
		}
 | 
			
		||||
		return "", xerrors.Errorf("Failed to lsof: %s", r)
 | 
			
		||||
	}
 | 
			
		||||
	return r.Stdout, nil
 | 
			
		||||
@@ -1365,7 +1369,7 @@ func (l *base) pkgPs(getOwnerPkgs func([]string) ([]string, error)) error {
 | 
			
		||||
 | 
			
		||||
	pidListenPorts := map[string][]models.PortStat{}
 | 
			
		||||
	stdout, err = l.lsOfListen()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
	if err != nil && !xerrors.Is(err, errLSOFNoInternetFiles) {
 | 
			
		||||
		// warning only, continue scanning
 | 
			
		||||
		l.log.Warnf("Failed to lsof: %+v", err)
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -519,28 +519,7 @@ func (o *redhatBase) parseInstalledPackages(stdout string) (models.Packages, mod
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var (
 | 
			
		||||
			pack *models.Package
 | 
			
		||||
			err  error
 | 
			
		||||
		)
 | 
			
		||||
		switch o.getDistro().Family {
 | 
			
		||||
		case constant.Amazon:
 | 
			
		||||
			switch strings.Fields(o.getDistro().Release)[0] {
 | 
			
		||||
			case "2":
 | 
			
		||||
				switch len(strings.Fields(line)) {
 | 
			
		||||
				case 5:
 | 
			
		||||
					pack, err = o.parseInstalledPackagesLine(line)
 | 
			
		||||
				case 6:
 | 
			
		||||
					pack, err = o.parseInstalledPackagesLineFromRepoquery(line)
 | 
			
		||||
				default:
 | 
			
		||||
					return nil, nil, xerrors.Errorf("Failed to parse package line: %s", line)
 | 
			
		||||
				}
 | 
			
		||||
			default:
 | 
			
		||||
				pack, err = o.parseInstalledPackagesLine(line)
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			pack, err = o.parseInstalledPackagesLine(line)
 | 
			
		||||
		}
 | 
			
		||||
		pack, err := o.parseInstalledPackagesLine(line)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, nil, err
 | 
			
		||||
		}
 | 
			
		||||
@@ -572,30 +551,7 @@ func (o *redhatBase) parseInstalledPackages(stdout string) (models.Packages, mod
 | 
			
		||||
 | 
			
		||||
func (o *redhatBase) parseInstalledPackagesLine(line string) (*models.Package, error) {
 | 
			
		||||
	fields := strings.Fields(line)
 | 
			
		||||
	if len(fields) != 5 {
 | 
			
		||||
		return nil,
 | 
			
		||||
			xerrors.Errorf("Failed to parse package line: %s", line)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ver := ""
 | 
			
		||||
	epoch := fields[1]
 | 
			
		||||
	if epoch == "0" || epoch == "(none)" {
 | 
			
		||||
		ver = fields[2]
 | 
			
		||||
	} else {
 | 
			
		||||
		ver = fmt.Sprintf("%s:%s", epoch, fields[2])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &models.Package{
 | 
			
		||||
		Name:    fields[0],
 | 
			
		||||
		Version: ver,
 | 
			
		||||
		Release: fields[3],
 | 
			
		||||
		Arch:    fields[4],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *redhatBase) parseInstalledPackagesLineFromRepoquery(line string) (*models.Package, error) {
 | 
			
		||||
	fields := strings.Fields(line)
 | 
			
		||||
	if len(fields) != 6 {
 | 
			
		||||
	if len(fields) < 5 {
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to parse package line: %s", line)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -607,9 +563,22 @@ func (o *redhatBase) parseInstalledPackagesLineFromRepoquery(line string) (*mode
 | 
			
		||||
		ver = fmt.Sprintf("%s:%s", epoch, fields[2])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	repo := strings.TrimPrefix(fields[5], "@")
 | 
			
		||||
	if repo == "installed" {
 | 
			
		||||
		repo = "amzn2-core"
 | 
			
		||||
	var repo string
 | 
			
		||||
	switch o.getDistro().Family {
 | 
			
		||||
	case constant.Amazon:
 | 
			
		||||
		switch strings.Fields(o.getDistro().Release)[0] {
 | 
			
		||||
		case "2":
 | 
			
		||||
			if len(fields) == 5 {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			if fields[5] == "installed" {
 | 
			
		||||
				repo = "amzn2-core"
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			repo = strings.TrimPrefix(fields[5], "@")
 | 
			
		||||
		default:
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &models.Package{
 | 
			
		||||
 
 | 
			
		||||
@@ -118,32 +118,6 @@ kernel-devel 0 2.6.32 695.20.3.el6 x86_64`,
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: `openssl	0	1.0.1e	30.el6.11 x86_64
 | 
			
		||||
Percona-Server-shared-56	1	5.6.19	rel67.0.el6 x84_64
 | 
			
		||||
kernel 0 2.6.32 696.20.1.el6 x86_64
 | 
			
		||||
kernel 0 2.6.32 696.20.3.el6 x86_64
 | 
			
		||||
kernel 0 2.6.32 695.20.3.el6 x86_64`,
 | 
			
		||||
			distro: config.Distro{Family: constant.Amazon, Release: "2 (Karoo)"},
 | 
			
		||||
			kernel: models.Kernel{},
 | 
			
		||||
			packages: models.Packages{
 | 
			
		||||
				"openssl": models.Package{
 | 
			
		||||
					Name:    "openssl",
 | 
			
		||||
					Version: "1.0.1e",
 | 
			
		||||
					Release: "30.el6.11",
 | 
			
		||||
				},
 | 
			
		||||
				"Percona-Server-shared-56": models.Package{
 | 
			
		||||
					Name:    "Percona-Server-shared-56",
 | 
			
		||||
					Version: "1:5.6.19",
 | 
			
		||||
					Release: "rel67.0.el6",
 | 
			
		||||
				},
 | 
			
		||||
				"kernel": models.Package{
 | 
			
		||||
					Name:    "kernel",
 | 
			
		||||
					Version: "2.6.32",
 | 
			
		||||
					Release: "696.20.3.el6",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: `yum-utils 0 1.1.31 46.amzn2.0.1 noarch @amzn2-core
 | 
			
		||||
zlib 0 1.2.7 19.amzn2.0.1 x86_64 installed
 | 
			
		||||
@@ -195,67 +169,52 @@ java-1.8.0-amazon-corretto 1 1.8.0_192.b12 1.amzn2 x86_64 @amzn2extra-corretto8`
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
func TestParseInstalledPackagesLine(t *testing.T) {
 | 
			
		||||
	r := newRHEL(config.ServerInfo{})
 | 
			
		||||
 | 
			
		||||
	var packagetests = []struct {
 | 
			
		||||
		in   string
 | 
			
		||||
		pack models.Package
 | 
			
		||||
		err  bool
 | 
			
		||||
func Test_redhatBase_parseInstalledPackagesLine(t *testing.T) {
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name    string
 | 
			
		||||
		distro  config.Distro
 | 
			
		||||
		line    string
 | 
			
		||||
		want    *models.Package
 | 
			
		||||
		wantErr bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			"openssl	0	1.0.1e	30.el6.11 x86_64",
 | 
			
		||||
			models.Package{
 | 
			
		||||
			name: "rpm -qa redhat 6.11 1",
 | 
			
		||||
			distro: config.Distro{
 | 
			
		||||
				Family:  constant.RedHat,
 | 
			
		||||
				Release: "6.11",
 | 
			
		||||
			},
 | 
			
		||||
			line: "openssl	0	1.0.1e	30.el6.11 x86_64",
 | 
			
		||||
			want: &models.Package{
 | 
			
		||||
				Name:    "openssl",
 | 
			
		||||
				Version: "1.0.1e",
 | 
			
		||||
				Release: "30.el6.11",
 | 
			
		||||
				Arch:    "x86_64",
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			"Percona-Server-shared-56	1	5.6.19	rel67.0.el6 x84_64",
 | 
			
		||||
			models.Package{
 | 
			
		||||
			name: "rpm -qa redhat 6.11 2",
 | 
			
		||||
			distro: config.Distro{
 | 
			
		||||
				Family:  constant.RedHat,
 | 
			
		||||
				Release: "6.11",
 | 
			
		||||
			},
 | 
			
		||||
			line: "Percona-Server-shared-56	1	5.6.19	rel67.0.el6 x84_64",
 | 
			
		||||
			want: &models.Package{
 | 
			
		||||
				Name:    "Percona-Server-shared-56",
 | 
			
		||||
				Version: "1:5.6.19",
 | 
			
		||||
				Release: "rel67.0.el6",
 | 
			
		||||
				Arch:    "x84_64",
 | 
			
		||||
			},
 | 
			
		||||
			false,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, tt := range packagetests {
 | 
			
		||||
		p, err := r.parseInstalledPackagesLine(tt.in)
 | 
			
		||||
		if err == nil && tt.err {
 | 
			
		||||
			t.Errorf("Expected err not occurred: %d", i)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil && !tt.err {
 | 
			
		||||
			t.Errorf("UnExpected err not occurred: %d", i)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Name != tt.pack.Name {
 | 
			
		||||
			t.Errorf("name: expected %s, actual %s", tt.pack.Name, p.Name)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Version != tt.pack.Version {
 | 
			
		||||
			t.Errorf("version: expected %s, actual %s", tt.pack.Version, p.Version)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Release != tt.pack.Release {
 | 
			
		||||
			t.Errorf("release: expected %s, actual %s", tt.pack.Release, p.Release)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) {
 | 
			
		||||
	r := newRHEL(config.ServerInfo{})
 | 
			
		||||
 | 
			
		||||
	var packagetests = []struct {
 | 
			
		||||
		in   string
 | 
			
		||||
		pack models.Package
 | 
			
		||||
		err  bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			in: "yum-utils 0 1.1.31 46.amzn2.0.1 noarch @amzn2-core",
 | 
			
		||||
			pack: models.Package{
 | 
			
		||||
			name: "rpmquery amazonlinux 2 1",
 | 
			
		||||
			distro: config.Distro{
 | 
			
		||||
				Family:  constant.Amazon,
 | 
			
		||||
				Release: "2",
 | 
			
		||||
			},
 | 
			
		||||
			line: "yum-utils 0 1.1.31 46.amzn2.0.1 noarch @amzn2-core",
 | 
			
		||||
			want: &models.Package{
 | 
			
		||||
				Name:       "yum-utils",
 | 
			
		||||
				Version:    "1.1.31",
 | 
			
		||||
				Release:    "46.amzn2.0.1",
 | 
			
		||||
@@ -264,8 +223,13 @@ func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: "zlib 0 1.2.7 19.amzn2.0.1 x86_64 installed",
 | 
			
		||||
			pack: models.Package{
 | 
			
		||||
			name: "rpmquery amazonlinux 2 2",
 | 
			
		||||
			distro: config.Distro{
 | 
			
		||||
				Family:  constant.Amazon,
 | 
			
		||||
				Release: "2",
 | 
			
		||||
			},
 | 
			
		||||
			line: "zlib 0 1.2.7 19.amzn2.0.1 x86_64 installed",
 | 
			
		||||
			want: &models.Package{
 | 
			
		||||
				Name:       "zlib",
 | 
			
		||||
				Version:    "1.2.7",
 | 
			
		||||
				Release:    "19.amzn2.0.1",
 | 
			
		||||
@@ -274,8 +238,13 @@ func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			in: "java-1.8.0-amazon-corretto 1 1.8.0_192.b12 1.amzn2 x86_64 @amzn2extra-corretto8",
 | 
			
		||||
			pack: models.Package{
 | 
			
		||||
			name: "rpmquery amazonlinux 2 3",
 | 
			
		||||
			distro: config.Distro{
 | 
			
		||||
				Family:  constant.Amazon,
 | 
			
		||||
				Release: "2",
 | 
			
		||||
			},
 | 
			
		||||
			line: "java-1.8.0-amazon-corretto 1 1.8.0_192.b12 1.amzn2 x86_64 @amzn2extra-corretto8",
 | 
			
		||||
			want: &models.Package{
 | 
			
		||||
				Name:       "java-1.8.0-amazon-corretto",
 | 
			
		||||
				Version:    "1:1.8.0_192.b12",
 | 
			
		||||
				Release:    "1.amzn2",
 | 
			
		||||
@@ -284,32 +253,18 @@ func TestParseInstalledPackagesLineFromRepoquery(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, tt := range packagetests {
 | 
			
		||||
		p, err := r.parseInstalledPackagesLineFromRepoquery(tt.in)
 | 
			
		||||
		if err == nil && tt.err {
 | 
			
		||||
			t.Errorf("Expected err not occurred: %d", i)
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil && !tt.err {
 | 
			
		||||
			t.Errorf("UnExpected err not occurred: %d", i)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Name != tt.pack.Name {
 | 
			
		||||
			t.Errorf("name: expected %s, actual %s", tt.pack.Name, p.Name)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Version != tt.pack.Version {
 | 
			
		||||
			t.Errorf("version: expected %s, actual %s", tt.pack.Version, p.Version)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Release != tt.pack.Release {
 | 
			
		||||
			t.Errorf("release: expected %s, actual %s", tt.pack.Release, p.Release)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Arch != tt.pack.Arch {
 | 
			
		||||
			t.Errorf("arch: expected %s, actual %s", tt.pack.Arch, p.Arch)
 | 
			
		||||
		}
 | 
			
		||||
		if p.Repository != tt.pack.Repository {
 | 
			
		||||
			t.Errorf("repository: expected %s, actual %s", tt.pack.Repository, p.Repository)
 | 
			
		||||
		}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			got, err := (&redhatBase{base: base{Distro: tt.distro}}).parseInstalledPackagesLine(tt.line)
 | 
			
		||||
			if (err != nil) != tt.wantErr {
 | 
			
		||||
				t.Errorf("redhatBase.parseInstalledPackagesLine() error = %v, wantErr %v", err, tt.wantErr)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			if !reflect.DeepEqual(got, tt.want) {
 | 
			
		||||
				t.Errorf("redhatBase.parseInstalledPackagesLine() = %v, want %v", got, tt.want)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestParseYumCheckUpdateLine(t *testing.T) {
 | 
			
		||||
 
 | 
			
		||||
@@ -181,17 +181,7 @@ func ViaHTTP(header http.Header, body string, toLocalFile bool) (models.ScanResu
 | 
			
		||||
			kernelVersion = formatKernelVersion(osInfo)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		w := &windows{
 | 
			
		||||
			base: base{
 | 
			
		||||
				Distro: config.Distro{Family: family, Release: release},
 | 
			
		||||
				osPackages: osPackages{
 | 
			
		||||
					Kernel: models.Kernel{Version: kernelVersion},
 | 
			
		||||
				},
 | 
			
		||||
				log: logging.Log,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		kbs, err := w.detectKBsFromKernelVersion()
 | 
			
		||||
		kbs, err := DetectKBsFromKernelVersion(release, kernelVersion)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return models.ScanResult{}, xerrors.Errorf("Failed to detect KBs from kernel version. err: %w", err)
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -1146,7 +1146,7 @@ func (o *windows) scanKBs() (*models.WindowsKB, error) {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kbs, err := o.detectKBsFromKernelVersion()
 | 
			
		||||
	kbs, err := DetectKBsFromKernelVersion(o.getDistro().Release, o.Kernel.Version)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, xerrors.Errorf("Failed to detect KBs from kernel version. err: %w", err)
 | 
			
		||||
	}
 | 
			
		||||
@@ -1397,6 +1397,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "", kb: "5021291"},
 | 
			
		||||
					{revision: "", kb: "5022338"},
 | 
			
		||||
					{revision: "", kb: "5022872"},
 | 
			
		||||
					{revision: "", kb: "5023769"},
 | 
			
		||||
					{revision: "", kb: "5025279"},
 | 
			
		||||
					{revision: "", kb: "5026413"},
 | 
			
		||||
					{revision: "", kb: "5027275"},
 | 
			
		||||
				},
 | 
			
		||||
				securityOnly: []string{
 | 
			
		||||
					"3192391",
 | 
			
		||||
@@ -1476,6 +1480,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					"5021288",
 | 
			
		||||
					"5022339",
 | 
			
		||||
					"5022874",
 | 
			
		||||
					"5023759",
 | 
			
		||||
					"5025277",
 | 
			
		||||
					"5026426",
 | 
			
		||||
					"5027256",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -1600,6 +1608,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "", kb: "5021294"},
 | 
			
		||||
					{revision: "", kb: "5022352"},
 | 
			
		||||
					{revision: "", kb: "5022899"},
 | 
			
		||||
					{revision: "", kb: "5023765"},
 | 
			
		||||
					{revision: "", kb: "5025285"},
 | 
			
		||||
					{revision: "", kb: "5026415"},
 | 
			
		||||
					{revision: "", kb: "5027271"},
 | 
			
		||||
				},
 | 
			
		||||
				securityOnly: []string{
 | 
			
		||||
					"3192392",
 | 
			
		||||
@@ -1678,6 +1690,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					"5021296",
 | 
			
		||||
					"5022346",
 | 
			
		||||
					"5022894",
 | 
			
		||||
					"5023764",
 | 
			
		||||
					"5025288",
 | 
			
		||||
					"5026409",
 | 
			
		||||
					"5027282",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -1803,6 +1819,11 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "19624", kb: "5021243"},
 | 
			
		||||
					{revision: "19685", kb: "5022297"},
 | 
			
		||||
					{revision: "19747", kb: "5022858"},
 | 
			
		||||
					{revision: "19805", kb: "5023713"},
 | 
			
		||||
					{revision: "19869", kb: "5025234"},
 | 
			
		||||
					{revision: "19926", kb: "5026382"},
 | 
			
		||||
					{revision: "19983", kb: "5027230"},
 | 
			
		||||
					{revision: "19986", kb: "5028622"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			// https://support.microsoft.com/en-us/topic/windows-10-update-history-2ad7900f-882c-1dfc-f9d7-82b7ca162010
 | 
			
		||||
@@ -2003,6 +2024,11 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "5582", kb: "5021235"},
 | 
			
		||||
					{revision: "5648", kb: "5022289"},
 | 
			
		||||
					{revision: "5717", kb: "5022838"},
 | 
			
		||||
					{revision: "5786", kb: "5023697"},
 | 
			
		||||
					{revision: "5850", kb: "5025228"},
 | 
			
		||||
					{revision: "5921", kb: "5026363"},
 | 
			
		||||
					{revision: "5989", kb: "5027219"},
 | 
			
		||||
					{revision: "5996", kb: "5028623"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			// https://support.microsoft.com/en-us/topic/windows-10-update-history-83aa43c0-82e0-92d8-1580-10642c9ed612
 | 
			
		||||
@@ -2373,6 +2399,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "3772", kb: "5022554"},
 | 
			
		||||
					{revision: "3887", kb: "5022286"},
 | 
			
		||||
					{revision: "4010", kb: "5022840"},
 | 
			
		||||
					{revision: "4131", kb: "5023702"},
 | 
			
		||||
					{revision: "4252", kb: "5025229"},
 | 
			
		||||
					{revision: "4377", kb: "5026362"},
 | 
			
		||||
					{revision: "4499", kb: "5027222"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			// https://support.microsoft.com/en-us/topic/windows-10-update-history-e6058e7c-4116-38f1-b984-4fcacfba5e5d
 | 
			
		||||
@@ -2602,6 +2632,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "2546", kb: "5019275"},
 | 
			
		||||
					{revision: "2604", kb: "5022834"},
 | 
			
		||||
					{revision: "2673", kb: "5022906"},
 | 
			
		||||
					{revision: "2728", kb: "5023696"},
 | 
			
		||||
					{revision: "2788", kb: "5023773"},
 | 
			
		||||
					{revision: "2846", kb: "5025221"},
 | 
			
		||||
					{revision: "2965", kb: "5026361"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			// https://support.microsoft.com/en-us/topic/windows-10-update-history-1b6aac92-bf01-42b5-b158-f80c6d93eb11
 | 
			
		||||
@@ -2693,6 +2727,11 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "2546", kb: "5019275"},
 | 
			
		||||
					{revision: "2604", kb: "5022834"},
 | 
			
		||||
					{revision: "2673", kb: "5022906"},
 | 
			
		||||
					{revision: "2728", kb: "5023696"},
 | 
			
		||||
					{revision: "2788", kb: "5023773"},
 | 
			
		||||
					{revision: "2846", kb: "5025221"},
 | 
			
		||||
					{revision: "2965", kb: "5026361"},
 | 
			
		||||
					{revision: "3086", kb: "5027215"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			// https://support.microsoft.com/en-us/topic/windows-10-update-history-8127c2c6-6edf-4fdf-8b9f-0f7be1ef3562
 | 
			
		||||
@@ -2707,6 +2746,14 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "2546", kb: "5019275"},
 | 
			
		||||
					{revision: "2604", kb: "5022834"},
 | 
			
		||||
					{revision: "2673", kb: "5022906"},
 | 
			
		||||
					{revision: "2728", kb: "5023696"},
 | 
			
		||||
					{revision: "2788", kb: "5023773"},
 | 
			
		||||
					{revision: "2846", kb: "5025221"},
 | 
			
		||||
					{revision: "2913", kb: "5025297"},
 | 
			
		||||
					{revision: "2965", kb: "5026361"},
 | 
			
		||||
					{revision: "3031", kb: "5026435"},
 | 
			
		||||
					{revision: "3086", kb: "5027215"},
 | 
			
		||||
					{revision: "3155", kb: "5027293"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -2751,6 +2798,14 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "1516", kb: "5019274"},
 | 
			
		||||
					{revision: "1574", kb: "5022836"},
 | 
			
		||||
					{revision: "1641", kb: "5022905"},
 | 
			
		||||
					{revision: "1696", kb: "5023698"},
 | 
			
		||||
					{revision: "1761", kb: "5023774"},
 | 
			
		||||
					{revision: "1817", kb: "5025224"},
 | 
			
		||||
					{revision: "1880", kb: "5025298"},
 | 
			
		||||
					{revision: "1936", kb: "5026368"},
 | 
			
		||||
					{revision: "2003", kb: "5026436"},
 | 
			
		||||
					{revision: "2057", kb: "5027223"},
 | 
			
		||||
					{revision: "2124", kb: "5027292"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			// https://support.microsoft.com/en-us/topic/windows-11-version-22h2-update-history-ec4229c3-9c5f-4e75-9d6d-9025ab70fcce
 | 
			
		||||
@@ -2768,6 +2823,15 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "1105", kb: "5022303"},
 | 
			
		||||
					{revision: "1194", kb: "5022360"},
 | 
			
		||||
					{revision: "1265", kb: "5022845"},
 | 
			
		||||
					{revision: "1344", kb: "5022913"},
 | 
			
		||||
					{revision: "1413", kb: "5023706"},
 | 
			
		||||
					{revision: "1485", kb: "5023778"},
 | 
			
		||||
					{revision: "1555", kb: "5025239"},
 | 
			
		||||
					{revision: "1635", kb: "5025305"},
 | 
			
		||||
					{revision: "1702", kb: "5026372"},
 | 
			
		||||
					{revision: "1778", kb: "5026446"},
 | 
			
		||||
					{revision: "1848", kb: "5027231"},
 | 
			
		||||
					{revision: "1928", kb: "5027303"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -2846,6 +2910,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "", kb: "5021289"},
 | 
			
		||||
					{revision: "", kb: "5022340"},
 | 
			
		||||
					{revision: "", kb: "5022890"},
 | 
			
		||||
					{revision: "", kb: "5023755"},
 | 
			
		||||
					{revision: "", kb: "5025271"},
 | 
			
		||||
					{revision: "", kb: "5026408"},
 | 
			
		||||
					{revision: "", kb: "5027279"},
 | 
			
		||||
				},
 | 
			
		||||
				securityOnly: []string{
 | 
			
		||||
					"4457984",
 | 
			
		||||
@@ -2903,6 +2971,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					"5021293",
 | 
			
		||||
					"5022353",
 | 
			
		||||
					"5022893",
 | 
			
		||||
					"5023754",
 | 
			
		||||
					"5025273",
 | 
			
		||||
					"5026427",
 | 
			
		||||
					"5027277",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -3025,6 +3097,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "", kb: "5021291"},
 | 
			
		||||
					{revision: "", kb: "5022338"},
 | 
			
		||||
					{revision: "", kb: "5022872"},
 | 
			
		||||
					{revision: "", kb: "5023769"},
 | 
			
		||||
					{revision: "", kb: "5025279"},
 | 
			
		||||
					{revision: "", kb: "5026413"},
 | 
			
		||||
					{revision: "", kb: "5027275"},
 | 
			
		||||
				},
 | 
			
		||||
				securityOnly: []string{
 | 
			
		||||
					"3192391",
 | 
			
		||||
@@ -3104,6 +3180,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					"5021288",
 | 
			
		||||
					"5022339",
 | 
			
		||||
					"5022874",
 | 
			
		||||
					"5023759",
 | 
			
		||||
					"5025277",
 | 
			
		||||
					"5026426",
 | 
			
		||||
					"5027256",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -3228,6 +3308,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "", kb: "5021285"},
 | 
			
		||||
					{revision: "", kb: "5022348"},
 | 
			
		||||
					{revision: "", kb: "5022903"},
 | 
			
		||||
					{revision: "", kb: "5023756"},
 | 
			
		||||
					{revision: "", kb: "5025287"},
 | 
			
		||||
					{revision: "", kb: "5026419"},
 | 
			
		||||
					{revision: "", kb: "5027283"},
 | 
			
		||||
				},
 | 
			
		||||
				securityOnly: []string{
 | 
			
		||||
					"3192393",
 | 
			
		||||
@@ -3306,6 +3390,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					"5021303",
 | 
			
		||||
					"5022343",
 | 
			
		||||
					"5022895",
 | 
			
		||||
					"5023752",
 | 
			
		||||
					"5025272",
 | 
			
		||||
					"5026411",
 | 
			
		||||
					"5027281",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -3430,6 +3518,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "", kb: "5021294"},
 | 
			
		||||
					{revision: "", kb: "5022352"},
 | 
			
		||||
					{revision: "", kb: "5022899"},
 | 
			
		||||
					{revision: "", kb: "5023765"},
 | 
			
		||||
					{revision: "", kb: "5025285"},
 | 
			
		||||
					{revision: "", kb: "5026415"},
 | 
			
		||||
					{revision: "", kb: "5027271"},
 | 
			
		||||
				},
 | 
			
		||||
				securityOnly: []string{
 | 
			
		||||
					"3192392",
 | 
			
		||||
@@ -3508,6 +3600,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					"5021296",
 | 
			
		||||
					"5022346",
 | 
			
		||||
					"5022894",
 | 
			
		||||
					"5023764",
 | 
			
		||||
					"5025288",
 | 
			
		||||
					"5026409",
 | 
			
		||||
					"5027282",
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -3665,6 +3761,11 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "5582", kb: "5021235"},
 | 
			
		||||
					{revision: "5648", kb: "5022289"},
 | 
			
		||||
					{revision: "5717", kb: "5022838"},
 | 
			
		||||
					{revision: "5786", kb: "5023697"},
 | 
			
		||||
					{revision: "5850", kb: "5025228"},
 | 
			
		||||
					{revision: "5921", kb: "5026363"},
 | 
			
		||||
					{revision: "5989", kb: "5027219"},
 | 
			
		||||
					{revision: "5996", kb: "5028623"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -3998,6 +4099,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "3772", kb: "5022554"},
 | 
			
		||||
					{revision: "3887", kb: "5022286"},
 | 
			
		||||
					{revision: "4010", kb: "5022840"},
 | 
			
		||||
					{revision: "4131", kb: "5023702"},
 | 
			
		||||
					{revision: "4252", kb: "5025229"},
 | 
			
		||||
					{revision: "4377", kb: "5026362"},
 | 
			
		||||
					{revision: "4499", kb: "5027222"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -4235,6 +4340,10 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "2546", kb: "5019275"},
 | 
			
		||||
					{revision: "2604", kb: "5022834"},
 | 
			
		||||
					{revision: "2673", kb: "5022906"},
 | 
			
		||||
					{revision: "2728", kb: "5023696"},
 | 
			
		||||
					{revision: "2788", kb: "5023773"},
 | 
			
		||||
					{revision: "2846", kb: "5025221"},
 | 
			
		||||
					{revision: "2965", kb: "5026361"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -4280,20 +4389,25 @@ var windowsReleases = map[string]map[string]map[string]updateProgram{
 | 
			
		||||
					{revision: "1368", kb: "5022553"},
 | 
			
		||||
					{revision: "1487", kb: "5022291"},
 | 
			
		||||
					{revision: "1547", kb: "5022842"},
 | 
			
		||||
					{revision: "1607", kb: "5023705"},
 | 
			
		||||
					{revision: "1668", kb: "5025230"},
 | 
			
		||||
					{revision: "1726", kb: "5026370"},
 | 
			
		||||
					{revision: "1787", kb: "5027225"},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (o *windows) detectKBsFromKernelVersion() (models.WindowsKB, error) {
 | 
			
		||||
	switch ss := strings.Split(o.Kernel.Version, "."); len(ss) {
 | 
			
		||||
// DetectKBsFromKernelVersion :
 | 
			
		||||
func DetectKBsFromKernelVersion(release, kernelVersion string) (models.WindowsKB, error) {
 | 
			
		||||
	switch ss := strings.Split(kernelVersion, "."); len(ss) {
 | 
			
		||||
	case 3:
 | 
			
		||||
		return models.WindowsKB{}, nil
 | 
			
		||||
	case 4:
 | 
			
		||||
		switch {
 | 
			
		||||
		case strings.HasPrefix(o.getDistro().Release, "Windows 10 "), strings.HasPrefix(o.getDistro().Release, "Windows 11 "):
 | 
			
		||||
			osver := strings.Split(o.getDistro().Release, " ")[1]
 | 
			
		||||
		case strings.HasPrefix(release, "Windows 10 "), strings.HasPrefix(release, "Windows 11 "):
 | 
			
		||||
			osver := strings.Split(release, " ")[1]
 | 
			
		||||
 | 
			
		||||
			verReleases, ok := windowsReleases["Client"][osver]
 | 
			
		||||
			if !ok {
 | 
			
		||||
@@ -4335,8 +4449,8 @@ func (o *windows) detectKBsFromKernelVersion() (models.WindowsKB, error) {
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return kbs, nil
 | 
			
		||||
		case strings.HasPrefix(o.getDistro().Release, "Windows Server 2016"), strings.HasPrefix(o.getDistro().Release, "Windows Server, Version 1709"), strings.HasPrefix(o.getDistro().Release, "Windows Server, Version 1809"), strings.HasPrefix(o.getDistro().Release, "Windows Server 2019"), strings.HasPrefix(o.getDistro().Release, "Windows Server, Version 1903"), strings.HasPrefix(o.getDistro().Release, "Windows Server, Version 1909"), strings.HasPrefix(o.getDistro().Release, "Windows Server, Version 2004"), strings.HasPrefix(o.getDistro().Release, "Windows Server, Version 20H2"), strings.HasPrefix(o.getDistro().Release, "Windows Server 2022"):
 | 
			
		||||
			osver := strings.TrimSpace(strings.NewReplacer("Windows Server", "", ",", "", "(Server Core installation)", "").Replace(o.getDistro().Release))
 | 
			
		||||
		case strings.HasPrefix(release, "Windows Server 2016"), strings.HasPrefix(release, "Windows Server, Version 1709"), strings.HasPrefix(release, "Windows Server, Version 1809"), strings.HasPrefix(release, "Windows Server 2019"), strings.HasPrefix(release, "Windows Server, Version 1903"), strings.HasPrefix(release, "Windows Server, Version 1909"), strings.HasPrefix(release, "Windows Server, Version 2004"), strings.HasPrefix(release, "Windows Server, Version 20H2"), strings.HasPrefix(release, "Windows Server 2022"):
 | 
			
		||||
			osver := strings.TrimSpace(strings.NewReplacer("Windows Server", "", ",", "", "(Server Core installation)", "").Replace(release))
 | 
			
		||||
 | 
			
		||||
			verReleases, ok := windowsReleases["Server"][osver]
 | 
			
		||||
			if !ok {
 | 
			
		||||
@@ -4382,7 +4496,7 @@ func (o *windows) detectKBsFromKernelVersion() (models.WindowsKB, error) {
 | 
			
		||||
			return models.WindowsKB{}, nil
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return models.WindowsKB{}, xerrors.Errorf("unexpected kernel version. expected: <major version>.<minor version>.<build>(.<revision>), actual: %s", o.Kernel.Version)
 | 
			
		||||
		return models.WindowsKB{}, xerrors.Errorf("unexpected kernel version. expected: <major version>.<minor version>.<build>(.<revision>), actual: %s", kernelVersion)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -723,7 +723,7 @@ func Test_windows_detectKBsFromKernelVersion(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			want: models.WindowsKB{
 | 
			
		||||
				Applied:   nil,
 | 
			
		||||
				Unapplied: []string{"5020953", "5019959", "5020030", "5021233", "5022282", "5019275", "5022834", "5022906"},
 | 
			
		||||
				Unapplied: []string{"5020953", "5019959", "5020030", "5021233", "5022282", "5019275", "5022834", "5022906", "5023696", "5023773", "5025221", "5025297", "5026361", "5026435", "5027215", "5027293"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -734,7 +734,7 @@ func Test_windows_detectKBsFromKernelVersion(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			want: models.WindowsKB{
 | 
			
		||||
				Applied:   nil,
 | 
			
		||||
				Unapplied: []string{"5020953", "5019959", "5020030", "5021233", "5022282", "5019275", "5022834", "5022906"},
 | 
			
		||||
				Unapplied: []string{"5020953", "5019959", "5020030", "5021233", "5022282", "5019275", "5022834", "5022906", "5023696", "5023773", "5025221", "5025297", "5026361", "5026435", "5027215", "5027293"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -745,7 +745,7 @@ func Test_windows_detectKBsFromKernelVersion(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			want: models.WindowsKB{
 | 
			
		||||
				Applied:   []string{"5019311", "5017389", "5018427", "5019509", "5018496", "5019980", "5020044", "5021255", "5022303"},
 | 
			
		||||
				Unapplied: []string{"5022360", "5022845"},
 | 
			
		||||
				Unapplied: []string{"5022360", "5022845", "5022913", "5023706", "5023778", "5025239", "5025305", "5026372", "5026446", "5027231", "5027303"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
@@ -756,6 +756,17 @@ func Test_windows_detectKBsFromKernelVersion(t *testing.T) {
 | 
			
		||||
			},
 | 
			
		||||
			want: models.WindowsKB{
 | 
			
		||||
				Applied:   []string{"5005575", "5005619", "5006699", "5006745", "5007205", "5007254", "5008223", "5010197", "5009555", "5010796", "5009608", "5010354", "5010421", "5011497", "5011558", "5012604", "5012637", "5013944", "5015013", "5014021", "5014678", "5014665", "5015827", "5015879", "5016627", "5016693", "5017316", "5017381", "5018421", "5020436", "5018485", "5019081", "5021656", "5020032", "5021249", "5022553", "5022291", "5022842"},
 | 
			
		||||
				Unapplied: []string{"5023705", "5025230", "5026370", "5027225"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "10.0.20348.9999",
 | 
			
		||||
			base: base{
 | 
			
		||||
				Distro:     config.Distro{Release: "Windows Server 2022"},
 | 
			
		||||
				osPackages: osPackages{Kernel: models.Kernel{Version: "10.0.20348.9999"}},
 | 
			
		||||
			},
 | 
			
		||||
			want: models.WindowsKB{
 | 
			
		||||
				Applied:   []string{"5005575", "5005619", "5006699", "5006745", "5007205", "5007254", "5008223", "5010197", "5009555", "5010796", "5009608", "5010354", "5010421", "5011497", "5011558", "5012604", "5012637", "5013944", "5015013", "5014021", "5014678", "5014665", "5015827", "5015879", "5016627", "5016693", "5017316", "5017381", "5018421", "5020436", "5018485", "5019081", "5021656", "5020032", "5021249", "5022553", "5022291", "5022842", "5023705", "5025230", "5026370", "5027225"},
 | 
			
		||||
				Unapplied: nil,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -773,7 +784,7 @@ func Test_windows_detectKBsFromKernelVersion(t *testing.T) {
 | 
			
		||||
			o := &windows{
 | 
			
		||||
				base: tt.base,
 | 
			
		||||
			}
 | 
			
		||||
			got, err := o.detectKBsFromKernelVersion()
 | 
			
		||||
			got, err := DetectKBsFromKernelVersion(o.getDistro().Release, o.Kernel.Version)
 | 
			
		||||
			if (err != nil) != tt.wantErr {
 | 
			
		||||
				t.Errorf("windows.detectKBsFromKernelVersion() error = %v, wantErr %v", err, tt.wantErr)
 | 
			
		||||
				return
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user