From fc908e65ba6c0ad3edb344cfb263adff8efe6f4e Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Thu, 10 Nov 2016 15:05:47 -0500 Subject: [PATCH] detectors/feature: add apk feature detector --- worker/detectors/feature/apk/apk.go | 84 ++++ worker/detectors/feature/apk/apk_test.go | 80 ++++ .../detectors/feature/apk/testdata/installed | 448 ++++++++++++++++++ 3 files changed, 612 insertions(+) create mode 100644 worker/detectors/feature/apk/apk.go create mode 100644 worker/detectors/feature/apk/apk_test.go create mode 100644 worker/detectors/feature/apk/testdata/installed diff --git a/worker/detectors/feature/apk/apk.go b/worker/detectors/feature/apk/apk.go new file mode 100644 index 0000000000..7fd395713a --- /dev/null +++ b/worker/detectors/feature/apk/apk.go @@ -0,0 +1,84 @@ +// Copyright 2016 clair authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apk + +import ( + "bufio" + "bytes" + + "github.com/coreos/clair/database" + "github.com/coreos/clair/utils/types" + "github.com/coreos/clair/worker/detectors" + "github.com/coreos/pkg/capnslog" +) + +var log = capnslog.NewPackageLogger("github.com/coreos/clair", "worker/detectors/packages") + +func init() { + detectors.RegisterFeaturesDetector("apk", &detector{}) +} + +type detector struct{} + +func (d *detector) Detect(data map[string][]byte) ([]database.FeatureVersion, error) { + file, exists := data["lib/apk/db/installed"] + if !exists { + return []database.FeatureVersion{}, nil + } + + // Iterate over each line in the "installed" file attempting to parse each + // package into a feature that will be stored in a set to guarantee + // uniqueness. + pkgSet := make(map[string]database.FeatureVersion) + ipkg := database.FeatureVersion{} + scanner := bufio.NewScanner(bytes.NewBuffer(file)) + for scanner.Scan() { + line := scanner.Text() + if len(line) < 2 { + continue + } + + // Parse the package name or version. + switch { + case line[:2] == "P:": + ipkg.Feature.Name = line[2:] + case line[:2] == "V:": + var err error + ipkg.Version, err = types.NewVersion(line[2:]) + if err != nil { + log.Warningf("could not parse package version '%s': %s. skipping", line[2:], err.Error()) + } + } + + // If we have a whole feature, store it in the set and try to parse a new + // one. + if ipkg.Feature.Name != "" && ipkg.Version.String() != "" { + pkgSet[ipkg.Feature.Name+"#"+ipkg.Version.String()] = ipkg + ipkg = database.FeatureVersion{} + } + } + + // Convert the map into a slice. + pkgs := make([]database.FeatureVersion, 0, len(pkgSet)) + for _, pkg := range pkgSet { + pkgs = append(pkgs, pkg) + } + + return pkgs, nil +} + +func (d *detector) GetRequiredFiles() []string { + return []string{"lib/apk/db/installed"} +} diff --git a/worker/detectors/feature/apk/apk_test.go b/worker/detectors/feature/apk/apk_test.go new file mode 100644 index 0000000000..803a665796 --- /dev/null +++ b/worker/detectors/feature/apk/apk_test.go @@ -0,0 +1,80 @@ +// Copyright 2016 clair authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apk + +import ( + "testing" + + "github.com/coreos/clair/database" + "github.com/coreos/clair/utils/types" + "github.com/coreos/clair/worker/detectors/feature" +) + +func TestAPKFeatureDetection(t *testing.T) { + testData := []feature.TestData{ + { + FeatureVersions: []database.FeatureVersion{ + { + Feature: database.Feature{Name: "musl"}, + Version: types.NewVersionUnsafe("1.1.14-r10"), + }, + { + Feature: database.Feature{Name: "busybox"}, + Version: types.NewVersionUnsafe("1.24.2-r9"), + }, + { + Feature: database.Feature{Name: "alpine-baselayout"}, + Version: types.NewVersionUnsafe("3.0.3-r0"), + }, + { + Feature: database.Feature{Name: "alpine-keys"}, + Version: types.NewVersionUnsafe("1.1-r0"), + }, + { + Feature: database.Feature{Name: "zlib"}, + Version: types.NewVersionUnsafe("1.2.8-r2"), + }, + { + Feature: database.Feature{Name: "libcrypto1.0"}, + Version: types.NewVersionUnsafe("1.0.2h-r1"), + }, + { + Feature: database.Feature{Name: "libssl1.0"}, + Version: types.NewVersionUnsafe("1.0.2h-r1"), + }, + { + Feature: database.Feature{Name: "apk-tools"}, + Version: types.NewVersionUnsafe("2.6.7-r0"), + }, + { + Feature: database.Feature{Name: "scanelf"}, + Version: types.NewVersionUnsafe("1.1.6-r0"), + }, + { + Feature: database.Feature{Name: "musl-utils"}, + Version: types.NewVersionUnsafe("1.1.14-r10"), + }, + { + Feature: database.Feature{Name: "libc-utils"}, + Version: types.NewVersionUnsafe("0.7-r0"), + }, + }, + Data: map[string][]byte{ + "lib/apk/db/installed": feature.LoadFileForTest("apk/testdata/installed"), + }, + }, + } + feature.TestDetector(t, &detector{}, testData) +} diff --git a/worker/detectors/feature/apk/testdata/installed b/worker/detectors/feature/apk/testdata/installed new file mode 100644 index 0000000000..747555d611 --- /dev/null +++ b/worker/detectors/feature/apk/testdata/installed @@ -0,0 +1,448 @@ +C:Q11otALzX1d1D0kVawy06IairTXS0= +P:musl +V:1.1.14-r10 +A:x86_64 +S:445080 +I:569344 +T:the musl c library (libc) implementation +U:http://www.musl-libc.org/ +L:MIT +o:musl +m:Timo Teräs +t:1466181580 +c:e6c226fbe17bb8f856dce5f0d9bc088b333e6225 +p:so:libc.musl-x86_64.so.1=1 +F:lib +R:libc.musl-x86_64.so.1 +a:0:0:777 +Z:Q17yJ3JFNypA4mxhJJr0ou6CzsJVI= +R:ld-musl-x86_64.so.1 +a:0:0:755 +Z:Q1KUwsFGLHn/enpN9+QIpK/FmixtQ= + +C:Q1yhJHGSZ80L7cL0y4UKKGrBPwrUQ= +P:busybox +V:1.24.2-r9 +A:x86_64 +S:642121 +I:909312 +T:Size optimized toolbox of many common UNIX utilities +U:http://busybox.net +L:GPL2 +o:busybox +m:Natanael Copa +t:1466671780 +c:386b639b3917a9d1b8588dd87f09ed446501cddf +D:so:libc.musl-x86_64.so.1 +F:bin +R:busybox +a:0:0:755 +Z:Q1xOlCsdvx4O0gnKWoFCNKjz2quRE= +R:sh +a:0:0:777 +Z:Q1pcfTfDNEbNKQc2s1tia7da05M8Q= +F:etc +R:securetty +Z:Q14VDshgWFleuDbp4jqXk+UNES65Q= +R:udhcpd.conf +Z:Q1PWhOJ+TaEzAXw+XC6kkz/FXI/KA= +F:etc/logrotate.d +R:acpid +Z:Q1bPM2hPZy1LntZ/YdI4ZFJzVl1Y8= +F:etc/network +F:etc/network/if-up.d +F:etc/network/if-post-up.d +F:etc/network/if-pre-up.d +F:etc/network/if-post-down.d +F:etc/network/if-pre-down.d +F:etc/network/if-down.d +F:sbin +F:tmp +M:0:0:1777 +F:usr +F:usr/sbin +F:usr/bin +F:var +F:var/lib +F:var/lib/udhcpd +F:var/cache +F:var/cache/misc + +C:Q1ohSJYVBBHXLdH6/bMtHGxIVczPo= +P:alpine-baselayout +V:3.0.3-r0 +A:x86_64 +S:74697 +I:401408 +T:Alpine base dir structure and init scripts +U:http://git.alpinelinux.org/cgit/aports/tree/main/alpine-baselayout +L:GPL2 +o:alpine-baselayout +m:Natanael Copa +t:1466181584 +c:d0bef446b94220475c60e78f2e081f38390b89ca +D:busybox so:libc.musl-x86_64.so.1 +F:dev +F:dev/shm +F:dev/pts +F:etc +R:hosts +Z:Q1S93L8EsQ/7zGSnfGDfj5I7bjCS4= +R:sysctl.conf +Z:Q14upz3tfnNxZkIEsUhWn7Xoiw96g= +R:group +Z:Q1zNuxdqs1x+nJO8WucpZfQrdiapA= +R:protocols +Z:Q13FqXUnvuOpMDrH/6rehxuYAEE34= +R:fstab +Z:Q11Q7hNe8QpDS531guqCdrXBzoA/o= +R:mtab +a:0:0:777 +Z:Q1kiljhXXH1LlQroHsEJIkPZg2eiw= +R:profile +Z:Q1FrM1yy3WJbQTc9LgnKTn5tRovlE= +R:TZ +Z:Q1uHH18uOLEzp56qFUP843WSoKM9E= +R:shells +Z:Q1ojm2YdpCJ6B/apGDaZ/Sdb2xJkA= +R:motd +Z:Q1MaUHN/Rf32Lf67Owrq1BXQU7usE= +R:inittab +Z:Q1TsthbhW7QzWRe1E/NKwTOuD4pHc= +R:hostname +Z:Q16nVwYVXP/tChvUPdukVD2ifXOmc= +R:modules +Z:Q1C7P4uPQo8B6P6V+O78ybHl0AHhA= +R:services +Z:Q1NBe0rrC8HMzNmVf4ybSENcsdey0= +R:shadow +a:0:42:640 +Z:Q1LG0ii8vP4gQgDmSnK0WBtjtovlg= +R:passwd +Z:Q11HpI0rBp2zsun4+LIIBENg8JQUE= +F:etc/profile.d +R:color_prompt +Z:Q10wL23GuSCVfumMRgakabUI6EsSk= +F:etc/init.d +F:etc/apk +F:etc/sysctl.d +R:00-alpine.conf +Z:Q1kZy9KEvjykp1vCw1kWgdvBuEXvg= +F:etc/modprobe.d +R:i386.conf +Z:Q1pnay/njn6ol9cCssL7KiZZ8etlc= +R:blacklist.conf +Z:Q1+TdC1pulajuYy0ebcos8V/aMeqk= +R:aliases.conf +Z:Q1udaZLaeaalyuCcnBgCKPIybDO08= +R:kms.conf +Z:Q1yH/c6fBvCWn0Huny5Rf/GET2Jbs= +F:etc/modules-load.d +F:etc/opt +F:etc/conf.d +F:etc/crontabs +R:root +a:0:0:600 +Z:Q1vfk1apUWI4yLJGhhNRd0kJixfvY= +F:etc/periodic +F:etc/periodic/hourly +F:etc/periodic/weekly +F:etc/periodic/monthly +F:etc/periodic/15min +F:etc/periodic/daily +F:etc/network +F:etc/network/if-up.d +F:etc/network/if-pre-up.d +F:etc/network/if-post-down.d +F:etc/network/if-down.d +F:home +F:lib +F:lib/mdev +F:lib/firmware +F:media +F:media/floppy +F:media/cdrom +F:media/usb +F:mnt +F:proc +F:root +M:0:0:700 +F:run +F:sbin +R:mkmntdirs +a:0:0:755 +Z:Q1lGBnGMsnB3SEZL/oHeN99F1/ie8= +F:srv +F:sys +F:tmp +M:0:0:1777 +F:usr +F:usr/sbin +F:usr/bin +F:usr/local +F:usr/local/bin +F:usr/local/lib +F:usr/local/share +F:usr/share +F:usr/share/man +F:usr/share/misc +F:var +F:var/lock +F:var/lock/subsys +F:var/tmp +M:0:0:1777 +F:var/log +F:var/lib +F:var/lib/misc +F:var/local +F:var/opt +F:var/cache +F:var/cache/misc +F:var/spool +F:var/spool/cron +R:crontabs +a:0:0:777 +Z:Q1OFZt+ZMp7j0Gny0rqSKuWJyqYmA= +F:var/empty +F:var/run + +C:Q1Te9/+u5q66cAwdYlcDJvdcu4+iU= +P:alpine-keys +V:1.1-r0 +A:x86_64 +S:7787 +I:36864 +T:Public keys for Alpine Linux packages +U:http://alpinelinux.org +L:GPL +o:alpine-keys +m:Natanael Copa +t:1461964035 +c:d0b08b1e17d40d21196df7709fdb95f37165615d +r:alpine-base +F:etc +F:etc/apk +F:etc/apk/keys +R:alpine-devel@lists.alpinelinux.org-4d07755e.rsa.pub +Z:Q1XfH9IG0ZFgbOIssIhpiWqDlSspY= +R:alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub +Z:Q1BTqS+H/UUyhQuzHwiBl47+BTKuU= +R:alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub +Z:Q1v7YWZYzAWoclaLDI45jEguI7YN0= +R:alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub +Z:Q1NnGuDsdQOx4ZNYfB3N97eLyGPkI= +R:alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub +Z:Q1OvCFSO94z97c80mIDCxqGkh2Og4= + +C:Q179BNNNQKqOszFIASc2TCeounYO8= +P:zlib +V:1.2.8-r2 +A:x86_64 +S:71733 +I:98304 +T:A compression/decompression Library +U:http://zlib.net +L:zlib +o:zlib +m:Natanael Copa +t:1461931151 +c:a7329a4de4d10d99206c78c229dc3742880cd042 +D:so:libc.musl-x86_64.so.1 +p:so:libz.so.1=1.2.8 +F:lib +R:libz.so.1.2.8 +a:0:0:755 +Z:Q1bh8VMdNZcPKyIQTtLMtz/0VL2H0= +R:libz.so.1 +a:0:0:777 +Z:Q1x1VqGi0rW5lxmvPQOjnqNapz/OU= + +C:Q1Zchg/48QO2ZPQLqEmj9aUcaci+s= +P:libcrypto1.0 +V:1.0.2h-r1 +A:x86_64 +S:1714530 +I:2527232 +T:Crypto library from openssl +U:http://openssl.org +L:openssl +o:openssl +m:Timo Teras +t:1466620012 +c:38c6e1fd86f4d9cba4c146b8bdcd71f84e1a4ee7 +D:so:libc.musl-x86_64.so.1 so:libz.so.1 +p:so:libcrypto.so.1.0.0=1.0.0 +F:lib +R:libcrypto.so.1.0.0 +a:0:0:555 +Z:Q1DgSoxP0AWq64XJSPXT0yRTjSSBk= +F:usr +F:usr/bin +R:c_rehash +a:0:0:755 +Z:Q1XZt0LbTr44grnBtK+Yihjynh2EE= +F:usr/lib +R:libcrypto.so.1.0.0 +a:0:0:777 +Z:Q1jLDKGBtunzKi5FKmK/QTAqfh6uI= +F:usr/lib/engines +R:libubsec.so +a:0:0:555 +Z:Q1SaoP91RpISCN8KO3AxuB8Tzyc/A= +R:libatalla.so +a:0:0:555 +Z:Q1W31yRhAZE9X5Z5zy9l6mkn1tbcQ= +R:libcapi.so +a:0:0:555 +Z:Q1iriyqA2XunZb8pxmsOeRML2ZsRg= +R:libgost.so +a:0:0:555 +Z:Q1zwS6yHAzzdnrHb9BV8pIsE2yIgg= +R:libcswift.so +a:0:0:555 +Z:Q16/TBTN+WkIFQeFlCPTDc5Xs33bU= +R:libchil.so +a:0:0:555 +Z:Q1fMssNRSfAgg4nZVYm0IzYG2gTLk= +R:libgmp.so +a:0:0:555 +Z:Q1onZiPB/LsF3Xqn8rwH5FcYLkuf4= +R:libnuron.so +a:0:0:555 +Z:Q189GVmg2NFt2nTCqfcSl7Wtoym1o= +R:lib4758cca.so +a:0:0:555 +Z:Q1aNXgEbvxfvZdZpa4frZ9p6eq2Y4= +R:libsureware.so +a:0:0:555 +Z:Q14Z9HkfG+WqvGRIb42iugBuBKOag= +R:libpadlock.so +a:0:0:555 +Z:Q1OAwUUirl7Q1OiqTjB96lKBQYbMc= +R:libaep.so +a:0:0:555 +Z:Q1nrvE4qxl4AXEC/psF1Eh9n6E7Pg= + +C:Q1cSDzN+k7K0xE4PXzGhW2DcZ4yhQ= +P:libssl1.0 +V:1.0.2h-r1 +A:x86_64 +S:274743 +I:442368 +T:SSL shared libraries +U:http://openssl.org +L:openssl +o:openssl +m:Timo Teras +t:1466620012 +c:38c6e1fd86f4d9cba4c146b8bdcd71f84e1a4ee7 +D:so:libc.musl-x86_64.so.1 so:libcrypto.so.1.0.0 +p:so:libssl.so.1.0.0=1.0.0 +F:lib +R:libssl.so.1.0.0 +a:0:0:555 +Z:Q1wdqn4897nQP5l/f3SV4DWf9QOkQ= +F:usr +F:usr/lib +R:libssl.so.1.0.0 +a:0:0:777 +Z:Q1ke5dnHGVWcEyRpOe0/lKEqizHHQ= + +C:Q1CZDArNYrQXWBjDpMxg7RHxTiO9g= +P:apk-tools +V:2.6.7-r0 +A:x86_64 +S:146592 +I:253952 +T:Alpine Package Keeper - package manager for alpine +U:http://git.alpinelinux.org/cgit/apk-tools/ +L:GPL2 +o:apk-tools +m:Natanael Copa +t:1464341138 +c:08b6e2ae43356fbb24ef5c262fb08bfe09d675b0 +D:so:libc.musl-x86_64.so.1 so:libcrypto.so.1.0.0 so:libssl.so.1.0.0 so:libz.so.1 +F:etc +F:etc/apk +F:etc/apk/keys +F:etc/apk/protected_paths.d +F:sbin +R:apk +a:0:0:755 +Z:Q1ozOGvVOspzXfX1bUFjrjZ6ygEB0= +F:usr +F:var +F:var/lib +F:var/lib/apk +F:var/cache +F:var/cache/misc + +C:Q1+bq4F8Wtk+kqYhi8D3WWtlfALZA= +P:scanelf +V:1.1.6-r0 +A:x86_64 +S:53666 +I:90112 +T:Scan ELF binaries for stuff +U:https://wiki.gentoo.org/wiki/Hardened/PaX_Utilities +L:GPL2 +o:pax-utils +m:Natanael Copa +t:1461934341 +c:891f6254fb6e1f11f62ee2c9fd35784fd313b9d1 +D:so:libc.musl-x86_64.so.1 +r:pax-utils +F:usr +F:usr/bin +R:scanelf +a:0:0:755 +Z:Q12S+aDBkRA63GvTmx45HqqbOKBz0= + +C:Q1YIqh3Tnv97xmFdPl4zODdQ+PXsw= +P:musl-utils +V:1.1.14-r10 +A:x86_64 +S:50427 +I:110592 +T:the musl c library (libc) implementation +U:http://www.musl-libc.org/ +L:MIT BSD GPL2+ +o:musl +m:Timo Teräs +t:1466181579 +c:e6c226fbe17bb8f856dce5f0d9bc088b333e6225 +D:!uclibc-utils scanelf musl=1.1.14-r10 so:libc.musl-x86_64.so.1 +r:libiconv uclibc-utils +F:sbin +R:ldconfig +a:0:0:755 +Z:Q1Kja2+POZKxEkUOZqwSjC6kmaED4= +F:usr +F:usr/bin +R:iconv +a:0:0:755 +Z:Q1DmLsMEsBDtwb8S0z1pl0MYH29+o= +R:ldd +a:0:0:777 +Z:Q1a/NMxsyXbxLcmrTyGQtovas5gJk= +R:getconf +a:0:0:755 +Z:Q1iub9vwJRjlaCnu21SWjb504fUqk= +R:getent +a:0:0:755 +Z:Q1Z5dnRfQ7nvRbRRSpM1k0J7UMdng= + +C:Q1kFW8ev12zyZyGYBC9y/Epe1PqWE= +P:libc-utils +V:0.7-r0 +A:x86_64 +S:2804 +I:4096 +T:Meta package to pull in correct libc +U:http://alpinelinux.org +L:GPL +o:libc-dev +m:Natanael Copa +t:1461934274 +c:e3725c0af137717d6883265a92db3838900b5cee +D:musl-utils