From db386baf81f2d3402ef197ec30a0b5b3b674bd0c Mon Sep 17 00:00:00 2001 From: Benji Visser Date: Fri, 6 Jan 2023 10:50:48 -0700 Subject: [PATCH] Add redis binary classifier (#1438) Signed-off-by: Benji Visser --- syft/pkg/cataloger/binary/cataloger_test.go | 70 ++++++++++++++++++ .../cataloger/binary/default_classifiers.go | 9 +++ .../positive/redis-server-2.8.23/redis-server | Bin 0 -> 7025 bytes .../positive/redis-server-4.0.11/redis-server | Bin 0 -> 9179 bytes .../positive/redis-server-5.0.0/redis-server | Bin 0 -> 7061 bytes .../positive/redis-server-6.0.16/redis-server | Bin 0 -> 2574 bytes .../positive/redis-server-7.0.0/redis-server | Bin 0 -> 1239 bytes 7 files changed, 79 insertions(+) create mode 100755 syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-2.8.23/redis-server create mode 100755 syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-4.0.11/redis-server create mode 100755 syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-5.0.0/redis-server create mode 100755 syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-6.0.16/redis-server create mode 100755 syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-7.0.0/redis-server diff --git a/syft/pkg/cataloger/binary/cataloger_test.go b/syft/pkg/cataloger/binary/cataloger_test.go index a2c37c3ba..7a5209074 100644 --- a/syft/pkg/cataloger/binary/cataloger_test.go +++ b/syft/pkg/cataloger/binary/cataloger_test.go @@ -17,6 +17,76 @@ func TestClassifierCataloger_DefaultClassifiers_PositiveCases(t *testing.T) { fixtureDir string expected pkg.Package }{ + { + name: "positive-redis-2.8.23", + fixtureDir: "test-fixtures/classifiers/positive/redis-server-2.8.23", + expected: pkg.Package{ + Name: "redis", + Version: "2.8.23", + Type: "binary", + PURL: "pkg:generic/redis@2.8.23", + Locations: singleLocation("redis-server"), + Metadata: pkg.BinaryMetadata{ + Classifier: "redis-binary", + }, + }, + }, + { + name: "positive-redis-4.0.11", + fixtureDir: "test-fixtures/classifiers/positive/redis-server-4.0.11", + expected: pkg.Package{ + Name: "redis", + Version: "4.0.11", + Type: "binary", + PURL: "pkg:generic/redis@4.0.11", + Locations: singleLocation("redis-server"), + Metadata: pkg.BinaryMetadata{ + Classifier: "redis-binary", + }, + }, + }, + { + name: "positive-redis-5.0.0", + fixtureDir: "test-fixtures/classifiers/positive/redis-server-5.0.0", + expected: pkg.Package{ + Name: "redis", + Version: "5.0.0", + Type: "binary", + PURL: "pkg:generic/redis@5.0.0", + Locations: singleLocation("redis-server"), + Metadata: pkg.BinaryMetadata{ + Classifier: "redis-binary", + }, + }, + }, + { + name: "positive-redis-6.0.16", + fixtureDir: "test-fixtures/classifiers/positive/redis-server-6.0.16", + expected: pkg.Package{ + Name: "redis", + Version: "6.0.16", + Type: "binary", + PURL: "pkg:generic/redis@6.0.16", + Locations: singleLocation("redis-server"), + Metadata: pkg.BinaryMetadata{ + Classifier: "redis-binary", + }, + }, + }, + { + name: "positive-redis-7.0.0", + fixtureDir: "test-fixtures/classifiers/positive/redis-server-7.0.0", + expected: pkg.Package{ + Name: "redis", + Version: "7.0.0", + Type: "binary", + PURL: "pkg:generic/redis@7.0.0", + Locations: singleLocation("redis-server"), + Metadata: pkg.BinaryMetadata{ + Classifier: "redis-binary", + }, + }, + }, { name: "positive-libpython3.7.so", fixtureDir: "test-fixtures/classifiers/positive", diff --git a/syft/pkg/cataloger/binary/default_classifiers.go b/syft/pkg/cataloger/binary/default_classifiers.go index 0456d526e..6a3b9b95c 100644 --- a/syft/pkg/cataloger/binary/default_classifiers.go +++ b/syft/pkg/cataloger/binary/default_classifiers.go @@ -38,6 +38,15 @@ var defaultClassifiers = []classifier{ PURL: mustPURL("pkg:generic/go@version"), CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*"), }, + { + Class: "redis-binary", + FileGlob: "**/redis-server", + EvidenceMatcher: fileContentsVersionMatcher( + `(?s)payload %5.*(?P\d.\d\.\d\d*?)[a-z0-9]{12}-[0-9]{19}`), + Package: "redis", + PURL: mustPURL("pkg:generic/redis@version"), + CPEs: singleCPE("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*"), + }, { Class: "java-binary-openjdk", FileGlob: "**/java", diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-2.8.23/redis-server b/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-2.8.23/redis-server new file mode 100755 index 0000000000000000000000000000000000000000..f56e59bbf678a2663f08946ae4574cf01208c0c8 GIT binary patch literal 7025 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 literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-5.0.0/redis-server b/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/redis-server-5.0.0/redis-server new file mode 100755 index 0000000000000000000000000000000000000000..124d42a598f5d504cbc6f1dda3662cc2df497e55 GIT binary patch literal 7061 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 GBhK$D zS%qdlbh|KU$8S-9{=|-rOx-_r4op8a8y<)cEl>SIX$=r(Bss$a**8?8n77Wkx zZm~lxM2&LDe}Dfv{QBYRAf6CwjGqNz5V9z0pGWhIo@cZb{e9X#Yq$S8uc2W`2K~XO zVR8kHFY)vx88^vQJe$NHhZFac^lxHvJsgdo%ZpB-wCxeV@d56p@dUc1VOpk3R(q${ z!`qv9pKCOn&fs1ZmMdu>2!aQ4m)!P|OsW~WmM@tqZ4d7MnG9#~OMf(aAd~oZ^aUE@ zngtQ*bRsfPQnK7hhZRTuGBuWI5X#tq^z)n* zmQl#}D67CT`-o>c9wn;P!zxj?d*144Hh;{7$`_A?GNf`8V)IyCVYqMtW382jmF5;D z0;b%l#H(cpW(*xEUs8B;0mi_nn0Ae5V%!JHO)Uxe+*ZU^Jek05J5x9*ZDN&z zj3Yt{E*WU{y=2B>>9Nobnd+x}r>I6Qvr;VZyrr~YtVVebhcvy(%K5$f&)l&d9PRyw z_k>HluAIUFk(4qmT`l*yT#{ueEO#z!74)zQ^`3iJy=9%WitIXDCp~oC?Rr|D3+$#~ zqrW%tRh+oMp|6XiH{SKeP`h61<~0P j@v8;R3vY|BeZ5|H$Q$>B6HNcvJ@bZ;*qhuF^!VsMCHZ^~ literal 0 HcmV?d00001