mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-12 15:50:15 -08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42043a0888 | ||
|
|
246793e873 | ||
|
|
692b0f1410 | ||
|
|
0629e1d731 | ||
|
|
9707c7bcb1 | ||
|
|
194fbef73c | ||
|
|
f7db00c1eb | ||
|
|
2f4b31ecc6 | ||
|
|
9289624688 | ||
|
|
5a8749cd5b | ||
|
|
4a7fb525d7 | ||
|
|
8888fcafa7 | ||
|
|
63a8c6d26b | ||
|
|
fc222bed7c | ||
|
|
6132ff93a2 | ||
|
|
87556aa741 |
@@ -1,5 +1,5 @@
|
|||||||
FROM alpine:3.10
|
FROM alpine:3.11
|
||||||
RUN apk --no-cache add ca-certificates git rpm
|
RUN apk --no-cache add ca-certificates git rpm
|
||||||
COPY trivy /usr/local/bin/trivy
|
COPY trivy /usr/local/bin/trivy
|
||||||
|
COPY contrib/gitlab.tpl contrib/gitlab.tpl
|
||||||
ENTRYPOINT ["trivy"]
|
ENTRYPOINT ["trivy"]
|
||||||
|
|||||||
46
README.md
46
README.md
@@ -32,6 +32,7 @@ A Simple and Comprehensive Vulnerability Scanner for Containers, Suitable for CI
|
|||||||
- [Scan an image](#scan-an-image)
|
- [Scan an image](#scan-an-image)
|
||||||
- [Scan an image file](#scan-an-image-file)
|
- [Scan an image file](#scan-an-image-file)
|
||||||
- [Save the results as JSON](#save-the-results-as-json)
|
- [Save the results as JSON](#save-the-results-as-json)
|
||||||
|
- [Save the results using a template](#save-the-results-using-a-template)
|
||||||
- [Filter the vulnerabilities by severities](#filter-the-vulnerabilities-by-severities)
|
- [Filter the vulnerabilities by severities](#filter-the-vulnerabilities-by-severities)
|
||||||
- [Filter the vulnerabilities by type](#filter-the-vulnerabilities-by-type)
|
- [Filter the vulnerabilities by type](#filter-the-vulnerabilities-by-type)
|
||||||
- [Skip an update of vulnerability DB](#skip-update-of-vulnerability-db)
|
- [Skip an update of vulnerability DB](#skip-update-of-vulnerability-db)
|
||||||
@@ -48,7 +49,7 @@ A Simple and Comprehensive Vulnerability Scanner for Containers, Suitable for CI
|
|||||||
- [Continuous Integration (CI)](#continuous-integration-ci)
|
- [Continuous Integration (CI)](#continuous-integration-ci)
|
||||||
- [Travis CI](#travis-ci)
|
- [Travis CI](#travis-ci)
|
||||||
- [CircleCI](#circleci)
|
- [CircleCI](#circleci)
|
||||||
- [GitLab CI](#gitlab)
|
- [GitLab CI](#gitlab-ci)
|
||||||
- [Authorization for Private Docker Registry](#authorization-for-private-docker-registry)
|
- [Authorization for Private Docker Registry](#authorization-for-private-docker-registry)
|
||||||
- [Vulnerability Detection](#vulnerability-detection)
|
- [Vulnerability Detection](#vulnerability-detection)
|
||||||
- [OS Packages](#os-packages)
|
- [OS Packages](#os-packages)
|
||||||
@@ -654,6 +655,25 @@ $ trivy -f json -o results.json golang:1.12-alpine
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
### Save the results using a template
|
||||||
|
|
||||||
|
```
|
||||||
|
$ trivy --format template --template "{{ range . }} {{ .Target }} {{ end }}" golang:1.12-alpine
|
||||||
|
```
|
||||||
|
<details>
|
||||||
|
<summary>Result</summary>
|
||||||
|
```
|
||||||
|
2020-01-02T18:02:32.856+0100 INFO Detecting Alpine vulnerabilities...
|
||||||
|
golang:1.12-alpine (alpine 3.10.2)
|
||||||
|
```
|
||||||
|
</details>
|
||||||
|
|
||||||
|
You can load templates from a file prefixing the template path with an @.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ trivy --format template --template "@/path/to/template" golang:1.12-alpine
|
||||||
|
```
|
||||||
|
|
||||||
### Filter the vulnerabilities by severities
|
### Filter the vulnerabilities by severities
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -1219,7 +1239,7 @@ workflows:
|
|||||||
Example: https://circleci.com/gh/aquasecurity/trivy-ci-test
|
Example: https://circleci.com/gh/aquasecurity/trivy-ci-test
|
||||||
Repository: https://github.com/aquasecurity/trivy-ci-test
|
Repository: https://github.com/aquasecurity/trivy-ci-test
|
||||||
|
|
||||||
## GitLab
|
## GitLab CI
|
||||||
|
|
||||||
```
|
```
|
||||||
$ cat .gitlab-ci.yml
|
$ cat .gitlab-ci.yml
|
||||||
@@ -1228,7 +1248,7 @@ stages:
|
|||||||
|
|
||||||
trivy:
|
trivy:
|
||||||
stage: test
|
stage: test
|
||||||
image: docker:19.03.1
|
image: docker:stable
|
||||||
services:
|
services:
|
||||||
- name: docker:dind
|
- name: docker:dind
|
||||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||||
@@ -1238,6 +1258,7 @@ trivy:
|
|||||||
DOCKER_DRIVER: overlay2
|
DOCKER_DRIVER: overlay2
|
||||||
# See https://github.com/docker-library/docker/pull/166
|
# See https://github.com/docker-library/docker/pull/166
|
||||||
DOCKER_TLS_CERTDIR: ""
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
IMAGE: trivy-ci-test:$CI_COMMIT_SHA
|
||||||
before_script:
|
before_script:
|
||||||
- apk add --no-cache curl
|
- apk add --no-cache curl
|
||||||
- export VERSION=$(curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
|
- export VERSION=$(curl --silent "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
|
||||||
@@ -1246,13 +1267,22 @@ trivy:
|
|||||||
- tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
|
- tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- docker build -t trivy-ci-test:$CI_COMMIT_SHA .
|
# Build image
|
||||||
- ./trivy --exit-code 0 --cache-dir $CI_PROJECT_DIR/.trivycache/ --no-progress --severity HIGH trivy-ci-test:$CI_COMMIT_SHA
|
- docker build -t $IMAGE .
|
||||||
- ./trivy --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:$CI_COMMIT_SHA
|
# Build report
|
||||||
|
- ./trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
|
||||||
|
# Print report
|
||||||
|
- ./trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --severity HIGH $IMAGE
|
||||||
|
# Fail on high and critical vulnerabilities
|
||||||
|
- ./trivy --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress $IMAGE
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- $CI_PROJECT_DIR/.trivycache/
|
- .trivycache/
|
||||||
```
|
# Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
container_scanning: gl-container-scanning-report.json
|
||||||
|
```
|
||||||
|
|
||||||
## Authorization for Private Docker Registry
|
## Authorization for Private Docker Registry
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM circleci/golang:1.13-buster
|
|||||||
RUN sudo apt-get -y update \
|
RUN sudo apt-get -y update \
|
||||||
&& sudo apt-get -y install rpm reprepro createrepo
|
&& sudo apt-get -y install rpm reprepro createrepo
|
||||||
|
|
||||||
ARG GORELEASER_VERSION=0.110.0
|
ARG GORELEASER_VERSION=0.124.1
|
||||||
ARG GORELEASER_ARTIFACT=goreleaser_Linux_x86_64.tar.gz
|
ARG GORELEASER_ARTIFACT=goreleaser_Linux_x86_64.tar.gz
|
||||||
RUN wget https://github.com/goreleaser/goreleaser/releases/download/v${GORELEASER_VERSION}/${GORELEASER_ARTIFACT} \
|
RUN wget https://github.com/goreleaser/goreleaser/releases/download/v${GORELEASER_VERSION}/${GORELEASER_ARTIFACT} \
|
||||||
&& sudo tar -xzf ${GORELEASER_ARTIFACT} -C /usr/bin/ goreleaser \
|
&& sudo tar -xzf ${GORELEASER_ARTIFACT} -C /usr/bin/ goreleaser \
|
||||||
|
|||||||
29
contrib/Trivy.gitlab-ci.yml
Normal file
29
contrib/Trivy.gitlab-ci.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
Trivy_container_scanning:
|
||||||
|
stage: test
|
||||||
|
image:
|
||||||
|
name: alpine:3.11
|
||||||
|
variables:
|
||||||
|
# Override the GIT_STRATEGY variable in your `.gitlab-ci.yml` file and set it to `fetch` if you want to provide a `clair-whitelist.yml`
|
||||||
|
# file. See https://docs.gitlab.com/ee/user/application_security/container_scanning/index.html#overriding-the-container-scanning-template
|
||||||
|
# for details
|
||||||
|
GIT_STRATEGY: none
|
||||||
|
IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
|
||||||
|
allow_failure: true
|
||||||
|
before_script:
|
||||||
|
- export TRIVY_VERSION=${TRIVY_VERSION:-v0.4.3}
|
||||||
|
- apk add --no-cache curl docker-cli
|
||||||
|
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
|
||||||
|
- curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/master/contrib/install.sh | sh -s -- -b /usr/local/bin ${TRIVY_VERSION}
|
||||||
|
- curl -sSL -o /tmp/trivy-gitlab.tpl https://github.com/aquasecurity/trivy/raw/${TRIVY_VERSION}/contrib/gitlab.tpl
|
||||||
|
script:
|
||||||
|
- trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@/tmp/trivy-gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
|
||||||
|
cache:
|
||||||
|
paths:
|
||||||
|
- .trivycache/
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
container_scanning: gl-container-scanning-report.json
|
||||||
|
dependencies: []
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
- branches
|
||||||
80
contrib/gitlab.tpl
Normal file
80
contrib/gitlab.tpl
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
{{- /* Template based on https://docs.gitlab.com/ee/user/application_security/container_scanning/#reports-json-format */ -}}
|
||||||
|
{
|
||||||
|
"version": "2.3",
|
||||||
|
"vulnerabilities": [
|
||||||
|
{{- $first := true }}
|
||||||
|
{{- range . }}
|
||||||
|
{{- $target := .Target }}
|
||||||
|
{{- range .Vulnerabilities -}}
|
||||||
|
{{- if $first -}}
|
||||||
|
{{- $first = false -}}
|
||||||
|
{{ else -}}
|
||||||
|
,
|
||||||
|
{{- end }}
|
||||||
|
{
|
||||||
|
"category": "container_scanning",
|
||||||
|
"message": {{ .Title | printf "%q" }},
|
||||||
|
"description": {{ .Description | printf "%q" }},
|
||||||
|
"cve": "{{ .VulnerabilityID }}",
|
||||||
|
"severity": {{ if eq .Severity "UNKNOWN" -}}
|
||||||
|
"Unknown"
|
||||||
|
{{- else if eq .Severity "LOW" -}}
|
||||||
|
"Low"
|
||||||
|
{{- else if eq .Severity "MEDIUM" -}}
|
||||||
|
"Medium"
|
||||||
|
{{- else if eq .Severity "HIGH" -}}
|
||||||
|
"High"
|
||||||
|
{{- else if eq .Severity "CRITICAL" -}}
|
||||||
|
"Critical"
|
||||||
|
{{- else -}}
|
||||||
|
"{{ .Severity }}"
|
||||||
|
{{- end }},
|
||||||
|
"confidence": "Unknown",
|
||||||
|
"solution": {{ if .FixedVersion -}}
|
||||||
|
"Upgrade {{ .PkgName }} to {{ .FixedVersion }}"
|
||||||
|
{{- else -}}
|
||||||
|
"No solution provided"
|
||||||
|
{{- end }},
|
||||||
|
"scanner": {
|
||||||
|
"id": "trivy",
|
||||||
|
"name": "trivy"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"dependency": {
|
||||||
|
"package": {
|
||||||
|
"name": "{{ .PkgName }}"
|
||||||
|
},
|
||||||
|
"version": "{{ .InstalledVersion }}"
|
||||||
|
},
|
||||||
|
{{- /* TODO: No mapping available - https://github.com/aquasecurity/trivy/issues/332 */}}
|
||||||
|
"operating_system": "Unknown",
|
||||||
|
"image": "{{ $target }}"
|
||||||
|
},
|
||||||
|
"identifiers": [
|
||||||
|
{
|
||||||
|
{{- /* TODO: Type not extractable - https://github.com/aquasecurity/trivy-db/pull/24 */}}
|
||||||
|
"type": "cve",
|
||||||
|
"name": "{{ .VulnerabilityID }}",
|
||||||
|
"value": "{{ .VulnerabilityID }}",
|
||||||
|
"url": ""
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"links": [
|
||||||
|
{{- $first := true -}}
|
||||||
|
{{- range .References -}}
|
||||||
|
{{- if $first -}}
|
||||||
|
{{- $first = false }}
|
||||||
|
{{- else -}}
|
||||||
|
,
|
||||||
|
{{- end -}}
|
||||||
|
{
|
||||||
|
"url": "{{ . }}"
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end }}
|
||||||
|
],
|
||||||
|
"remediations": []
|
||||||
|
}
|
||||||
409
contrib/install.sh
Executable file
409
contrib/install.sh
Executable file
@@ -0,0 +1,409 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
# Code generated by godownloader on 2020-01-14T10:03:29Z. DO NOT EDIT.
|
||||||
|
#
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
this=$1
|
||||||
|
cat <<EOF
|
||||||
|
$this: download go binaries for aquasecurity/trivy
|
||||||
|
|
||||||
|
Usage: $this [-b] bindir [-d] [tag]
|
||||||
|
-b sets bindir or installation directory, Defaults to ./bin
|
||||||
|
-d turns on debug logging
|
||||||
|
[tag] is a tag from
|
||||||
|
https://github.com/aquasecurity/trivy/releases
|
||||||
|
If tag is missing, then the latest will be used.
|
||||||
|
|
||||||
|
Generated by godownloader
|
||||||
|
https://github.com/goreleaser/godownloader
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 2
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_args() {
|
||||||
|
#BINDIR is ./bin unless set be ENV
|
||||||
|
# over-ridden by flag below
|
||||||
|
|
||||||
|
BINDIR=${BINDIR:-./bin}
|
||||||
|
while getopts "b:dh?x" arg; do
|
||||||
|
case "$arg" in
|
||||||
|
b) BINDIR="$OPTARG" ;;
|
||||||
|
d) log_set_priority 10 ;;
|
||||||
|
h | \?) usage "$0" ;;
|
||||||
|
x) set -x ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
TAG=$1
|
||||||
|
}
|
||||||
|
# this function wraps all the destructive operations
|
||||||
|
# if a curl|bash cuts off the end of the script due to
|
||||||
|
# network, either nothing will happen or will syntax error
|
||||||
|
# out preventing half-done work
|
||||||
|
execute() {
|
||||||
|
tmpdir=$(mktemp -d)
|
||||||
|
log_debug "downloading files into ${tmpdir}"
|
||||||
|
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}"
|
||||||
|
http_download "${tmpdir}/${CHECKSUM}" "${CHECKSUM_URL}"
|
||||||
|
hash_sha256_verify "${tmpdir}/${TARBALL}" "${tmpdir}/${CHECKSUM}"
|
||||||
|
srcdir="${tmpdir}"
|
||||||
|
(cd "${tmpdir}" && untar "${TARBALL}")
|
||||||
|
test ! -d "${BINDIR}" && install -d "${BINDIR}"
|
||||||
|
for binexe in $BINARIES; do
|
||||||
|
if [ "$OS" = "windows" ]; then
|
||||||
|
binexe="${binexe}.exe"
|
||||||
|
fi
|
||||||
|
install "${srcdir}/${binexe}" "${BINDIR}/"
|
||||||
|
log_info "installed ${BINDIR}/${binexe}"
|
||||||
|
done
|
||||||
|
rm -rf "${tmpdir}"
|
||||||
|
}
|
||||||
|
get_binaries() {
|
||||||
|
case "$PLATFORM" in
|
||||||
|
darwin/386) BINARIES="trivy" ;;
|
||||||
|
darwin/amd64) BINARIES="trivy" ;;
|
||||||
|
darwin/arm64) BINARIES="trivy" ;;
|
||||||
|
darwin/armv7) BINARIES="trivy" ;;
|
||||||
|
freebsd/386) BINARIES="trivy" ;;
|
||||||
|
freebsd/amd64) BINARIES="trivy" ;;
|
||||||
|
freebsd/arm64) BINARIES="trivy" ;;
|
||||||
|
freebsd/armv7) BINARIES="trivy" ;;
|
||||||
|
linux/386) BINARIES="trivy" ;;
|
||||||
|
linux/amd64) BINARIES="trivy" ;;
|
||||||
|
linux/arm64) BINARIES="trivy" ;;
|
||||||
|
linux/armv7) BINARIES="trivy" ;;
|
||||||
|
openbsd/386) BINARIES="trivy" ;;
|
||||||
|
openbsd/amd64) BINARIES="trivy" ;;
|
||||||
|
openbsd/arm64) BINARIES="trivy" ;;
|
||||||
|
openbsd/armv7) BINARIES="trivy" ;;
|
||||||
|
*)
|
||||||
|
log_crit "platform $PLATFORM is not supported. Make sure this script is up-to-date and file request at https://github.com/${PREFIX}/issues/new"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
tag_to_version() {
|
||||||
|
if [ -z "${TAG}" ]; then
|
||||||
|
log_info "checking GitHub for latest tag"
|
||||||
|
else
|
||||||
|
log_info "checking GitHub for tag '${TAG}'"
|
||||||
|
fi
|
||||||
|
REALTAG=$(github_release "$OWNER/$REPO" "${TAG}") && true
|
||||||
|
if test -z "$REALTAG"; then
|
||||||
|
log_crit "unable to find '${TAG}' - use 'latest' or see https://github.com/${PREFIX}/releases for details"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# if version starts with 'v', remove it
|
||||||
|
TAG="$REALTAG"
|
||||||
|
VERSION=${TAG#v}
|
||||||
|
}
|
||||||
|
adjust_format() {
|
||||||
|
# change format (tar.gz or zip) based on OS
|
||||||
|
true
|
||||||
|
}
|
||||||
|
adjust_os() {
|
||||||
|
# adjust archive name based on OS
|
||||||
|
case ${OS} in
|
||||||
|
386) OS=32bit ;;
|
||||||
|
amd64) OS=64bit ;;
|
||||||
|
arm) OS=ARM ;;
|
||||||
|
arm64) OS=ARM64 ;;
|
||||||
|
darwin) OS=macOS ;;
|
||||||
|
dragonfly) OS=DragonFlyBSD ;;
|
||||||
|
freebsd) OS=FreeBSD ;;
|
||||||
|
linux) OS=Linux ;;
|
||||||
|
netbsd) OS=NetBSD ;;
|
||||||
|
openbsd) OS=OpenBSD ;;
|
||||||
|
esac
|
||||||
|
true
|
||||||
|
}
|
||||||
|
adjust_arch() {
|
||||||
|
# adjust archive name based on ARCH
|
||||||
|
case ${ARCH} in
|
||||||
|
386) ARCH=32bit ;;
|
||||||
|
amd64) ARCH=64bit ;;
|
||||||
|
arm) ARCH=ARM ;;
|
||||||
|
arm64) ARCH=ARM64 ;;
|
||||||
|
darwin) ARCH=macOS ;;
|
||||||
|
dragonfly) ARCH=DragonFlyBSD ;;
|
||||||
|
freebsd) ARCH=FreeBSD ;;
|
||||||
|
linux) ARCH=Linux ;;
|
||||||
|
netbsd) ARCH=NetBSD ;;
|
||||||
|
openbsd) ARCH=OpenBSD ;;
|
||||||
|
esac
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
cat /dev/null <<EOF
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
https://github.com/client9/shlib - portable posix shell functions
|
||||||
|
Public domain - http://unlicense.org
|
||||||
|
https://github.com/client9/shlib/blob/master/LICENSE.md
|
||||||
|
but credit (and pull requests) appreciated.
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
EOF
|
||||||
|
is_command() {
|
||||||
|
command -v "$1" >/dev/null
|
||||||
|
}
|
||||||
|
echoerr() {
|
||||||
|
echo "$@" 1>&2
|
||||||
|
}
|
||||||
|
log_prefix() {
|
||||||
|
echo "$0"
|
||||||
|
}
|
||||||
|
_logp=6
|
||||||
|
log_set_priority() {
|
||||||
|
_logp="$1"
|
||||||
|
}
|
||||||
|
log_priority() {
|
||||||
|
if test -z "$1"; then
|
||||||
|
echo "$_logp"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
[ "$1" -le "$_logp" ]
|
||||||
|
}
|
||||||
|
log_tag() {
|
||||||
|
case $1 in
|
||||||
|
0) echo "emerg" ;;
|
||||||
|
1) echo "alert" ;;
|
||||||
|
2) echo "crit" ;;
|
||||||
|
3) echo "err" ;;
|
||||||
|
4) echo "warning" ;;
|
||||||
|
5) echo "notice" ;;
|
||||||
|
6) echo "info" ;;
|
||||||
|
7) echo "debug" ;;
|
||||||
|
*) echo "$1" ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
log_debug() {
|
||||||
|
log_priority 7 || return 0
|
||||||
|
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
|
||||||
|
}
|
||||||
|
log_info() {
|
||||||
|
log_priority 6 || return 0
|
||||||
|
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
|
||||||
|
}
|
||||||
|
log_err() {
|
||||||
|
log_priority 3 || return 0
|
||||||
|
echoerr "$(log_prefix)" "$(log_tag 3)" "$@"
|
||||||
|
}
|
||||||
|
log_crit() {
|
||||||
|
log_priority 2 || return 0
|
||||||
|
echoerr "$(log_prefix)" "$(log_tag 2)" "$@"
|
||||||
|
}
|
||||||
|
uname_os() {
|
||||||
|
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||||
|
case "$os" in
|
||||||
|
cygwin_nt*) os="windows" ;;
|
||||||
|
mingw*) os="windows" ;;
|
||||||
|
msys_nt*) os="windows" ;;
|
||||||
|
esac
|
||||||
|
echo "$os"
|
||||||
|
}
|
||||||
|
uname_arch() {
|
||||||
|
arch=$(uname -m)
|
||||||
|
case $arch in
|
||||||
|
x86_64) arch="amd64" ;;
|
||||||
|
x86) arch="386" ;;
|
||||||
|
i686) arch="386" ;;
|
||||||
|
i386) arch="386" ;;
|
||||||
|
aarch64) arch="arm64" ;;
|
||||||
|
armv5*) arch="armv5" ;;
|
||||||
|
armv6*) arch="armv6" ;;
|
||||||
|
armv7*) arch="armv7" ;;
|
||||||
|
esac
|
||||||
|
echo ${arch}
|
||||||
|
}
|
||||||
|
uname_os_check() {
|
||||||
|
os=$(uname_os)
|
||||||
|
case "$os" in
|
||||||
|
darwin) return 0 ;;
|
||||||
|
dragonfly) return 0 ;;
|
||||||
|
freebsd) return 0 ;;
|
||||||
|
linux) return 0 ;;
|
||||||
|
android) return 0 ;;
|
||||||
|
nacl) return 0 ;;
|
||||||
|
netbsd) return 0 ;;
|
||||||
|
openbsd) return 0 ;;
|
||||||
|
plan9) return 0 ;;
|
||||||
|
solaris) return 0 ;;
|
||||||
|
windows) return 0 ;;
|
||||||
|
esac
|
||||||
|
log_crit "uname_os_check '$(uname -s)' got converted to '$os' which is not a GOOS value. Please file bug at https://github.com/client9/shlib"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
uname_arch_check() {
|
||||||
|
arch=$(uname_arch)
|
||||||
|
case "$arch" in
|
||||||
|
386) return 0 ;;
|
||||||
|
amd64) return 0 ;;
|
||||||
|
arm64) return 0 ;;
|
||||||
|
armv5) return 0 ;;
|
||||||
|
armv6) return 0 ;;
|
||||||
|
armv7) return 0 ;;
|
||||||
|
ppc64) return 0 ;;
|
||||||
|
ppc64le) return 0 ;;
|
||||||
|
mips) return 0 ;;
|
||||||
|
mipsle) return 0 ;;
|
||||||
|
mips64) return 0 ;;
|
||||||
|
mips64le) return 0 ;;
|
||||||
|
s390x) return 0 ;;
|
||||||
|
amd64p32) return 0 ;;
|
||||||
|
esac
|
||||||
|
log_crit "uname_arch_check '$(uname -m)' got converted to '$arch' which is not a GOARCH value. Please file bug report at https://github.com/client9/shlib"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
untar() {
|
||||||
|
tarball=$1
|
||||||
|
case "${tarball}" in
|
||||||
|
*.tar.gz | *.tgz) tar --no-same-owner -xzf "${tarball}" ;;
|
||||||
|
*.tar) tar --no-same-owner -xf "${tarball}" ;;
|
||||||
|
*.zip) unzip "${tarball}" ;;
|
||||||
|
*)
|
||||||
|
log_err "untar unknown archive format for ${tarball}"
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
http_download_curl() {
|
||||||
|
local_file=$1
|
||||||
|
source_url=$2
|
||||||
|
header=$3
|
||||||
|
if [ -z "$header" ]; then
|
||||||
|
code=$(curl -w '%{http_code}' -sL -o "$local_file" "$source_url")
|
||||||
|
else
|
||||||
|
code=$(curl -w '%{http_code}' -sL -H "$header" -o "$local_file" "$source_url")
|
||||||
|
fi
|
||||||
|
if [ "$code" != "200" ]; then
|
||||||
|
log_debug "http_download_curl received HTTP status $code"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
http_download_wget() {
|
||||||
|
local_file=$1
|
||||||
|
source_url=$2
|
||||||
|
header=$3
|
||||||
|
if [ -z "$header" ]; then
|
||||||
|
wget -q -O "$local_file" "$source_url"
|
||||||
|
else
|
||||||
|
wget -q --header "$header" -O "$local_file" "$source_url"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
http_download() {
|
||||||
|
log_debug "http_download $2"
|
||||||
|
if is_command curl; then
|
||||||
|
http_download_curl "$@"
|
||||||
|
return
|
||||||
|
elif is_command wget; then
|
||||||
|
http_download_wget "$@"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
log_crit "http_download unable to find wget or curl"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
http_copy() {
|
||||||
|
tmp=$(mktemp)
|
||||||
|
http_download "${tmp}" "$1" "$2" || return 1
|
||||||
|
body=$(cat "$tmp")
|
||||||
|
rm -f "${tmp}"
|
||||||
|
echo "$body"
|
||||||
|
}
|
||||||
|
github_release() {
|
||||||
|
owner_repo=$1
|
||||||
|
version=$2
|
||||||
|
test -z "$version" && version="latest"
|
||||||
|
giturl="https://github.com/${owner_repo}/releases/${version}"
|
||||||
|
json=$(http_copy "$giturl" "Accept:application/json")
|
||||||
|
test -z "$json" && return 1
|
||||||
|
version=$(echo "$json" | tr -s '\n' ' ' | sed 's/.*"tag_name":"//' | sed 's/".*//')
|
||||||
|
test -z "$version" && return 1
|
||||||
|
echo "$version"
|
||||||
|
}
|
||||||
|
hash_sha256() {
|
||||||
|
TARGET=${1:-/dev/stdin}
|
||||||
|
if is_command gsha256sum; then
|
||||||
|
hash=$(gsha256sum "$TARGET") || return 1
|
||||||
|
echo "$hash" | cut -d ' ' -f 1
|
||||||
|
elif is_command sha256sum; then
|
||||||
|
hash=$(sha256sum "$TARGET") || return 1
|
||||||
|
echo "$hash" | cut -d ' ' -f 1
|
||||||
|
elif is_command shasum; then
|
||||||
|
hash=$(shasum -a 256 "$TARGET" 2>/dev/null) || return 1
|
||||||
|
echo "$hash" | cut -d ' ' -f 1
|
||||||
|
elif is_command openssl; then
|
||||||
|
hash=$(openssl -dst openssl dgst -sha256 "$TARGET") || return 1
|
||||||
|
echo "$hash" | cut -d ' ' -f a
|
||||||
|
else
|
||||||
|
log_crit "hash_sha256 unable to find command to compute sha-256 hash"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
hash_sha256_verify() {
|
||||||
|
TARGET=$1
|
||||||
|
checksums=$2
|
||||||
|
if [ -z "$checksums" ]; then
|
||||||
|
log_err "hash_sha256_verify checksum file not specified in arg2"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
BASENAME=${TARGET##*/}
|
||||||
|
want=$(grep "${BASENAME}" "${checksums}" 2>/dev/null | tr '\t' ' ' | cut -d ' ' -f 1)
|
||||||
|
if [ -z "$want" ]; then
|
||||||
|
log_err "hash_sha256_verify unable to find checksum for '${TARGET}' in '${checksums}'"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
got=$(hash_sha256 "$TARGET")
|
||||||
|
if [ "$want" != "$got" ]; then
|
||||||
|
log_err "hash_sha256_verify checksum for '$TARGET' did not verify ${want} vs $got"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
cat /dev/null <<EOF
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
End of functions from https://github.com/client9/shlib
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
EOF
|
||||||
|
|
||||||
|
PROJECT_NAME="trivy"
|
||||||
|
OWNER=aquasecurity
|
||||||
|
REPO="trivy"
|
||||||
|
BINARY=trivy
|
||||||
|
FORMAT=tar.gz
|
||||||
|
OS=$(uname_os)
|
||||||
|
ARCH=$(uname_arch)
|
||||||
|
PREFIX="$OWNER/$REPO"
|
||||||
|
|
||||||
|
# use in logging routines
|
||||||
|
log_prefix() {
|
||||||
|
echo "$PREFIX"
|
||||||
|
}
|
||||||
|
PLATFORM="${OS}/${ARCH}"
|
||||||
|
GITHUB_DOWNLOAD=https://github.com/${OWNER}/${REPO}/releases/download
|
||||||
|
|
||||||
|
uname_os_check "$OS"
|
||||||
|
uname_arch_check "$ARCH"
|
||||||
|
|
||||||
|
parse_args "$@"
|
||||||
|
|
||||||
|
get_binaries
|
||||||
|
|
||||||
|
tag_to_version
|
||||||
|
|
||||||
|
adjust_format
|
||||||
|
|
||||||
|
adjust_os
|
||||||
|
|
||||||
|
adjust_arch
|
||||||
|
|
||||||
|
log_info "found version: ${VERSION} for ${TAG}/${OS}/${ARCH}"
|
||||||
|
|
||||||
|
NAME=${PROJECT_NAME}_${VERSION}_${OS}-${ARCH}
|
||||||
|
TARBALL=${NAME}.${FORMAT}
|
||||||
|
TARBALL_URL=${GITHUB_DOWNLOAD}/${TAG}/${TARBALL}
|
||||||
|
CHECKSUM=${PROJECT_NAME}_${VERSION}_checksums.txt
|
||||||
|
CHECKSUM_URL=${GITHUB_DOWNLOAD}/${TAG}/${CHECKSUM}
|
||||||
|
|
||||||
|
|
||||||
|
execute
|
||||||
4
go.mod
4
go.mod
@@ -3,6 +3,7 @@ module github.com/aquasecurity/trivy
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 // indirect
|
||||||
github.com/aquasecurity/fanal v0.0.0-20200112144021-9a35ce3bd793
|
github.com/aquasecurity/fanal v0.0.0-20200112144021-9a35ce3bd793
|
||||||
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b
|
github.com/aquasecurity/go-dep-parser v0.0.0-20190819075924-ea223f0ef24b
|
||||||
github.com/aquasecurity/trivy-db v0.0.0-20191226181755-d6cabf5bc5d1
|
github.com/aquasecurity/trivy-db v0.0.0-20191226181755-d6cabf5bc5d1
|
||||||
@@ -20,8 +21,9 @@ require (
|
|||||||
github.com/knqyf263/go-version v1.1.1
|
github.com/knqyf263/go-version v1.1.1
|
||||||
github.com/kylelemons/godebug v1.1.0
|
github.com/kylelemons/godebug v1.1.0
|
||||||
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a
|
github.com/olekukonko/tablewriter v0.0.2-0.20190607075207-195002e6e56a
|
||||||
|
github.com/prometheus/procfs v0.0.5 // indirect
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
github.com/twitchtv/twirp v5.9.0+incompatible
|
github.com/twitchtv/twirp v5.10.1+incompatible
|
||||||
github.com/urfave/cli v1.20.0
|
github.com/urfave/cli v1.20.0
|
||||||
go.uber.org/atomic v1.5.1 // indirect
|
go.uber.org/atomic v1.5.1 // indirect
|
||||||
go.uber.org/multierr v1.4.0 // indirect
|
go.uber.org/multierr v1.4.0 // indirect
|
||||||
|
|||||||
10
go.sum
10
go.sum
@@ -10,6 +10,8 @@ github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0 h1:wykTgKwhVr2t2qs+x
|
|||||||
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
|
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0/go.mod h1:BB1eHdMLYEFuFdBlRMb0N7YGVdM5s6Pt0njxgvfbGGs=
|
||||||
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
|
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
|
||||||
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||||
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6trr62pF5DucadTWGdEB4mEyvzi0e2nbcmcyA=
|
||||||
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
|
||||||
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
@@ -263,6 +265,8 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ
|
|||||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
|
||||||
@@ -293,8 +297,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
|||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00 h1:0e4vRd9YqnQBIAIAE39jLKDWffRfJWxloyWwcaMAQho=
|
github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00 h1:0e4vRd9YqnQBIAIAE39jLKDWffRfJWxloyWwcaMAQho=
|
||||||
github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00/go.mod h1:RQE7h2jyIxekQZ24/wad0c9RGP+KSq4XzHh7h83ALi8=
|
github.com/tomoyamachi/reg v0.16.1-0.20190706172545-2a2250fd7c00/go.mod h1:RQE7h2jyIxekQZ24/wad0c9RGP+KSq4XzHh7h83ALi8=
|
||||||
github.com/twitchtv/twirp v5.9.0+incompatible h1:KBCo4NYCpE9alO1HAEcgninDnw/0AhPT1rZnHkkSqi8=
|
github.com/twitchtv/twirp v5.10.1+incompatible h1:35js8ID9rYPKkZ0qWnuZw+q+OuCWM1GIibu1F1YImjA=
|
||||||
github.com/twitchtv/twirp v5.9.0+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
|
github.com/twitchtv/twirp v5.10.1+incompatible/go.mod h1:RRJoFSAmTEh2weEqWtpPE3vFK5YBhA6bqp2l1kfCC5A=
|
||||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
|
github.com/xanzy/ssh-agent v0.2.0/go.mod h1:0NyE30eGUDliuLEHJgYte/zncp2zdTStcOnWhgSqHD8=
|
||||||
@@ -356,6 +360,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/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=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180903190138-2b024373dcd9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -371,6 +376,7 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e h1:bq5BY1tGuaK8HxuwN6pT6kWgTVLeJ5KwuyBpsl1CZL4=
|
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e h1:bq5BY1tGuaK8HxuwN6pT6kWgTVLeJ5KwuyBpsl1CZL4=
|
||||||
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190506115046-ca7f33d4116e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191105231009-c1f44814a5cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 h1:ZBzSG/7F4eNKz2L3GE9o300RX0Az1Bw5HF7PDraD+qU=
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ nfpms:
|
|||||||
homepage: "https://github.com/aquasecurity"
|
homepage: "https://github.com/aquasecurity"
|
||||||
maintainer: "Teppei Fukuda <knqyf263@gmail.com>"
|
maintainer: "Teppei Fukuda <knqyf263@gmail.com>"
|
||||||
description: "A Fast Vulnerability Scanner for Containers"
|
description: "A Fast Vulnerability Scanner for Containers"
|
||||||
license: "MIT"
|
license: "AGPL-3.0"
|
||||||
name_template: "{{.ProjectName}}_{{.Version}}_{{.Os}}-{{.Arch}}"
|
file_name_template: "{{.ProjectName}}_{{.Version}}_{{.Os}}-{{.Arch}}"
|
||||||
replacements:
|
replacements:
|
||||||
amd64: 64bit
|
amd64: 64bit
|
||||||
386: 32bit
|
386: 32bit
|
||||||
@@ -65,6 +65,7 @@ archives:
|
|||||||
files:
|
files:
|
||||||
- README.md
|
- README.md
|
||||||
- LICENSE
|
- LICENSE
|
||||||
|
- contrib/gitlab.tpl
|
||||||
|
|
||||||
brews:
|
brews:
|
||||||
-
|
-
|
||||||
@@ -93,3 +94,5 @@ dockers:
|
|||||||
- "--label=org.label-schema.build-date={{ .Date }}"
|
- "--label=org.label-schema.build-date={{ .Date }}"
|
||||||
- "--label=org.label-schema.vcs=https://github.com/aquasecurity/trivy"
|
- "--label=org.label-schema.vcs=https://github.com/aquasecurity/trivy"
|
||||||
- "--label=org.label-schema.vcs-ref={{ .FullCommit }}"
|
- "--label=org.label-schema.vcs-ref={{ .FullCommit }}"
|
||||||
|
extra_files:
|
||||||
|
- contrib/gitlab.tpl
|
||||||
|
|||||||
26
integration/testdata/centos-6.json.golden
vendored
26
integration/testdata/centos-6.json.golden
vendored
@@ -12628,6 +12628,32 @@
|
|||||||
"https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug"
|
"https://utcc.utoronto.ca/~cks/space/blog/sysadmin/TarFindingTruncateBug"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"VulnerabilityID": "CVE-2019-12735",
|
||||||
|
"PkgName": "vim-minimal",
|
||||||
|
"InstalledVersion": "2:7.4.629-5.el6_8.1",
|
||||||
|
"FixedVersion": "2:7.4.629-5.el6_10.2",
|
||||||
|
"Title": "vim/neovim: ':source!' command allows arbitrary command execution via modelines",
|
||||||
|
"Description": "getchar.c in Vim before 8.1.1365 and Neovim before 0.3.6 allows remote attackers to execute arbitrary OS commands via the :source! command in a modeline, as demonstrated by execute in Vim, and assert_fails or nvim_input in Neovim.",
|
||||||
|
"Severity": "CRITICAL",
|
||||||
|
"References": [
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00031.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00036.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00037.html",
|
||||||
|
"http://www.securityfocus.com/bid/108724",
|
||||||
|
"https://bugs.debian.org/930020",
|
||||||
|
"https://bugs.debian.org/930024",
|
||||||
|
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12735",
|
||||||
|
"https://github.com/neovim/neovim/pull/10082",
|
||||||
|
"https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md",
|
||||||
|
"https://github.com/vim/vim/commit/53575521406739cf20bbe4e384d88e7dca11f040",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/2BMDSHTF754TITC6AQJPCS5IRIDMMIM7/",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/TRIRBC2YRGKPAWVRMZS4SZTGGCVRVZPR/",
|
||||||
|
"https://usn.ubuntu.com/4016-1/",
|
||||||
|
"https://usn.ubuntu.com/4016-2/",
|
||||||
|
"https://www.debian.org/security/2019/dsa-4467"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"VulnerabilityID": "CVE-2017-5953",
|
"VulnerabilityID": "CVE-2017-5953",
|
||||||
"PkgName": "vim-minimal",
|
"PkgName": "vim-minimal",
|
||||||
|
|||||||
@@ -112,6 +112,32 @@
|
|||||||
"https://usn.ubuntu.com/3816-1/",
|
"https://usn.ubuntu.com/3816-1/",
|
||||||
"https://www.exploit-db.com/exploits/45714/"
|
"https://www.exploit-db.com/exploits/45714/"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"VulnerabilityID": "CVE-2019-12735",
|
||||||
|
"PkgName": "vim-minimal",
|
||||||
|
"InstalledVersion": "2:7.4.160-5.el7",
|
||||||
|
"FixedVersion": "2:7.4.160-6.el7_6",
|
||||||
|
"Title": "vim/neovim: ':source!' command allows arbitrary command execution via modelines",
|
||||||
|
"Description": "getchar.c in Vim before 8.1.1365 and Neovim before 0.3.6 allows remote attackers to execute arbitrary OS commands via the :source! command in a modeline, as demonstrated by execute in Vim, and assert_fails or nvim_input in Neovim.",
|
||||||
|
"Severity": "CRITICAL",
|
||||||
|
"References": [
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00031.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00036.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00037.html",
|
||||||
|
"http://www.securityfocus.com/bid/108724",
|
||||||
|
"https://bugs.debian.org/930020",
|
||||||
|
"https://bugs.debian.org/930024",
|
||||||
|
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12735",
|
||||||
|
"https://github.com/neovim/neovim/pull/10082",
|
||||||
|
"https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md",
|
||||||
|
"https://github.com/vim/vim/commit/53575521406739cf20bbe4e384d88e7dca11f040",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/2BMDSHTF754TITC6AQJPCS5IRIDMMIM7/",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/TRIRBC2YRGKPAWVRMZS4SZTGGCVRVZPR/",
|
||||||
|
"https://usn.ubuntu.com/4016-1/",
|
||||||
|
"https://usn.ubuntu.com/4016-2/",
|
||||||
|
"https://www.debian.org/security/2019/dsa-4467"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1708,6 +1708,32 @@
|
|||||||
"https://lists.apache.org/thread.html/5960a34a524848cd722fd7ab7e2227eac10107b0f90d9d1e9c3caa74@%3Cuser.cassandra.apache.org%3E",
|
"https://lists.apache.org/thread.html/5960a34a524848cd722fd7ab7e2227eac10107b0f90d9d1e9c3caa74@%3Cuser.cassandra.apache.org%3E",
|
||||||
"https://security.netapp.com/advisory/ntap-20190307-0007/"
|
"https://security.netapp.com/advisory/ntap-20190307-0007/"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"VulnerabilityID": "CVE-2019-12735",
|
||||||
|
"PkgName": "vim-minimal",
|
||||||
|
"InstalledVersion": "2:7.4.160-5.el7",
|
||||||
|
"FixedVersion": "2:7.4.160-6.el7_6",
|
||||||
|
"Title": "vim/neovim: ':source!' command allows arbitrary command execution via modelines",
|
||||||
|
"Description": "getchar.c in Vim before 8.1.1365 and Neovim before 0.3.6 allows remote attackers to execute arbitrary OS commands via the :source! command in a modeline, as demonstrated by execute in Vim, and assert_fails or nvim_input in Neovim.",
|
||||||
|
"Severity": "CRITICAL",
|
||||||
|
"References": [
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00031.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00036.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00037.html",
|
||||||
|
"http://www.securityfocus.com/bid/108724",
|
||||||
|
"https://bugs.debian.org/930020",
|
||||||
|
"https://bugs.debian.org/930024",
|
||||||
|
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12735",
|
||||||
|
"https://github.com/neovim/neovim/pull/10082",
|
||||||
|
"https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md",
|
||||||
|
"https://github.com/vim/vim/commit/53575521406739cf20bbe4e384d88e7dca11f040",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/2BMDSHTF754TITC6AQJPCS5IRIDMMIM7/",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/TRIRBC2YRGKPAWVRMZS4SZTGGCVRVZPR/",
|
||||||
|
"https://usn.ubuntu.com/4016-1/",
|
||||||
|
"https://usn.ubuntu.com/4016-2/",
|
||||||
|
"https://www.debian.org/security/2019/dsa-4467"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
26
integration/testdata/centos-7.json.golden
vendored
26
integration/testdata/centos-7.json.golden
vendored
@@ -11849,6 +11849,32 @@
|
|||||||
"https://www.kernel.org/pub/linux/utils/util-linux/v2.27/v2.27-ReleaseNotes"
|
"https://www.kernel.org/pub/linux/utils/util-linux/v2.27/v2.27-ReleaseNotes"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"VulnerabilityID": "CVE-2019-12735",
|
||||||
|
"PkgName": "vim-minimal",
|
||||||
|
"InstalledVersion": "2:7.4.160-5.el7",
|
||||||
|
"FixedVersion": "2:7.4.160-6.el7_6",
|
||||||
|
"Title": "vim/neovim: ':source!' command allows arbitrary command execution via modelines",
|
||||||
|
"Description": "getchar.c in Vim before 8.1.1365 and Neovim before 0.3.6 allows remote attackers to execute arbitrary OS commands via the :source! command in a modeline, as demonstrated by execute in Vim, and assert_fails or nvim_input in Neovim.",
|
||||||
|
"Severity": "CRITICAL",
|
||||||
|
"References": [
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00031.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00036.html",
|
||||||
|
"http://lists.opensuse.org/opensuse-security-announce/2019-06/msg00037.html",
|
||||||
|
"http://www.securityfocus.com/bid/108724",
|
||||||
|
"https://bugs.debian.org/930020",
|
||||||
|
"https://bugs.debian.org/930024",
|
||||||
|
"https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12735",
|
||||||
|
"https://github.com/neovim/neovim/pull/10082",
|
||||||
|
"https://github.com/numirias/security/blob/master/doc/2019-06-04_ace-vim-neovim.md",
|
||||||
|
"https://github.com/vim/vim/commit/53575521406739cf20bbe4e384d88e7dca11f040",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/2BMDSHTF754TITC6AQJPCS5IRIDMMIM7/",
|
||||||
|
"https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/TRIRBC2YRGKPAWVRMZS4SZTGGCVRVZPR/",
|
||||||
|
"https://usn.ubuntu.com/4016-1/",
|
||||||
|
"https://usn.ubuntu.com/4016-2/",
|
||||||
|
"https://www.debian.org/security/2019/dsa-4467"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"VulnerabilityID": "CVE-2017-5953",
|
"VulnerabilityID": "CVE-2017-5953",
|
||||||
"PkgName": "vim-minimal",
|
"PkgName": "vim-minimal",
|
||||||
|
|||||||
@@ -108,6 +108,9 @@ func (c *Config) Init() (err error) {
|
|||||||
c.logger.Error(`trivy requires at least 1 argument or --input option`)
|
c.logger.Error(`trivy requires at least 1 argument or --input option`)
|
||||||
cli.ShowAppHelp(c.context)
|
cli.ShowAppHelp(c.context)
|
||||||
return xerrors.New("arguments error")
|
return xerrors.New("arguments error")
|
||||||
|
} else if len(args) > 1 {
|
||||||
|
c.logger.Error(`multiple images cannot be specified`)
|
||||||
|
return xerrors.New("arguments error")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Output = os.Stdout
|
c.Output = os.Stdout
|
||||||
|
|||||||
@@ -165,6 +165,17 @@ func TestConfig_Init(t *testing.T) {
|
|||||||
CustomHeaders: make(http.Header),
|
CustomHeaders: make(http.Header),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "sad: multiple image names",
|
||||||
|
fields: fields{
|
||||||
|
severities: "MEDIUM",
|
||||||
|
},
|
||||||
|
args: []string{"centos:7", "alpine:3.10"},
|
||||||
|
logs: []string{
|
||||||
|
"multiple images cannot be specified",
|
||||||
|
},
|
||||||
|
wantErr: "arguments error",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "sad: no image name",
|
name: "sad: no image name",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
|
|||||||
@@ -97,6 +97,16 @@ func New(c *cli.Context) (Config, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Config) Init() (err error) {
|
func (c *Config) Init() (err error) {
|
||||||
|
if c.Template != "" {
|
||||||
|
if c.Format == "" {
|
||||||
|
c.logger.Warn("--template is ignored because --format template is not specified. Use --template option with --format template option.")
|
||||||
|
} else if c.Format != "template" {
|
||||||
|
c.logger.Warnf("--template is ignored because --format %s is specified. Use --template option with --format template option.", c.Format)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if c.Format == "template" && c.Template == "" {
|
||||||
|
c.logger.Warn("--format template is ignored because --template not is specified. Specify --template option when you use --format template.")
|
||||||
|
}
|
||||||
if c.onlyUpdate != "" || c.refresh || c.autoRefresh {
|
if c.onlyUpdate != "" || c.refresh || c.autoRefresh {
|
||||||
c.logger.Warn("--only-update, --refresh and --auto-refresh are unnecessary and ignored now. These commands will be removed in the next version.")
|
c.logger.Warn("--only-update, --refresh and --auto-refresh are unnecessary and ignored now. These commands will be removed in the next version.")
|
||||||
}
|
}
|
||||||
@@ -118,6 +128,9 @@ func (c *Config) Init() (err error) {
|
|||||||
c.logger.Error(`trivy requires at least 1 argument or --input option`)
|
c.logger.Error(`trivy requires at least 1 argument or --input option`)
|
||||||
cli.ShowAppHelp(c.context)
|
cli.ShowAppHelp(c.context)
|
||||||
return xerrors.New("arguments error")
|
return xerrors.New("arguments error")
|
||||||
|
} else if len(args) > 1 {
|
||||||
|
c.logger.Error(`multiple images cannot be specified`)
|
||||||
|
return xerrors.New("arguments error")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Output = os.Stdout
|
c.Output = os.Stdout
|
||||||
|
|||||||
@@ -168,6 +168,68 @@ func TestConfig_Init(t *testing.T) {
|
|||||||
onlyUpdate: "alpine",
|
onlyUpdate: "alpine",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid option combination: --template enabled without --format",
|
||||||
|
fields: fields{
|
||||||
|
Template: "@contrib/gitlab.tpl",
|
||||||
|
severities: "LOW",
|
||||||
|
},
|
||||||
|
args: []string{"gitlab/gitlab-ce:12.7.2-ce.0"},
|
||||||
|
logs: []string{
|
||||||
|
"--template is ignored because --format template is not specified. Use --template option with --format template option.",
|
||||||
|
},
|
||||||
|
want: Config{
|
||||||
|
AppVersion: "0.0.0",
|
||||||
|
ImageName: "gitlab/gitlab-ce:12.7.2-ce.0",
|
||||||
|
Output: os.Stdout,
|
||||||
|
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
|
||||||
|
severities: "LOW",
|
||||||
|
Template: "@contrib/gitlab.tpl",
|
||||||
|
VulnType: []string{""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid option combination: --template and --format json",
|
||||||
|
fields: fields{
|
||||||
|
Format: "json",
|
||||||
|
Template: "@contrib/gitlab.tpl",
|
||||||
|
severities: "LOW",
|
||||||
|
},
|
||||||
|
args: []string{"gitlab/gitlab-ce:12.7.2-ce.0"},
|
||||||
|
logs: []string{
|
||||||
|
"--template is ignored because --format json is specified. Use --template option with --format template option.",
|
||||||
|
},
|
||||||
|
want: Config{
|
||||||
|
AppVersion: "0.0.0",
|
||||||
|
Format: "json",
|
||||||
|
ImageName: "gitlab/gitlab-ce:12.7.2-ce.0",
|
||||||
|
Output: os.Stdout,
|
||||||
|
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
|
||||||
|
severities: "LOW",
|
||||||
|
Template: "@contrib/gitlab.tpl",
|
||||||
|
VulnType: []string{""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid option combination: --format template without --template",
|
||||||
|
fields: fields{
|
||||||
|
Format: "template",
|
||||||
|
severities: "LOW",
|
||||||
|
},
|
||||||
|
args: []string{"gitlab/gitlab-ce:12.7.2-ce.0"},
|
||||||
|
logs: []string{
|
||||||
|
"--format template is ignored because --template not is specified. Specify --template option when you use --format template.",
|
||||||
|
},
|
||||||
|
want: Config{
|
||||||
|
AppVersion: "0.0.0",
|
||||||
|
Format: "template",
|
||||||
|
ImageName: "gitlab/gitlab-ce:12.7.2-ce.0",
|
||||||
|
Output: os.Stdout,
|
||||||
|
Severities: []dbTypes.Severity{dbTypes.SeverityLow},
|
||||||
|
severities: "LOW",
|
||||||
|
VulnType: []string{""},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "with latest tag",
|
name: "with latest tag",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
@@ -204,6 +266,17 @@ func TestConfig_Init(t *testing.T) {
|
|||||||
},
|
},
|
||||||
wantErr: "The --skip-update and --download-db-only option can not be specified both",
|
wantErr: "The --skip-update and --download-db-only option can not be specified both",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "sad: multiple image names",
|
||||||
|
fields: fields{
|
||||||
|
severities: "MEDIUM",
|
||||||
|
},
|
||||||
|
args: []string{"centos:7", "alpine:3.10"},
|
||||||
|
logs: []string{
|
||||||
|
"multiple images cannot be specified",
|
||||||
|
},
|
||||||
|
wantErr: "arguments error",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "sad: no image name",
|
name: "sad: no image name",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package standalone
|
package standalone
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
l "log"
|
l "log"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/aquasecurity/fanal/cache"
|
"github.com/aquasecurity/fanal/cache"
|
||||||
"github.com/aquasecurity/trivy-db/pkg/db"
|
"github.com/aquasecurity/trivy-db/pkg/db"
|
||||||
@@ -80,7 +82,17 @@ func run(c config.Config) (err error) {
|
|||||||
c.Severities, c.IgnoreUnfixed, c.IgnoreFile)
|
c.Severities, c.IgnoreUnfixed, c.IgnoreFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = report.WriteResults(c.Format, c.Output, results, c.Template, c.Light); err != nil {
|
template := c.Template
|
||||||
|
|
||||||
|
if strings.HasPrefix(c.Template, "@") {
|
||||||
|
buf, err := ioutil.ReadFile(strings.TrimPrefix(c.Template, "@"))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("Error retrieving template from path: %w", err)
|
||||||
|
}
|
||||||
|
template = string(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = report.WriteResults(c.Format, c.Output, results, template, c.Light); err != nil {
|
||||||
return xerrors.Errorf("unable to write results: %w", err)
|
return xerrors.Errorf("unable to write results: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package library
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ var SuperSet = wire.NewSet(
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Operation interface {
|
type Operation interface {
|
||||||
Detect(string, []ptypes.Library) ([]types.DetectedVulnerability, error)
|
Detect(string, string, time.Time, []ptypes.Library) ([]types.DetectedVulnerability, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Detector struct {
|
type Detector struct {
|
||||||
@@ -34,7 +35,7 @@ func NewDetector(factory Factory) Detector {
|
|||||||
return Detector{driverFactory: factory}
|
return Detector{driverFactory: factory}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Detector) Detect(filePath string, pkgs []ptypes.Library) ([]types.DetectedVulnerability, error) {
|
func (d Detector) Detect(_ string, filePath string, _ time.Time, pkgs []ptypes.Library) ([]types.DetectedVulnerability, error) {
|
||||||
log.Logger.Debugf("Detecting library vulnerabilities, path: %s", filePath)
|
log.Logger.Debugf("Detecting library vulnerabilities, path: %s", filePath)
|
||||||
driver := d.driverFactory.NewDriver(filepath.Base(filePath))
|
driver := d.driverFactory.NewDriver(filepath.Base(filePath))
|
||||||
if driver == nil {
|
if driver == nil {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package library
|
package library
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
ptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
ptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
||||||
"github.com/aquasecurity/trivy/pkg/types"
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@@ -11,8 +13,10 @@ type MockDetector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DetectInput struct {
|
type DetectInput struct {
|
||||||
FilePath string
|
ImageName string
|
||||||
Libs []ptypes.Library
|
FilePath string
|
||||||
|
Created time.Time
|
||||||
|
Libs []ptypes.Library
|
||||||
}
|
}
|
||||||
type DetectOutput struct {
|
type DetectOutput struct {
|
||||||
Vulns []types.DetectedVulnerability
|
Vulns []types.DetectedVulnerability
|
||||||
@@ -26,14 +30,14 @@ type DetectExpectation struct {
|
|||||||
func NewMockDetector(detectExpectations []DetectExpectation) *MockDetector {
|
func NewMockDetector(detectExpectations []DetectExpectation) *MockDetector {
|
||||||
mockDetector := new(MockDetector)
|
mockDetector := new(MockDetector)
|
||||||
for _, e := range detectExpectations {
|
for _, e := range detectExpectations {
|
||||||
mockDetector.On("Detect", e.Args.FilePath, e.Args.Libs).Return(
|
mockDetector.On("Detect", e.Args.ImageName, e.Args.FilePath, e.Args.Created, e.Args.Libs).Return(
|
||||||
e.ReturnArgs.Vulns, e.ReturnArgs.Err)
|
e.ReturnArgs.Vulns, e.ReturnArgs.Err)
|
||||||
}
|
}
|
||||||
return mockDetector
|
return mockDetector
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_m *MockDetector) Detect(a string, b []ptypes.Library) ([]types.DetectedVulnerability, error) {
|
func (_m *MockDetector) Detect(a, b string, c time.Time, d []ptypes.Library) ([]types.DetectedVulnerability, error) {
|
||||||
ret := _m.Called(a, b)
|
ret := _m.Called(a, b, c, d)
|
||||||
ret0 := ret.Get(0)
|
ret0 := ret.Get(0)
|
||||||
if ret0 == nil {
|
if ret0 == nil {
|
||||||
return nil, ret.Error(1)
|
return nil, ret.Error(1)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package ospkg
|
package ospkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aquasecurity/trivy/pkg/detector/ospkg/alpine"
|
"github.com/aquasecurity/trivy/pkg/detector/ospkg/alpine"
|
||||||
"github.com/aquasecurity/trivy/pkg/detector/ospkg/amazon"
|
"github.com/aquasecurity/trivy/pkg/detector/ospkg/amazon"
|
||||||
"github.com/aquasecurity/trivy/pkg/detector/ospkg/debian"
|
"github.com/aquasecurity/trivy/pkg/detector/ospkg/debian"
|
||||||
@@ -28,7 +30,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Operation interface {
|
type Operation interface {
|
||||||
Detect(string, string, []analyzer.Package) ([]types.DetectedVulnerability, bool, error)
|
Detect(string, string, string, time.Time, []analyzer.Package) ([]types.DetectedVulnerability, bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Driver interface {
|
type Driver interface {
|
||||||
@@ -38,7 +40,7 @@ type Driver interface {
|
|||||||
|
|
||||||
type Detector struct{}
|
type Detector struct{}
|
||||||
|
|
||||||
func (d Detector) Detect(osFamily, osName string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, bool, error) {
|
func (d Detector) Detect(_, osFamily, osName string, _ time.Time, pkgs []analyzer.Package) ([]types.DetectedVulnerability, bool, error) {
|
||||||
driver := newDriver(osFamily, osName)
|
driver := newDriver(osFamily, osName)
|
||||||
if driver == nil {
|
if driver == nil {
|
||||||
return nil, false, ErrUnsupportedOS
|
return nil, false, ErrUnsupportedOS
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package ospkg
|
package ospkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aquasecurity/fanal/analyzer"
|
"github.com/aquasecurity/fanal/analyzer"
|
||||||
"github.com/aquasecurity/trivy/pkg/types"
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@@ -11,9 +13,11 @@ type MockDetector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type DetectInput struct {
|
type DetectInput struct {
|
||||||
OSFamily string
|
ImageName string
|
||||||
OSName string
|
OSFamily string
|
||||||
Pkgs []analyzer.Package
|
OSName string
|
||||||
|
Created time.Time
|
||||||
|
Pkgs []analyzer.Package
|
||||||
}
|
}
|
||||||
type DetectOutput struct {
|
type DetectOutput struct {
|
||||||
Vulns []types.DetectedVulnerability
|
Vulns []types.DetectedVulnerability
|
||||||
@@ -28,14 +32,14 @@ type DetectExpectation struct {
|
|||||||
func NewMockDetector(detectExpectations []DetectExpectation) *MockDetector {
|
func NewMockDetector(detectExpectations []DetectExpectation) *MockDetector {
|
||||||
mockDetector := new(MockDetector)
|
mockDetector := new(MockDetector)
|
||||||
for _, e := range detectExpectations {
|
for _, e := range detectExpectations {
|
||||||
mockDetector.On("Detect", e.Args.OSFamily, e.Args.OSName, e.Args.Pkgs).Return(
|
mockDetector.On("Detect", e.Args.ImageName, e.Args.OSFamily, e.Args.OSName, e.Args.Created, e.Args.Pkgs).Return(
|
||||||
e.ReturnArgs.Vulns, e.ReturnArgs.Eosl, e.ReturnArgs.Err)
|
e.ReturnArgs.Vulns, e.ReturnArgs.Eosl, e.ReturnArgs.Err)
|
||||||
}
|
}
|
||||||
return mockDetector
|
return mockDetector
|
||||||
}
|
}
|
||||||
|
|
||||||
func (_m *MockDetector) Detect(a, b string, c []analyzer.Package) ([]types.DetectedVulnerability, bool, error) {
|
func (_m *MockDetector) Detect(a string, b string, c string, d time.Time, e []analyzer.Package) ([]types.DetectedVulnerability, bool, error) {
|
||||||
ret := _m.Called(a, b, c)
|
ret := _m.Called(a, b, c, d, e)
|
||||||
ret0 := ret.Get(0)
|
ret0 := ret.Get(0)
|
||||||
if ret0 == nil {
|
if ret0 == nil {
|
||||||
return nil, false, ret.Error(2)
|
return nil, false, ret.Error(2)
|
||||||
|
|||||||
@@ -57,25 +57,42 @@ func (s *Scanner) Detect(osVer string, pkgs []analyzer.Package) ([]types.Detecte
|
|||||||
|
|
||||||
var vulns []types.DetectedVulnerability
|
var vulns []types.DetectedVulnerability
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
|
// For Red Hat Security Data API containing only source package names
|
||||||
advisories, err := s.vs.Get(osVer, pkg.SrcName)
|
advisories, err := s.vs.Get(osVer, pkg.SrcName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
|
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
installed := utils.FormatSrcVersion(pkg)
|
installed := utils.FormatVersion(pkg)
|
||||||
installedVersion := version.NewVersion(installed)
|
installedVersion := version.NewVersion(installed)
|
||||||
for _, adv := range advisories {
|
|
||||||
fixedVersion := version.NewVersion(adv.FixedVersion)
|
|
||||||
|
|
||||||
|
for _, adv := range advisories {
|
||||||
|
if adv.FixedVersion != "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
vuln := types.DetectedVulnerability{
|
vuln := types.DetectedVulnerability{
|
||||||
VulnerabilityID: adv.VulnerabilityID,
|
VulnerabilityID: adv.VulnerabilityID,
|
||||||
PkgName: pkg.Name,
|
PkgName: pkg.Name,
|
||||||
InstalledVersion: installed,
|
InstalledVersion: installed,
|
||||||
}
|
}
|
||||||
|
vulns = append(vulns, vuln)
|
||||||
|
}
|
||||||
|
|
||||||
|
// For Red Hat OVAL containing only binary package names
|
||||||
|
advisories, err = s.vs.Get(osVer, pkg.Name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, adv := range advisories {
|
||||||
|
fixedVersion := version.NewVersion(adv.FixedVersion)
|
||||||
if installedVersion.LessThan(fixedVersion) {
|
if installedVersion.LessThan(fixedVersion) {
|
||||||
vuln.FixedVersion = fixedVersion.String()
|
vuln := types.DetectedVulnerability{
|
||||||
vulns = append(vulns, vuln)
|
VulnerabilityID: adv.VulnerabilityID,
|
||||||
} else if adv.FixedVersion == "" {
|
PkgName: pkg.Name,
|
||||||
|
InstalledVersion: installed,
|
||||||
|
FixedVersion: fixedVersion.String(),
|
||||||
|
}
|
||||||
vulns = append(vulns, vuln)
|
vulns = append(vulns, vuln)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,14 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/aquasecurity/fanal/analyzer"
|
||||||
|
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||||
"github.com/aquasecurity/trivy/pkg/log"
|
"github.com/aquasecurity/trivy/pkg/log"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@@ -13,6 +20,196 @@ func TestMain(m *testing.M) {
|
|||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestScanner_Detect(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
osVer string
|
||||||
|
pkgs []analyzer.Package
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
get []dbTypes.GetExpectation
|
||||||
|
want []types.DetectedVulnerability
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "happy path: src pkg name is different from bin pkg name",
|
||||||
|
args: args{
|
||||||
|
osVer: "7.6",
|
||||||
|
pkgs: []analyzer.Package{
|
||||||
|
{
|
||||||
|
Name: "vim-minimal",
|
||||||
|
Version: "7.4.160",
|
||||||
|
Release: "5.el7",
|
||||||
|
Epoch: 2,
|
||||||
|
Arch: "x86_64",
|
||||||
|
SrcName: "vim",
|
||||||
|
SrcVersion: "7.4.160",
|
||||||
|
SrcRelease: "5.el7",
|
||||||
|
SrcEpoch: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
get: []dbTypes.GetExpectation{
|
||||||
|
{
|
||||||
|
Args: dbTypes.GetArgs{
|
||||||
|
Release: "7",
|
||||||
|
PkgName: "vim",
|
||||||
|
},
|
||||||
|
Returns: dbTypes.GetReturns{
|
||||||
|
Advisories: []dbTypes.Advisory{
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2017-5953",
|
||||||
|
FixedVersion: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2017-6350",
|
||||||
|
FixedVersion: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Args: dbTypes.GetArgs{
|
||||||
|
Release: "7",
|
||||||
|
PkgName: "vim-minimal",
|
||||||
|
},
|
||||||
|
Returns: dbTypes.GetReturns{
|
||||||
|
Advisories: []dbTypes.Advisory{
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2019-12735",
|
||||||
|
FixedVersion: "2:7.4.160-6.el7_6",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []types.DetectedVulnerability{
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2017-5953",
|
||||||
|
PkgName: "vim-minimal",
|
||||||
|
InstalledVersion: "2:7.4.160-5.el7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2017-6350",
|
||||||
|
PkgName: "vim-minimal",
|
||||||
|
InstalledVersion: "2:7.4.160-5.el7",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2019-12735",
|
||||||
|
PkgName: "vim-minimal",
|
||||||
|
InstalledVersion: "2:7.4.160-5.el7",
|
||||||
|
FixedVersion: "2:7.4.160-6.el7_6",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "happy path: src pkg name is the same as bin pkg name",
|
||||||
|
args: args{
|
||||||
|
osVer: "6.5",
|
||||||
|
pkgs: []analyzer.Package{
|
||||||
|
{
|
||||||
|
Name: "nss",
|
||||||
|
Version: "3.36.0",
|
||||||
|
Release: "7.1.el7_6",
|
||||||
|
Epoch: 0,
|
||||||
|
Arch: "x86_64",
|
||||||
|
SrcName: "nss",
|
||||||
|
SrcVersion: "3.36.0",
|
||||||
|
SrcRelease: "7.4.160",
|
||||||
|
SrcEpoch: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
get: []dbTypes.GetExpectation{
|
||||||
|
{
|
||||||
|
Args: dbTypes.GetArgs{
|
||||||
|
Release: "6",
|
||||||
|
PkgName: "nss",
|
||||||
|
},
|
||||||
|
Returns: dbTypes.GetReturns{
|
||||||
|
Advisories: []dbTypes.Advisory{
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2015-2808",
|
||||||
|
FixedVersion: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2016-2183",
|
||||||
|
FixedVersion: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2018-12404",
|
||||||
|
FixedVersion: "3.44.0-4.el7",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: []types.DetectedVulnerability{
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2015-2808",
|
||||||
|
PkgName: "nss",
|
||||||
|
InstalledVersion: "3.36.0-7.1.el7_6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2016-2183",
|
||||||
|
PkgName: "nss",
|
||||||
|
InstalledVersion: "3.36.0-7.1.el7_6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
VulnerabilityID: "CVE-2018-12404",
|
||||||
|
PkgName: "nss",
|
||||||
|
InstalledVersion: "3.36.0-7.1.el7_6",
|
||||||
|
FixedVersion: "3.44.0-4.el7",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "sad path: Get returns an error",
|
||||||
|
args: args{
|
||||||
|
osVer: "5",
|
||||||
|
pkgs: []analyzer.Package{
|
||||||
|
{
|
||||||
|
Name: "nss",
|
||||||
|
Version: "3.36.0",
|
||||||
|
Release: "7.1.el7_6",
|
||||||
|
Epoch: 0,
|
||||||
|
Arch: "x86_64",
|
||||||
|
SrcName: "nss",
|
||||||
|
SrcVersion: "3.36.0",
|
||||||
|
SrcRelease: "7.4.160",
|
||||||
|
SrcEpoch: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
get: []dbTypes.GetExpectation{
|
||||||
|
{
|
||||||
|
Args: dbTypes.GetArgs{
|
||||||
|
Release: "5",
|
||||||
|
PkgName: "nss",
|
||||||
|
},
|
||||||
|
Returns: dbTypes.GetReturns{
|
||||||
|
Err: xerrors.New("error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
mockVs := new(dbTypes.MockVulnSrc)
|
||||||
|
mockVs.ApplyGetExpectations(tt.get)
|
||||||
|
s := &Scanner{
|
||||||
|
vs: mockVs,
|
||||||
|
}
|
||||||
|
got, err := s.Detect(tt.args.osVer, tt.args.pkgs)
|
||||||
|
require.Equal(t, tt.wantErr, err != nil)
|
||||||
|
assert.Equal(t, tt.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestScanner_IsSupportedVersion(t *testing.T) {
|
func TestScanner_IsSupportedVersion(t *testing.T) {
|
||||||
vectors := map[string]struct {
|
vectors := map[string]struct {
|
||||||
now time.Time
|
now time.Time
|
||||||
|
|||||||
@@ -3,12 +3,16 @@ package library
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
ptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
depptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
||||||
detector "github.com/aquasecurity/trivy/pkg/detector/library"
|
detector "github.com/aquasecurity/trivy/pkg/detector/library"
|
||||||
|
"github.com/aquasecurity/trivy/pkg/log"
|
||||||
r "github.com/aquasecurity/trivy/pkg/rpc"
|
r "github.com/aquasecurity/trivy/pkg/rpc"
|
||||||
"github.com/aquasecurity/trivy/pkg/rpc/client"
|
"github.com/aquasecurity/trivy/pkg/rpc/client"
|
||||||
"github.com/aquasecurity/trivy/pkg/types"
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
@@ -38,15 +42,23 @@ func NewDetector(customHeaders CustomHeaders, detector rpc.LibDetector) Detector
|
|||||||
return Detector{customHeaders: customHeaders, client: detector}
|
return Detector{customHeaders: customHeaders, client: detector}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Detector) Detect(filePath string, libs []ptypes.Library) ([]types.DetectedVulnerability, error) {
|
func (d Detector) Detect(imageName, filePath string, created time.Time, libs []depptypes.Library) ([]types.DetectedVulnerability, error) {
|
||||||
ctx := client.WithCustomHeaders(context.Background(), http.Header(d.customHeaders))
|
ctx := client.WithCustomHeaders(context.Background(), http.Header(d.customHeaders))
|
||||||
|
|
||||||
var res *rpc.DetectResponse
|
var res *rpc.DetectResponse
|
||||||
err := r.Retry(func() error {
|
err := r.Retry(func() error {
|
||||||
var err error
|
var err error
|
||||||
res, err = d.client.Detect(ctx, &rpc.LibDetectRequest{
|
res, err = d.client.Detect(ctx, &rpc.LibDetectRequest{
|
||||||
|
ImageName: imageName,
|
||||||
FilePath: filePath,
|
FilePath: filePath,
|
||||||
Libraries: r.ConvertToRpcLibraries(libs),
|
Libraries: r.ConvertToRpcLibraries(libs),
|
||||||
|
Created: func() *timestamp.Timestamp {
|
||||||
|
t, err := ptypes.TimestampProto(created)
|
||||||
|
if err != nil {
|
||||||
|
log.Logger.Warnf("invalid timestamp: %s", err)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}(),
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,14 +3,18 @@ package library
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
ptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
deptypes "github.com/aquasecurity/go-dep-parser/pkg/types"
|
||||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||||
"github.com/aquasecurity/trivy/pkg/types"
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
"github.com/aquasecurity/trivy/rpc/detector"
|
"github.com/aquasecurity/trivy/rpc/detector"
|
||||||
@@ -52,8 +56,10 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type args struct {
|
type args struct {
|
||||||
filePath string
|
imageName string
|
||||||
libs []ptypes.Library
|
filePath string
|
||||||
|
created time.Time
|
||||||
|
libs []deptypes.Library
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -71,14 +77,22 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
filePath: "app/Pipfile.lock",
|
imageName: "/tmp/alpine.tar",
|
||||||
libs: []ptypes.Library{
|
filePath: "app/Pipfile.lock",
|
||||||
|
created: time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
libs: []deptypes.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
detect: detect{
|
detect: detect{
|
||||||
input: detectInput{req: &detector.LibDetectRequest{
|
input: detectInput{req: &detector.LibDetectRequest{
|
||||||
FilePath: "app/Pipfile.lock",
|
ImageName: "/tmp/alpine.tar",
|
||||||
|
FilePath: "app/Pipfile.lock",
|
||||||
|
Created: func() *timestamp.Timestamp {
|
||||||
|
d := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
t, _ := ptypes.TimestampProto(d)
|
||||||
|
return t
|
||||||
|
}(),
|
||||||
Libraries: []*detector.Library{
|
Libraries: []*detector.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
@@ -118,17 +132,25 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
name: "Detect returns an error",
|
name: "Detect returns an error",
|
||||||
fields: fields{},
|
fields: fields{},
|
||||||
args: args{
|
args: args{
|
||||||
filePath: "app/Pipfile.lock",
|
imageName: "/tmp/alpine.tar",
|
||||||
libs: []ptypes.Library{
|
filePath: "app/Pipfile.lock",
|
||||||
|
created: time.Date(2019, 2, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
libs: []deptypes.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
detect: detect{
|
detect: detect{
|
||||||
input: detectInput{req: &detector.LibDetectRequest{
|
input: detectInput{req: &detector.LibDetectRequest{
|
||||||
FilePath: "app/Pipfile.lock",
|
ImageName: "/tmp/alpine.tar",
|
||||||
|
FilePath: "app/Pipfile.lock",
|
||||||
Libraries: []*detector.Library{
|
Libraries: []*detector.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
|
Created: func() *timestamp.Timestamp {
|
||||||
|
d := time.Date(2019, 2, 1, 0, 0, 0, 0, time.UTC)
|
||||||
|
t, _ := ptypes.TimestampProto(d)
|
||||||
|
return t
|
||||||
|
}(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
output: detectOutput{
|
output: detectOutput{
|
||||||
@@ -145,7 +167,7 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
tt.detect.output.res, tt.detect.output.err)
|
tt.detect.output.res, tt.detect.output.err)
|
||||||
|
|
||||||
d := NewDetector(tt.fields.customHeaders, mockDetector)
|
d := NewDetector(tt.fields.customHeaders, mockDetector)
|
||||||
got, err := d.Detect(tt.args.filePath, tt.args.libs)
|
got, err := d.Detect(tt.args.imageName, tt.args.filePath, tt.args.created, tt.args.libs)
|
||||||
if tt.wantErr != "" {
|
if tt.wantErr != "" {
|
||||||
require.NotNil(t, err, tt.name)
|
require.NotNil(t, err, tt.name)
|
||||||
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
|
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
|
||||||
|
|||||||
@@ -3,6 +3,12 @@ package ospkg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/aquasecurity/trivy/pkg/log"
|
||||||
|
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@@ -38,15 +44,23 @@ func NewDetector(customHeaders CustomHeaders, detector rpc.OSDetector) Detector
|
|||||||
return Detector{customHeaders: customHeaders, client: detector}
|
return Detector{customHeaders: customHeaders, client: detector}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d Detector) Detect(osFamily, osName string, pkgs []analyzer.Package) ([]types.DetectedVulnerability, bool, error) {
|
func (d Detector) Detect(imageName, osFamily, osName string, created time.Time, pkgs []analyzer.Package) ([]types.DetectedVulnerability, bool, error) {
|
||||||
ctx := client.WithCustomHeaders(context.Background(), http.Header(d.customHeaders))
|
ctx := client.WithCustomHeaders(context.Background(), http.Header(d.customHeaders))
|
||||||
|
|
||||||
var res *rpc.DetectResponse
|
var res *rpc.DetectResponse
|
||||||
err := r.Retry(func() error {
|
err := r.Retry(func() error {
|
||||||
var err error
|
var err error
|
||||||
res, err = d.client.Detect(ctx, &rpc.OSDetectRequest{
|
res, err = d.client.Detect(ctx, &rpc.OSDetectRequest{
|
||||||
OsFamily: osFamily,
|
ImageName: imageName,
|
||||||
OsName: osName,
|
OsFamily: osFamily,
|
||||||
|
OsName: osName,
|
||||||
|
Created: func() *timestamp.Timestamp {
|
||||||
|
t, err := ptypes.TimestampProto(created)
|
||||||
|
if err != nil {
|
||||||
|
log.Logger.Warnf("invalid timestamp: %s", err)
|
||||||
|
}
|
||||||
|
return t
|
||||||
|
}(),
|
||||||
Packages: r.ConvertToRpcPkgs(pkgs),
|
Packages: r.ConvertToRpcPkgs(pkgs),
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -3,18 +3,18 @@ package ospkg
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/aquasecurity/fanal/analyzer"
|
"github.com/aquasecurity/fanal/analyzer"
|
||||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||||
"github.com/aquasecurity/trivy/pkg/types"
|
"github.com/aquasecurity/trivy/pkg/types"
|
||||||
"github.com/aquasecurity/trivy/rpc/detector"
|
"github.com/aquasecurity/trivy/rpc/detector"
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
"github.com/golang/protobuf/ptypes/timestamp"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockDetector struct {
|
type mockDetector struct {
|
||||||
@@ -51,9 +51,11 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
customHeaders CustomHeaders
|
customHeaders CustomHeaders
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
osFamily string
|
imageName string
|
||||||
osName string
|
osFamily string
|
||||||
pkgs []analyzer.Package
|
osName string
|
||||||
|
created time.Time
|
||||||
|
pkgs []analyzer.Package
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -71,8 +73,10 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
osFamily: "alpine",
|
imageName: "alpine:3.10.2",
|
||||||
osName: "3.10.2",
|
osFamily: "alpine",
|
||||||
|
osName: "3.10.2",
|
||||||
|
created: time.Unix(1581498560, 0),
|
||||||
pkgs: []analyzer.Package{
|
pkgs: []analyzer.Package{
|
||||||
{
|
{
|
||||||
Name: "openssl",
|
Name: "openssl",
|
||||||
@@ -85,8 +89,13 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
detect: detect{
|
detect: detect{
|
||||||
input: detectInput{
|
input: detectInput{
|
||||||
req: &detector.OSDetectRequest{
|
req: &detector.OSDetectRequest{
|
||||||
OsFamily: "alpine",
|
OsFamily: "alpine",
|
||||||
OsName: "3.10.2",
|
OsName: "3.10.2",
|
||||||
|
ImageName: "alpine:3.10.2",
|
||||||
|
Created: func() *timestamp.Timestamp {
|
||||||
|
t, _ := ptypes.TimestampProto(time.Unix(1581498560, 0))
|
||||||
|
return t
|
||||||
|
}(),
|
||||||
Packages: []*detector.Package{
|
Packages: []*detector.Package{
|
||||||
{
|
{
|
||||||
Name: "openssl",
|
Name: "openssl",
|
||||||
@@ -131,8 +140,10 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
name: "Detect returns an error",
|
name: "Detect returns an error",
|
||||||
fields: fields{},
|
fields: fields{},
|
||||||
args: args{
|
args: args{
|
||||||
osFamily: "alpine",
|
imageName: "alpine:3.10.2",
|
||||||
osName: "3.10.2",
|
osFamily: "alpine",
|
||||||
|
osName: "3.10.2",
|
||||||
|
created: time.Unix(1581498560, 0),
|
||||||
pkgs: []analyzer.Package{
|
pkgs: []analyzer.Package{
|
||||||
{
|
{
|
||||||
Name: "openssl",
|
Name: "openssl",
|
||||||
@@ -145,8 +156,13 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
detect: detect{
|
detect: detect{
|
||||||
input: detectInput{
|
input: detectInput{
|
||||||
req: &detector.OSDetectRequest{
|
req: &detector.OSDetectRequest{
|
||||||
OsFamily: "alpine",
|
ImageName: "alpine:3.10.2",
|
||||||
OsName: "3.10.2",
|
OsFamily: "alpine",
|
||||||
|
OsName: "3.10.2",
|
||||||
|
Created: func() *timestamp.Timestamp {
|
||||||
|
t, _ := ptypes.TimestampProto(time.Unix(1581498560, 0))
|
||||||
|
return t
|
||||||
|
}(),
|
||||||
Packages: []*detector.Package{
|
Packages: []*detector.Package{
|
||||||
{
|
{
|
||||||
Name: "openssl",
|
Name: "openssl",
|
||||||
@@ -171,7 +187,7 @@ func TestDetectClient_Detect(t *testing.T) {
|
|||||||
tt.detect.output.res, tt.detect.output.err)
|
tt.detect.output.res, tt.detect.output.err)
|
||||||
|
|
||||||
d := NewDetector(tt.fields.customHeaders, mockDetector)
|
d := NewDetector(tt.fields.customHeaders, mockDetector)
|
||||||
got, _, err := d.Detect(tt.args.osFamily, tt.args.osName, tt.args.pkgs)
|
got, _, err := d.Detect(tt.args.imageName, tt.args.osFamily, tt.args.osName, tt.args.created, tt.args.pkgs)
|
||||||
if tt.wantErr != "" {
|
if tt.wantErr != "" {
|
||||||
require.NotNil(t, err, tt.name)
|
require.NotNil(t, err, tt.name)
|
||||||
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
|
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package library
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@@ -28,8 +29,8 @@ func NewServer(detector detector.Operation, vulnClient vulnerability.Operation)
|
|||||||
return &Server{detector: detector, vulnClient: vulnClient}
|
return &Server{detector: detector, vulnClient: vulnClient}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Detect(ctx context.Context, req *proto.LibDetectRequest) (res *proto.DetectResponse, err error) {
|
func (s *Server) Detect(_ context.Context, req *proto.LibDetectRequest) (res *proto.DetectResponse, err error) {
|
||||||
vulns, err := s.detector.Detect(req.FilePath, rpc.ConvertFromRpcLibraries(req.Libraries))
|
vulns, err := s.detector.Detect("", req.FilePath, time.Time{}, rpc.ConvertFromRpcLibraries(req.Libraries))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = xerrors.Errorf("failed to detect library vulnerabilities: %w", err)
|
err = xerrors.Errorf("failed to detect library vulnerabilities: %w", err)
|
||||||
log.Logger.Error(err)
|
log.Logger.Error(err)
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ func TestServer_Detect(t *testing.T) {
|
|||||||
name: "happy path",
|
name: "happy path",
|
||||||
args: args{
|
args: args{
|
||||||
req: &proto.LibDetectRequest{
|
req: &proto.LibDetectRequest{
|
||||||
FilePath: "app/Pipfile.lock",
|
ImageName: "alpine:3.10",
|
||||||
|
FilePath: "app/Pipfile.lock",
|
||||||
Libraries: []*proto.Library{
|
Libraries: []*proto.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
@@ -91,7 +92,8 @@ func TestServer_Detect(t *testing.T) {
|
|||||||
name: "Detect returns an error",
|
name: "Detect returns an error",
|
||||||
args: args{
|
args: args{
|
||||||
req: &proto.LibDetectRequest{
|
req: &proto.LibDetectRequest{
|
||||||
FilePath: "app/Pipfile.lock",
|
ImageName: "alpine:3.10",
|
||||||
|
FilePath: "app/Pipfile.lock",
|
||||||
Libraries: []*proto.Library{
|
Libraries: []*proto.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ospkg
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@@ -29,7 +30,7 @@ func NewServer(detector detector.Operation, vulnClient vulnerability.Operation)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Detect(ctx context.Context, req *proto.OSDetectRequest) (res *proto.DetectResponse, err error) {
|
func (s *Server) Detect(ctx context.Context, req *proto.OSDetectRequest) (res *proto.DetectResponse, err error) {
|
||||||
vulns, eosl, err := s.detector.Detect(req.OsFamily, req.OsName, rpc.ConvertFromRpcPkgs(req.Packages))
|
vulns, eosl, err := s.detector.Detect("", req.OsFamily, req.OsName, time.Time{}, rpc.ConvertFromRpcPkgs(req.Packages))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = xerrors.Errorf("failed to detect vulnerabilities of OS packages: %w", err)
|
err = xerrors.Errorf("failed to detect vulnerabilities of OS packages: %w", err)
|
||||||
log.Logger.Error(err)
|
log.Logger.Error(err)
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
package library
|
package library
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"time"
|
||||||
"os"
|
|
||||||
|
|
||||||
detector "github.com/aquasecurity/trivy/pkg/detector/library"
|
detector "github.com/aquasecurity/trivy/pkg/detector/library"
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ func NewScanner(detector detector.Operation) Scanner {
|
|||||||
return Scanner{detector: detector}
|
return Scanner{detector: detector}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Scanner) Scan(files extractor.FileMap) (map[string][]types.DetectedVulnerability, error) {
|
func (s Scanner) Scan(imageName string, created time.Time, files extractor.FileMap) (map[string][]types.DetectedVulnerability, error) {
|
||||||
results, err := analyzer.GetLibraries(files)
|
results, err := analyzer.GetLibraries(files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to analyze libraries: %w", err)
|
return nil, xerrors.Errorf("failed to analyze libraries: %w", err)
|
||||||
@@ -35,7 +34,7 @@ func (s Scanner) Scan(files extractor.FileMap) (map[string][]types.DetectedVulne
|
|||||||
|
|
||||||
vulnerabilities := map[string][]types.DetectedVulnerability{}
|
vulnerabilities := map[string][]types.DetectedVulnerability{}
|
||||||
for path, libs := range results {
|
for path, libs := range results {
|
||||||
vulns, err := s.detector.Detect(string(path), libs)
|
vulns, err := s.detector.Detect(imageName, string(path), created, libs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed library scan: %w", err)
|
return nil, xerrors.Errorf("failed library scan: %w", err)
|
||||||
}
|
}
|
||||||
@@ -44,24 +43,3 @@ func (s Scanner) Scan(files extractor.FileMap) (map[string][]types.DetectedVulne
|
|||||||
}
|
}
|
||||||
return vulnerabilities, nil
|
return vulnerabilities, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Scanner) ScanFile(f *os.File) ([]types.DetectedVulnerability, error) {
|
|
||||||
content, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
files := extractor.FileMap{
|
|
||||||
f.Name(): content,
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := s.Scan(files)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// need only 1 result
|
|
||||||
for _, vulns := range results {
|
|
||||||
return vulns, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package library
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
library2 "github.com/aquasecurity/trivy/pkg/detector/library"
|
library2 "github.com/aquasecurity/trivy/pkg/detector/library"
|
||||||
|
|
||||||
@@ -17,8 +18,10 @@ import (
|
|||||||
|
|
||||||
func TestScanner_Scan(t *testing.T) {
|
func TestScanner_Scan(t *testing.T) {
|
||||||
type detectInput struct {
|
type detectInput struct {
|
||||||
filePath string
|
imageName string
|
||||||
libs []ptypes.Library
|
filePath string
|
||||||
|
created time.Time
|
||||||
|
libs []ptypes.Library
|
||||||
}
|
}
|
||||||
type detectOutput struct {
|
type detectOutput struct {
|
||||||
vulns []types.DetectedVulnerability
|
vulns []types.DetectedVulnerability
|
||||||
@@ -29,7 +32,9 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
output detectOutput
|
output detectOutput
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
files extractor.FileMap
|
imageName string
|
||||||
|
created time.Time
|
||||||
|
files extractor.FileMap
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@@ -41,6 +46,8 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "happy",
|
name: "happy",
|
||||||
args: args{
|
args: args{
|
||||||
|
imageName: "alpine:3.10",
|
||||||
|
created: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
files: extractor.FileMap{
|
files: extractor.FileMap{
|
||||||
"app/Pipfile.lock": []byte(`{
|
"app/Pipfile.lock": []byte(`{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
@@ -94,7 +101,9 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
detect: []detect{
|
detect: []detect{
|
||||||
{
|
{
|
||||||
input: detectInput{
|
input: detectInput{
|
||||||
filePath: "app/Pipfile.lock",
|
imageName: "alpine:3.10",
|
||||||
|
filePath: "app/Pipfile.lock",
|
||||||
|
created: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
libs: []ptypes.Library{
|
libs: []ptypes.Library{
|
||||||
{Name: "django", Version: "3.0.0"},
|
{Name: "django", Version: "3.0.0"},
|
||||||
},
|
},
|
||||||
@@ -107,7 +116,9 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
input: detectInput{
|
input: detectInput{
|
||||||
filePath: "app/package-lock.json",
|
imageName: "alpine:3.10",
|
||||||
|
filePath: "app/package-lock.json",
|
||||||
|
created: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
libs: []ptypes.Library{
|
libs: []ptypes.Library{
|
||||||
{Name: "react", Version: "16.8.6"},
|
{Name: "react", Version: "16.8.6"},
|
||||||
},
|
},
|
||||||
@@ -131,6 +142,8 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "broken lock file",
|
name: "broken lock file",
|
||||||
args: args{
|
args: args{
|
||||||
|
imageName: "alpine:3.10",
|
||||||
|
created: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
files: extractor.FileMap{
|
files: extractor.FileMap{
|
||||||
"app/Pipfile.lock": []byte(`{broken}`),
|
"app/Pipfile.lock": []byte(`{broken}`),
|
||||||
},
|
},
|
||||||
@@ -179,14 +192,14 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
mockDetector := new(library2.MockDetector)
|
mockDetector := new(library2.MockDetector)
|
||||||
for _, d := range tt.detect {
|
for _, d := range tt.detect {
|
||||||
mockDetector.On("Detect", d.input.filePath, d.input.libs).Return(
|
mockDetector.On("Detect", d.input.imageName, d.input.filePath, d.input.created, d.input.libs).Return(
|
||||||
d.output.vulns, d.output.err)
|
d.output.vulns, d.output.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := Scanner{
|
s := Scanner{
|
||||||
detector: mockDetector,
|
detector: mockDetector,
|
||||||
}
|
}
|
||||||
got, err := s.Scan(tt.args.files)
|
got, err := s.Scan(tt.args.imageName, tt.args.created, tt.args.files)
|
||||||
if tt.wantErr != "" {
|
if tt.wantErr != "" {
|
||||||
require.NotNil(t, err, tt.name)
|
require.NotNil(t, err, tt.name)
|
||||||
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
|
assert.Contains(t, err.Error(), tt.wantErr, tt.name)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package ospkg
|
package ospkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/aquasecurity/fanal/analyzer"
|
"github.com/aquasecurity/fanal/analyzer"
|
||||||
@@ -28,7 +30,7 @@ func NewScanner(detector detector.Operation) Scanner {
|
|||||||
return Scanner{detector: detector}
|
return Scanner{detector: detector}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Scanner) Scan(files extractor.FileMap) (string, string, []types.DetectedVulnerability, error) {
|
func (s Scanner) Scan(imageName string, created time.Time, files extractor.FileMap) (string, string, []types.DetectedVulnerability, error) {
|
||||||
os, err := analyzer.GetOS(files)
|
os, err := analyzer.GetOS(files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil, xerrors.Errorf("failed to analyze OS: %w", err)
|
return "", "", nil, xerrors.Errorf("failed to analyze OS: %w", err)
|
||||||
@@ -53,11 +55,12 @@ func (s Scanner) Scan(files extractor.FileMap) (string, string, []types.Detected
|
|||||||
pkgs = mergePkgs(pkgs, pkgsFromCommands)
|
pkgs = mergePkgs(pkgs, pkgsFromCommands)
|
||||||
log.Logger.Debugf("the number of packages: %d", len(pkgs))
|
log.Logger.Debugf("the number of packages: %d", len(pkgs))
|
||||||
|
|
||||||
vulns, eosl, err := s.detector.Detect(os.Family, os.Name, pkgs)
|
vulns, eosl, err := s.detector.Detect(imageName, os.Family, os.Name, created, pkgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil, xerrors.Errorf("failed to detect vulnerabilities: %w", err)
|
return "", "", nil, xerrors.Errorf("failed to detect vulnerabilities: %w", err)
|
||||||
}
|
}
|
||||||
if eosl {
|
if eosl {
|
||||||
|
// TODO: test logger
|
||||||
log.Logger.Warnf("This OS version is no longer supported by the distribution: %s %s", os.Family, os.Name)
|
log.Logger.Warnf("This OS version is no longer supported by the distribution: %s %s", os.Family, os.Name)
|
||||||
log.Logger.Warnf("The vulnerability detection may be insufficient because security updates are not provided")
|
log.Logger.Warnf("The vulnerability detection may be insufficient because security updates are not provided")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ package ospkg
|
|||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
ospkg2 "github.com/aquasecurity/trivy/pkg/detector/ospkg"
|
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
ospkg2 "github.com/aquasecurity/trivy/pkg/detector/ospkg"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@@ -26,9 +27,11 @@ func TestMain(m *testing.M) {
|
|||||||
|
|
||||||
func TestScanner_Scan(t *testing.T) {
|
func TestScanner_Scan(t *testing.T) {
|
||||||
type detectInput struct {
|
type detectInput struct {
|
||||||
osFamily string
|
imageName string
|
||||||
osName string
|
osFamily string
|
||||||
pkgs []analyzer.Package
|
osName string
|
||||||
|
buildTime time.Time
|
||||||
|
pkgs []analyzer.Package
|
||||||
}
|
}
|
||||||
type detectOutput struct {
|
type detectOutput struct {
|
||||||
vulns []types.DetectedVulnerability
|
vulns []types.DetectedVulnerability
|
||||||
@@ -41,7 +44,9 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type fields struct {
|
type fields struct {
|
||||||
files extractor.FileMap
|
imageName string
|
||||||
|
created time.Time
|
||||||
|
files extractor.FileMap
|
||||||
}
|
}
|
||||||
type want struct {
|
type want struct {
|
||||||
osFamily string
|
osFamily string
|
||||||
@@ -58,7 +63,10 @@ func TestScanner_Scan(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "happy path",
|
name: "happy path",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
|
imageName: "alpine:3.10.2",
|
||||||
|
created: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
files: extractor.FileMap{
|
files: extractor.FileMap{
|
||||||
|
"/config": []byte(`{"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"ArgsEscaped":true,"Image":"sha256:09f2bbe58e774849d74dc1391c2e01731896c745c4aba1ecf69a283bdb4b537a","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"c10d36fa368a7ea673683682666758adf35efe98e10989505f4f566b5b18538f","container_config":{"Hostname":"c10d36fa368a","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"ArgsEscaped":true,"Image":"sha256:09f2bbe58e774849d74dc1391c2e01731896c745c4aba1ecf69a283bdb4b537a","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2019-05-11T00:07:03.510395965Z","docker_version":"18.06.1-ce","history":[{"created":"2019-05-11T00:07:03.358250803Z","created_by":"/bin/sh -c #(nop) ADD file:a86aea1f3a7d68f6ae03397b99ea77f2e9ee901c5c59e59f76f93adbb4035913 in / "},{"created":"2019-05-11T00:07:03.510395965Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:f1b5933fe4b5f49bbe8258745cf396afe07e625bdab3168e364daf7c956b6b81"]}}`),
|
||||||
"etc/alpine-release": []byte("3.10.2"),
|
"etc/alpine-release": []byte("3.10.2"),
|
||||||
"lib/apk/db/installed": []byte(`C:Q11Ing8/u1VIdY9czSxaDO9wJg72I=
|
"lib/apk/db/installed": []byte(`C:Q11Ing8/u1VIdY9czSxaDO9wJg72I=
|
||||||
P:musl
|
P:musl
|
||||||
@@ -88,8 +96,10 @@ F:usr/lib
|
|||||||
},
|
},
|
||||||
detect: detect{
|
detect: detect{
|
||||||
input: detectInput{
|
input: detectInput{
|
||||||
osFamily: "alpine",
|
imageName: "alpine:3.10.2",
|
||||||
osName: "3.10.2",
|
osFamily: "alpine",
|
||||||
|
osName: "3.10.2",
|
||||||
|
buildTime: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
pkgs: []analyzer.Package{
|
pkgs: []analyzer.Package{
|
||||||
{Name: "musl", Version: "1.1.22-r3"},
|
{Name: "musl", Version: "1.1.22-r3"},
|
||||||
},
|
},
|
||||||
@@ -122,7 +132,10 @@ F:usr/lib
|
|||||||
{
|
{
|
||||||
name: "Detect returns an error",
|
name: "Detect returns an error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
|
imageName: "alpine:3.10",
|
||||||
|
created: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
files: extractor.FileMap{
|
files: extractor.FileMap{
|
||||||
|
"/config": []byte(`{"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh"],"ArgsEscaped":true,"Image":"sha256:09f2bbe58e774849d74dc1391c2e01731896c745c4aba1ecf69a283bdb4b537a","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"c10d36fa368a7ea673683682666758adf35efe98e10989505f4f566b5b18538f","container_config":{"Hostname":"c10d36fa368a","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/bin/sh\"]"],"ArgsEscaped":true,"Image":"sha256:09f2bbe58e774849d74dc1391c2e01731896c745c4aba1ecf69a283bdb4b537a","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2019-05-11T00:07:03.510395965Z","docker_version":"18.06.1-ce","history":[{"created":"2019-05-11T00:07:03.358250803Z","created_by":"/bin/sh -c #(nop) ADD file:a86aea1f3a7d68f6ae03397b99ea77f2e9ee901c5c59e59f76f93adbb4035913 in / "},{"created":"2019-05-11T00:07:03.510395965Z","created_by":"/bin/sh -c #(nop) CMD [\"/bin/sh\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:f1b5933fe4b5f49bbe8258745cf396afe07e625bdab3168e364daf7c956b6b81"]}}`),
|
||||||
"etc/alpine-release": []byte("3.10.2"),
|
"etc/alpine-release": []byte("3.10.2"),
|
||||||
"lib/apk/db/installed": []byte(`C:Q11Ing8/u1VIdY9czSxaDO9wJg72I=
|
"lib/apk/db/installed": []byte(`C:Q11Ing8/u1VIdY9czSxaDO9wJg72I=
|
||||||
P:musl
|
P:musl
|
||||||
@@ -133,8 +146,10 @@ A:x86_64
|
|||||||
},
|
},
|
||||||
detect: detect{
|
detect: detect{
|
||||||
input: detectInput{
|
input: detectInput{
|
||||||
osFamily: "alpine",
|
imageName: "alpine:3.10",
|
||||||
osName: "3.10.2",
|
osFamily: "alpine",
|
||||||
|
osName: "3.10.2",
|
||||||
|
buildTime: time.Date(2019, 5, 11, 0, 7, 3, 510395965, time.UTC),
|
||||||
pkgs: []analyzer.Package{
|
pkgs: []analyzer.Package{
|
||||||
{Name: "musl", Version: "1.1.22-r3"},
|
{Name: "musl", Version: "1.1.22-r3"},
|
||||||
},
|
},
|
||||||
@@ -151,11 +166,11 @@ A:x86_64
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
mockDetector := new(ospkg2.MockDetector)
|
mockDetector := new(ospkg2.MockDetector)
|
||||||
mockDetector.On("Detect", tt.detect.input.osFamily, tt.detect.input.osName,
|
mockDetector.On("Detect", tt.detect.input.imageName, tt.detect.input.osFamily, tt.detect.input.osName,
|
||||||
tt.detect.input.pkgs).Return(tt.detect.output.vulns, tt.detect.output.eosl, tt.detect.output.err)
|
tt.detect.input.buildTime, tt.detect.input.pkgs).Return(tt.detect.output.vulns, tt.detect.output.eosl, tt.detect.output.err)
|
||||||
|
|
||||||
s := NewScanner(mockDetector)
|
s := NewScanner(mockDetector)
|
||||||
got, got1, got2, err := s.Scan(tt.fields.files)
|
got, got1, got2, err := s.Scan(tt.fields.imageName, tt.fields.created, tt.fields.files)
|
||||||
|
|
||||||
if tt.want.err != "" {
|
if tt.want.err != "" {
|
||||||
require.NotNil(t, err, tt.name)
|
require.NotNil(t, err, tt.name)
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ package scanner
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/google/wire"
|
"github.com/google/wire"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
@@ -96,8 +98,13 @@ func (s Scanner) ScanImage(imageName, filePath string, scanOptions types.ScanOpt
|
|||||||
return nil, xerrors.New("image name or image file must be specified")
|
return nil, xerrors.New("image name or image file must be specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
created, err := getCreated(files["/config"])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if utils.StringInSlice("os", scanOptions.VulnType) {
|
if utils.StringInSlice("os", scanOptions.VulnType) {
|
||||||
osFamily, osVersion, osVulns, err := s.ospkgScanner.Scan(files)
|
osFamily, osVersion, osVulns, err := s.ospkgScanner.Scan(target, created, files)
|
||||||
if err != nil && err != ospkgDetector.ErrUnsupportedOS {
|
if err != nil && err != ospkgDetector.ErrUnsupportedOS {
|
||||||
return nil, xerrors.Errorf("failed to scan the image: %w", err)
|
return nil, xerrors.Errorf("failed to scan the image: %w", err)
|
||||||
}
|
}
|
||||||
@@ -111,7 +118,7 @@ func (s Scanner) ScanImage(imageName, filePath string, scanOptions types.ScanOpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
if utils.StringInSlice("library", scanOptions.VulnType) {
|
if utils.StringInSlice("library", scanOptions.VulnType) {
|
||||||
libVulns, err := s.libScanner.Scan(files)
|
libVulns, err := s.libScanner.Scan(target, created, files)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("failed to scan libraries: %w", err)
|
return nil, xerrors.Errorf("failed to scan libraries: %w", err)
|
||||||
}
|
}
|
||||||
@@ -132,15 +139,16 @@ func (s Scanner) ScanImage(imageName, filePath string, scanOptions types.ScanOpt
|
|||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s Scanner) ScanFile(f *os.File) (report.Results, error) {
|
type config struct {
|
||||||
vulns, err := s.libScanner.ScanFile(f)
|
Created time.Time
|
||||||
if err != nil {
|
}
|
||||||
return nil, xerrors.Errorf("failed to scan libraries in file: %w", err)
|
|
||||||
|
func getCreated(configBlob []byte) (time.Time, error) {
|
||||||
|
var config config
|
||||||
|
if err := json.Unmarshal(configBlob, &config); err != nil {
|
||||||
|
return time.Time{}, xerrors.Errorf("invalid config JSON: %w", err)
|
||||||
}
|
}
|
||||||
results := report.Results{
|
return config.Created, nil
|
||||||
{Target: f.Name(), Vulnerabilities: vulns},
|
|
||||||
}
|
|
||||||
return results, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func openStream(path string) (*os.File, error) {
|
func openStream(path string) (*os.File, error) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package detector
|
|||||||
import (
|
import (
|
||||||
fmt "fmt"
|
fmt "fmt"
|
||||||
proto "github.com/golang/protobuf/proto"
|
proto "github.com/golang/protobuf/proto"
|
||||||
|
timestamp "github.com/golang/protobuf/ptypes/timestamp"
|
||||||
math "math"
|
math "math"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -55,12 +56,14 @@ func (Severity) EnumDescriptor() ([]byte, []int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OSDetectRequest struct {
|
type OSDetectRequest struct {
|
||||||
OsFamily string `protobuf:"bytes,1,opt,name=os_family,json=osFamily,proto3" json:"os_family,omitempty"`
|
OsFamily string `protobuf:"bytes,1,opt,name=os_family,json=osFamily,proto3" json:"os_family,omitempty"`
|
||||||
OsName string `protobuf:"bytes,2,opt,name=os_name,json=osName,proto3" json:"os_name,omitempty"`
|
OsName string `protobuf:"bytes,2,opt,name=os_name,json=osName,proto3" json:"os_name,omitempty"`
|
||||||
Packages []*Package `protobuf:"bytes,3,rep,name=packages,proto3" json:"packages,omitempty"`
|
Packages []*Package `protobuf:"bytes,3,rep,name=packages,proto3" json:"packages,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
ImageName string `protobuf:"bytes,4,opt,name=image_name,json=imageName,proto3" json:"image_name,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
Created *timestamp.Timestamp `protobuf:"bytes,5,opt,name=created,proto3" json:"created,omitempty"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *OSDetectRequest) Reset() { *m = OSDetectRequest{} }
|
func (m *OSDetectRequest) Reset() { *m = OSDetectRequest{} }
|
||||||
@@ -109,6 +112,20 @@ func (m *OSDetectRequest) GetPackages() []*Package {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *OSDetectRequest) GetImageName() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.ImageName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *OSDetectRequest) GetCreated() *timestamp.Timestamp {
|
||||||
|
if m != nil {
|
||||||
|
return m.Created
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type DetectResponse struct {
|
type DetectResponse struct {
|
||||||
Vulnerabilities []*Vulnerability `protobuf:"bytes,1,rep,name=vulnerabilities,proto3" json:"vulnerabilities,omitempty"`
|
Vulnerabilities []*Vulnerability `protobuf:"bytes,1,rep,name=vulnerabilities,proto3" json:"vulnerabilities,omitempty"`
|
||||||
Eosl bool `protobuf:"varint,2,opt,name=eosl,proto3" json:"eosl,omitempty"`
|
Eosl bool `protobuf:"varint,2,opt,name=eosl,proto3" json:"eosl,omitempty"`
|
||||||
@@ -264,11 +281,13 @@ func (m *Package) GetSrcEpoch() int32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LibDetectRequest struct {
|
type LibDetectRequest struct {
|
||||||
FilePath string `protobuf:"bytes,1,opt,name=file_path,json=filePath,proto3" json:"file_path,omitempty"`
|
FilePath string `protobuf:"bytes,1,opt,name=file_path,json=filePath,proto3" json:"file_path,omitempty"`
|
||||||
Libraries []*Library `protobuf:"bytes,2,rep,name=libraries,proto3" json:"libraries,omitempty"`
|
Libraries []*Library `protobuf:"bytes,2,rep,name=libraries,proto3" json:"libraries,omitempty"`
|
||||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
ImageName string `protobuf:"bytes,3,opt,name=image_name,json=imageName,proto3" json:"image_name,omitempty"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
Created *timestamp.Timestamp `protobuf:"bytes,4,opt,name=created,proto3" json:"created,omitempty"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
|
XXX_unrecognized []byte `json:"-"`
|
||||||
|
XXX_sizecache int32 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *LibDetectRequest) Reset() { *m = LibDetectRequest{} }
|
func (m *LibDetectRequest) Reset() { *m = LibDetectRequest{} }
|
||||||
@@ -310,6 +329,20 @@ func (m *LibDetectRequest) GetLibraries() []*Library {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *LibDetectRequest) GetImageName() string {
|
||||||
|
if m != nil {
|
||||||
|
return m.ImageName
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *LibDetectRequest) GetCreated() *timestamp.Timestamp {
|
||||||
|
if m != nil {
|
||||||
|
return m.Created
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Library struct {
|
type Library struct {
|
||||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||||
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
|
Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"`
|
||||||
@@ -465,44 +498,49 @@ func init() {
|
|||||||
func init() { proto.RegisterFile("rpc/detector/service.proto", fileDescriptor_93e16dbd737b8924) }
|
func init() { proto.RegisterFile("rpc/detector/service.proto", fileDescriptor_93e16dbd737b8924) }
|
||||||
|
|
||||||
var fileDescriptor_93e16dbd737b8924 = []byte{
|
var fileDescriptor_93e16dbd737b8924 = []byte{
|
||||||
// 618 bytes of a gzipped FileDescriptorProto
|
// 693 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x4f, 0xdb, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x6f, 0xd3, 0x40,
|
||||||
0x10, 0x6d, 0x3e, 0xed, 0x4c, 0xf8, 0x70, 0x57, 0x48, 0xb8, 0xa0, 0x42, 0x94, 0x5e, 0x68, 0x2b,
|
0x10, 0xc5, 0xf9, 0xb2, 0x33, 0xe9, 0x87, 0x59, 0x55, 0xaa, 0x49, 0xd5, 0x36, 0x0a, 0x97, 0x02,
|
||||||
0x05, 0x29, 0xb4, 0xea, 0xb9, 0x05, 0x0a, 0x69, 0x43, 0x40, 0xa6, 0x80, 0xda, 0x4b, 0xb4, 0x71,
|
0x52, 0x22, 0xa5, 0x45, 0x9c, 0xa1, 0x2d, 0x6d, 0x20, 0x4d, 0x2b, 0xf7, 0x4b, 0x70, 0x89, 0x36,
|
||||||
0x26, 0x64, 0x85, 0x93, 0x75, 0x77, 0x97, 0xa8, 0x96, 0xfa, 0xb7, 0xfa, 0xd3, 0x7a, 0xaf, 0x76,
|
0xce, 0x24, 0x59, 0xd5, 0xc9, 0x9a, 0xdd, 0x6d, 0x44, 0x7e, 0x18, 0x27, 0x7e, 0x05, 0x3f, 0x86,
|
||||||
0xd7, 0x36, 0x49, 0xca, 0x85, 0xdb, 0xcc, 0xbc, 0xe7, 0x99, 0xd9, 0xf7, 0xd6, 0x0b, 0x5b, 0x22,
|
0x3b, 0xf2, 0xae, 0x9d, 0x26, 0xa1, 0x42, 0xf4, 0xb6, 0x33, 0xef, 0xed, 0xec, 0xbc, 0x99, 0x67,
|
||||||
0x0e, 0xf7, 0x87, 0xa8, 0x30, 0x54, 0x5c, 0xec, 0x4b, 0x14, 0x33, 0x16, 0x62, 0x2b, 0x16, 0x5c,
|
0x43, 0x59, 0x44, 0x41, 0xbd, 0x87, 0x0a, 0x03, 0xc5, 0x45, 0x5d, 0xa2, 0x98, 0xb0, 0x00, 0x6b,
|
||||||
0x71, 0xb2, 0xa6, 0x04, 0x9b, 0x25, 0xad, 0x0c, 0x6d, 0xfe, 0x86, 0xf5, 0xf3, 0xcb, 0x23, 0x93,
|
0x91, 0xe0, 0x8a, 0x93, 0x35, 0x25, 0xd8, 0x64, 0x5a, 0x4b, 0xd1, 0xf2, 0xee, 0x80, 0xf3, 0x41,
|
||||||
0x05, 0xf8, 0xf3, 0x1e, 0xa5, 0x22, 0xdb, 0x50, 0xe3, 0xb2, 0x3f, 0xa2, 0x13, 0x16, 0x25, 0x7e,
|
0x88, 0x75, 0x8d, 0x76, 0xef, 0xfb, 0x75, 0xc5, 0x46, 0x28, 0x15, 0x1d, 0x45, 0xe6, 0x42, 0xf5,
|
||||||
0xa1, 0x51, 0xd8, 0xab, 0x05, 0x2e, 0x97, 0x9f, 0x4d, 0x4e, 0x36, 0xc1, 0xe1, 0xb2, 0x3f, 0xa5,
|
0x97, 0x05, 0xeb, 0xe7, 0x97, 0x47, 0x9a, 0xef, 0xe3, 0xb7, 0x7b, 0x94, 0x8a, 0x6c, 0x41, 0x91,
|
||||||
0x13, 0xf4, 0x8b, 0x06, 0xaa, 0x72, 0xd9, 0xa3, 0x13, 0x24, 0x07, 0xe0, 0xc6, 0x34, 0xbc, 0xa3,
|
0xcb, 0x4e, 0x9f, 0x8e, 0x58, 0x38, 0xf5, 0xac, 0x8a, 0xb5, 0x57, 0xf4, 0x1d, 0x2e, 0x3f, 0xea,
|
||||||
0xb7, 0x28, 0xfd, 0x52, 0xa3, 0xb4, 0x57, 0x6f, 0x6f, 0xb6, 0x16, 0x67, 0xb5, 0x2e, 0x2c, 0x1e,
|
0x98, 0x6c, 0x82, 0xcd, 0x65, 0x67, 0x4c, 0x47, 0xe8, 0x65, 0x34, 0x54, 0xe0, 0xb2, 0x4d, 0x47,
|
||||||
0xe4, 0xc4, 0xe6, 0x04, 0xd6, 0xb2, 0xd9, 0x32, 0xe6, 0x53, 0x89, 0xe4, 0x04, 0xd6, 0x67, 0xf7,
|
0x48, 0xf6, 0xc1, 0x89, 0x68, 0x70, 0x47, 0x07, 0x28, 0xbd, 0x6c, 0x25, 0xbb, 0x57, 0x6a, 0x6c,
|
||||||
0xd1, 0x14, 0x05, 0x1d, 0xb0, 0x88, 0x29, 0x86, 0xd2, 0x2f, 0x98, 0x6e, 0x2f, 0x97, 0xbb, 0x5d,
|
0xd6, 0x16, 0xbb, 0xa9, 0x5d, 0x18, 0xdc, 0x9f, 0x11, 0xc9, 0x36, 0x00, 0x1b, 0xd1, 0x01, 0x9a,
|
||||||
0xcf, 0xd1, 0x92, 0x60, 0xf9, 0x2b, 0x42, 0xa0, 0x8c, 0x5c, 0x46, 0x66, 0x4b, 0x37, 0x30, 0x71,
|
0x82, 0x39, 0x5d, 0xb0, 0xa8, 0x33, 0xba, 0xe6, 0x01, 0xd8, 0x81, 0x40, 0xaa, 0xb0, 0xe7, 0xe5,
|
||||||
0xf3, 0x6f, 0x01, 0x9c, 0x74, 0x09, 0x8d, 0x9b, 0x53, 0xd8, 0x03, 0x9a, 0x98, 0xf8, 0xe0, 0xcc,
|
0x2b, 0xd6, 0x5e, 0xa9, 0x51, 0xae, 0x19, 0x41, 0xb5, 0x54, 0x50, 0xed, 0x2a, 0x15, 0xe4, 0xa7,
|
||||||
0x50, 0x48, 0xc6, 0xa7, 0xe9, 0xe1, 0xb2, 0x54, 0x23, 0x02, 0x23, 0xa4, 0x12, 0xfd, 0x92, 0x45,
|
0xd4, 0xea, 0x08, 0xd6, 0x52, 0x41, 0x32, 0xe2, 0x63, 0x89, 0xe4, 0x04, 0xd6, 0x27, 0xf7, 0xe1,
|
||||||
0xd2, 0x94, 0x6c, 0x40, 0x05, 0x63, 0x1e, 0x8e, 0xfd, 0x72, 0xa3, 0xb0, 0x57, 0x09, 0x6c, 0xa2,
|
0x18, 0x05, 0xed, 0xb2, 0x90, 0x29, 0x86, 0xd2, 0xb3, 0x74, 0x8b, 0xdb, 0xcb, 0x2d, 0xde, 0xcc,
|
||||||
0xbb, 0x53, 0x11, 0x8e, 0xfd, 0x8a, 0xed, 0xae, 0x63, 0xf2, 0x02, 0x5c, 0x29, 0x42, 0xab, 0x5d,
|
0xd1, 0xa6, 0xfe, 0xf2, 0x2d, 0x42, 0x20, 0x87, 0x5c, 0x86, 0x5a, 0xba, 0xe3, 0xeb, 0x73, 0xf5,
|
||||||
0xd5, 0x36, 0x91, 0x22, 0x34, 0xe2, 0xed, 0x42, 0x5d, 0x43, 0xd9, 0x70, 0xc7, 0xa0, 0x20, 0x45,
|
0xb7, 0x05, 0x76, 0xa2, 0x2c, 0xc6, 0xb5, 0x12, 0x33, 0x35, 0x7d, 0x26, 0x1e, 0xd8, 0x13, 0x14,
|
||||||
0x78, 0x9d, 0xce, 0x4f, 0x09, 0xd9, 0x0e, 0x6e, 0x4e, 0x08, 0xd2, 0x35, 0xb6, 0xa1, 0xa6, 0x09,
|
0x92, 0xf1, 0x71, 0x32, 0xb1, 0x34, 0x8c, 0x11, 0x81, 0x21, 0x52, 0x89, 0x5e, 0xd6, 0x20, 0x49,
|
||||||
0x76, 0x95, 0x9a, 0x59, 0x45, 0x4f, 0x3b, 0xd6, 0x79, 0x73, 0x04, 0x5e, 0x97, 0x0d, 0xfe, 0x73,
|
0x48, 0x36, 0x20, 0x8f, 0x11, 0x0f, 0x86, 0x7a, 0x24, 0x79, 0xdf, 0x04, 0x71, 0x75, 0x2a, 0x82,
|
||||||
0x79, 0xc4, 0x22, 0xec, 0xc7, 0x54, 0x8d, 0x33, 0x97, 0x75, 0xe1, 0x82, 0xaa, 0x31, 0x79, 0x0f,
|
0xa1, 0x9e, 0x45, 0xd1, 0xd7, 0x67, 0xf2, 0x02, 0x1c, 0x29, 0x02, 0x33, 0xbf, 0x82, 0x29, 0x22,
|
||||||
0xb5, 0x88, 0x0d, 0x04, 0x15, 0x5a, 0xff, 0xe2, 0xe3, 0x6e, 0x76, 0x0d, 0x21, 0x09, 0x1e, 0x98,
|
0x45, 0xa0, 0xa7, 0xb7, 0x0b, 0xa5, 0x18, 0x4a, 0x1f, 0xb7, 0x35, 0x0a, 0x52, 0x04, 0x37, 0xc9,
|
||||||
0xcd, 0x0f, 0xe0, 0xa4, 0xd5, 0xa7, 0xc9, 0xdb, 0xfc, 0x53, 0x84, 0xd5, 0x05, 0x3f, 0xc9, 0x6b,
|
0xfb, 0x09, 0x21, 0xed, 0xc1, 0x99, 0x11, 0xfc, 0xa4, 0x8d, 0x2d, 0x28, 0xc6, 0x04, 0xd3, 0x4a,
|
||||||
0xf0, 0xe6, 0x1d, 0x4d, 0xfa, 0x6c, 0x98, 0xf6, 0x5a, 0x70, 0x3a, 0xe9, 0x0c, 0xb5, 0xae, 0xf1,
|
0x51, 0xb7, 0x12, 0xbf, 0x76, 0x1c, 0xc7, 0xd5, 0x9f, 0x16, 0xb8, 0x2d, 0xd6, 0xfd, 0xcb, 0x3b,
|
||||||
0xdd, 0xed, 0xfc, 0x9d, 0x74, 0xe2, 0xbb, 0x5b, 0xa3, 0xeb, 0x5b, 0x78, 0xce, 0xa6, 0x52, 0xd1,
|
0x7d, 0x16, 0x62, 0x27, 0xa2, 0x6a, 0x98, 0x7a, 0x27, 0x4e, 0x5c, 0x50, 0x35, 0x24, 0x6f, 0xa1,
|
||||||
0x28, 0xc2, 0x61, 0xae, 0xae, 0x35, 0xd0, 0xcb, 0x81, 0x4c, 0xe3, 0x57, 0xb0, 0x3a, 0x62, 0xbf,
|
0x18, 0xb2, 0xae, 0xa0, 0x22, 0x5e, 0x40, 0xe6, 0x71, 0x8f, 0xb4, 0x34, 0x61, 0xea, 0x3f, 0x30,
|
||||||
0xe6, 0x88, 0x65, 0x43, 0x5c, 0x31, 0xc5, 0x8c, 0xb4, 0x01, 0x15, 0xc5, 0x54, 0x84, 0xa9, 0xb3,
|
0x97, 0x4c, 0x92, 0xfd, 0x87, 0x49, 0x72, 0xff, 0x6f, 0x92, 0x77, 0x60, 0x27, 0x4f, 0x3d, 0x6d,
|
||||||
0x36, 0x21, 0x0d, 0xa8, 0x0f, 0x51, 0x86, 0x82, 0xc5, 0x4a, 0x7f, 0x68, 0xdd, 0x9d, 0x2f, 0x91,
|
0x69, 0xd5, 0x1f, 0x19, 0x58, 0x5d, 0x70, 0x09, 0x79, 0x05, 0xee, 0xbc, 0x4f, 0xa6, 0x1d, 0xd6,
|
||||||
0x77, 0xe0, 0x4a, 0x9c, 0xa1, 0x60, 0x2a, 0x31, 0xf6, 0xae, 0xb5, 0xfd, 0x65, 0x41, 0x2f, 0x53,
|
0x4b, 0x6a, 0x2d, 0xf8, 0x67, 0xda, 0xec, 0xc5, 0xdb, 0x8a, 0xee, 0x06, 0xf3, 0x9f, 0x8f, 0x1d,
|
||||||
0x3c, 0xc8, 0x99, 0x64, 0x07, 0x40, 0xe0, 0x08, 0x05, 0x4e, 0x43, 0x94, 0xbe, 0xdb, 0x28, 0x69,
|
0xdd, 0x0d, 0xb4, 0x8c, 0x37, 0xf0, 0x9c, 0x8d, 0xa5, 0xa2, 0x61, 0x88, 0xbd, 0xd9, 0xce, 0x8c,
|
||||||
0xd7, 0x1f, 0x2a, 0x6f, 0x8e, 0xc0, 0xcd, 0xbe, 0x22, 0x75, 0x70, 0xae, 0x7a, 0x5f, 0x7b, 0xe7,
|
0x58, 0x77, 0x06, 0xa4, 0x9b, 0x7b, 0x09, 0xab, 0x7d, 0xf6, 0x7d, 0x8e, 0x68, 0x3e, 0x9d, 0x15,
|
||||||
0x37, 0x3d, 0xef, 0x19, 0x71, 0xa0, 0xd4, 0x3d, 0xbf, 0xf1, 0x0a, 0x04, 0xa0, 0x7a, 0x76, 0x7c,
|
0x9d, 0x4c, 0x49, 0x1b, 0x90, 0x57, 0x4c, 0x85, 0x98, 0xf8, 0xc5, 0x04, 0xa4, 0x02, 0xa5, 0x1e,
|
||||||
0xd4, 0xb9, 0x3a, 0xf3, 0x8a, 0xc4, 0x85, 0xf2, 0x69, 0xe7, 0xe4, 0xd4, 0x2b, 0x91, 0x15, 0x70,
|
0xca, 0x40, 0xb0, 0x48, 0xc5, 0x17, 0x8d, 0x67, 0xe6, 0x53, 0xe4, 0x00, 0x1c, 0x89, 0x13, 0x14,
|
||||||
0x0f, 0x83, 0xce, 0xb7, 0xce, 0xe1, 0xc7, 0xae, 0x57, 0x6e, 0xdf, 0x00, 0x64, 0x6f, 0x00, 0x17,
|
0x4c, 0x4d, 0xb5, 0x69, 0xd6, 0x1a, 0xde, 0xf2, 0x96, 0x2e, 0x13, 0xdc, 0x9f, 0x31, 0xc9, 0x0e,
|
||||||
0xa4, 0x03, 0x55, 0x1b, 0x93, 0xdd, 0xe5, 0x0d, 0x97, 0x5e, 0x8a, 0xad, 0x9d, 0x65, 0xc2, 0xe2,
|
0x80, 0xc0, 0x3e, 0x0a, 0x1c, 0x07, 0x28, 0x3d, 0xa7, 0x92, 0x8d, 0xbd, 0xf4, 0x90, 0x79, 0x7d,
|
||||||
0xcf, 0xdc, 0xfe, 0x0e, 0xf5, 0xfc, 0xde, 0x71, 0x41, 0xbe, 0xe4, 0x9d, 0x1b, 0x8f, 0x5c, 0xa6,
|
0x04, 0x4e, 0x7a, 0x8b, 0x94, 0xc0, 0xbe, 0x6e, 0x7f, 0x6e, 0x9f, 0xdf, 0xb6, 0xdd, 0x67, 0xc4,
|
||||||
0x27, 0xb5, 0xfe, 0x04, 0x3f, 0xdc, 0x0c, 0x1a, 0x54, 0xcd, 0xd3, 0x76, 0xf0, 0x2f, 0x00, 0x00,
|
0x86, 0x6c, 0xeb, 0xfc, 0xd6, 0xb5, 0x08, 0x40, 0xe1, 0xec, 0xf8, 0xa8, 0x79, 0x7d, 0xe6, 0x66,
|
||||||
0xff, 0xff, 0xde, 0x1c, 0x85, 0x42, 0xf8, 0x04, 0x00, 0x00,
|
0x88, 0x03, 0xb9, 0xd3, 0xe6, 0xc9, 0xa9, 0x9b, 0x25, 0x2b, 0xe0, 0x1c, 0xfa, 0xcd, 0xab, 0xe6,
|
||||||
|
0xe1, 0xfb, 0x96, 0x9b, 0x6b, 0xdc, 0x02, 0xa4, 0xbf, 0x2b, 0x2e, 0x48, 0x13, 0x0a, 0xe6, 0x4c,
|
||||||
|
0x76, 0x97, 0x3b, 0x5c, 0xfa, 0xa9, 0x95, 0x77, 0x96, 0x09, 0x8b, 0xbf, 0x88, 0xc6, 0x17, 0x28,
|
||||||
|
0xcd, 0xcc, 0xcc, 0x05, 0xf9, 0x34, 0xab, 0x5c, 0x79, 0xc4, 0xa1, 0x4f, 0x2a, 0xfd, 0x01, 0xbe,
|
||||||
|
0x3a, 0x29, 0xd4, 0x2d, 0x68, 0x4f, 0xee, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x65, 0x1f, 0xdb,
|
||||||
|
0x8d, 0xc5, 0x05, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
|
import "google/protobuf/timestamp.proto";
|
||||||
|
|
||||||
package trivy.detector;
|
package trivy.detector;
|
||||||
option go_package = "detector";
|
option go_package = "detector";
|
||||||
|
|
||||||
@@ -8,9 +10,11 @@ service OSDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message OSDetectRequest {
|
message OSDetectRequest {
|
||||||
string os_family = 1;
|
string os_family = 1;
|
||||||
string os_name = 2;
|
string os_name = 2;
|
||||||
repeated Package packages = 3;
|
repeated Package packages = 3;
|
||||||
|
string image_name = 4;
|
||||||
|
google.protobuf.Timestamp created = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
message DetectResponse {
|
message DetectResponse {
|
||||||
@@ -39,8 +43,10 @@ service LibDetector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message LibDetectRequest {
|
message LibDetectRequest {
|
||||||
string file_path = 1;
|
string file_path = 1;
|
||||||
repeated Library libraries = 2;
|
repeated Library libraries = 2;
|
||||||
|
string image_name = 3;
|
||||||
|
google.protobuf.Timestamp created = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Library {
|
message Library {
|
||||||
|
|||||||
@@ -1084,44 +1084,49 @@ func callError(ctx context.Context, h *twirp.ServerHooks, err twirp.Error) conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
var twirpFileDescriptor0 = []byte{
|
var twirpFileDescriptor0 = []byte{
|
||||||
// 618 bytes of a gzipped FileDescriptorProto
|
// 693 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x4f, 0xdb, 0x40,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x54, 0x4d, 0x6f, 0xd3, 0x40,
|
||||||
0x10, 0x6d, 0x3e, 0xed, 0x4c, 0xf8, 0x70, 0x57, 0x48, 0xb8, 0xa0, 0x42, 0x94, 0x5e, 0x68, 0x2b,
|
0x10, 0xc5, 0xf9, 0xb2, 0x33, 0xe9, 0x87, 0x59, 0x55, 0xaa, 0x49, 0xd5, 0x36, 0x0a, 0x97, 0x02,
|
||||||
0x05, 0x29, 0xb4, 0xea, 0xb9, 0x05, 0x0a, 0x69, 0x43, 0x40, 0xa6, 0x80, 0xda, 0x4b, 0xb4, 0x71,
|
0x52, 0x22, 0xa5, 0x45, 0x9c, 0xa1, 0x2d, 0x6d, 0x20, 0x4d, 0x2b, 0xf7, 0x4b, 0x70, 0x89, 0x36,
|
||||||
0x26, 0x64, 0x85, 0x93, 0x75, 0x77, 0x97, 0xa8, 0x96, 0xfa, 0xb7, 0xfa, 0xd3, 0x7a, 0xaf, 0x76,
|
0xce, 0x24, 0x59, 0xd5, 0xc9, 0x9a, 0xdd, 0x6d, 0x44, 0x7e, 0x18, 0x27, 0x7e, 0x05, 0x3f, 0x86,
|
||||||
0xd7, 0x36, 0x49, 0xca, 0x85, 0xdb, 0xcc, 0xbc, 0xe7, 0x99, 0xd9, 0xf7, 0xd6, 0x0b, 0x5b, 0x22,
|
0x3b, 0xf2, 0xae, 0x9d, 0x26, 0xa1, 0x42, 0xf4, 0xb6, 0x33, 0xef, 0xed, 0xec, 0xbc, 0x99, 0x67,
|
||||||
0x0e, 0xf7, 0x87, 0xa8, 0x30, 0x54, 0x5c, 0xec, 0x4b, 0x14, 0x33, 0x16, 0x62, 0x2b, 0x16, 0x5c,
|
0x43, 0x59, 0x44, 0x41, 0xbd, 0x87, 0x0a, 0x03, 0xc5, 0x45, 0x5d, 0xa2, 0x98, 0xb0, 0x00, 0x6b,
|
||||||
0x71, 0xb2, 0xa6, 0x04, 0x9b, 0x25, 0xad, 0x0c, 0x6d, 0xfe, 0x86, 0xf5, 0xf3, 0xcb, 0x23, 0x93,
|
0x91, 0xe0, 0x8a, 0x93, 0x35, 0x25, 0xd8, 0x64, 0x5a, 0x4b, 0xd1, 0xf2, 0xee, 0x80, 0xf3, 0x41,
|
||||||
0x05, 0xf8, 0xf3, 0x1e, 0xa5, 0x22, 0xdb, 0x50, 0xe3, 0xb2, 0x3f, 0xa2, 0x13, 0x16, 0x25, 0x7e,
|
0x88, 0x75, 0x8d, 0x76, 0xef, 0xfb, 0x75, 0xc5, 0x46, 0x28, 0x15, 0x1d, 0x45, 0xe6, 0x42, 0xf5,
|
||||||
0xa1, 0x51, 0xd8, 0xab, 0x05, 0x2e, 0x97, 0x9f, 0x4d, 0x4e, 0x36, 0xc1, 0xe1, 0xb2, 0x3f, 0xa5,
|
0x97, 0x05, 0xeb, 0xe7, 0x97, 0x47, 0x9a, 0xef, 0xe3, 0xb7, 0x7b, 0x94, 0x8a, 0x6c, 0x41, 0x91,
|
||||||
0x13, 0xf4, 0x8b, 0x06, 0xaa, 0x72, 0xd9, 0xa3, 0x13, 0x24, 0x07, 0xe0, 0xc6, 0x34, 0xbc, 0xa3,
|
0xcb, 0x4e, 0x9f, 0x8e, 0x58, 0x38, 0xf5, 0xac, 0x8a, 0xb5, 0x57, 0xf4, 0x1d, 0x2e, 0x3f, 0xea,
|
||||||
0xb7, 0x28, 0xfd, 0x52, 0xa3, 0xb4, 0x57, 0x6f, 0x6f, 0xb6, 0x16, 0x67, 0xb5, 0x2e, 0x2c, 0x1e,
|
0x98, 0x6c, 0x82, 0xcd, 0x65, 0x67, 0x4c, 0x47, 0xe8, 0x65, 0x34, 0x54, 0xe0, 0xb2, 0x4d, 0x47,
|
||||||
0xe4, 0xc4, 0xe6, 0x04, 0xd6, 0xb2, 0xd9, 0x32, 0xe6, 0x53, 0x89, 0xe4, 0x04, 0xd6, 0x67, 0xf7,
|
0x48, 0xf6, 0xc1, 0x89, 0x68, 0x70, 0x47, 0x07, 0x28, 0xbd, 0x6c, 0x25, 0xbb, 0x57, 0x6a, 0x6c,
|
||||||
0xd1, 0x14, 0x05, 0x1d, 0xb0, 0x88, 0x29, 0x86, 0xd2, 0x2f, 0x98, 0x6e, 0x2f, 0x97, 0xbb, 0x5d,
|
0xd6, 0x16, 0xbb, 0xa9, 0x5d, 0x18, 0xdc, 0x9f, 0x11, 0xc9, 0x36, 0x00, 0x1b, 0xd1, 0x01, 0x9a,
|
||||||
0xcf, 0xd1, 0x92, 0x60, 0xf9, 0x2b, 0x42, 0xa0, 0x8c, 0x5c, 0x46, 0x66, 0x4b, 0x37, 0x30, 0x71,
|
0x82, 0x39, 0x5d, 0xb0, 0xa8, 0x33, 0xba, 0xe6, 0x01, 0xd8, 0x81, 0x40, 0xaa, 0xb0, 0xe7, 0xe5,
|
||||||
0xf3, 0x6f, 0x01, 0x9c, 0x74, 0x09, 0x8d, 0x9b, 0x53, 0xd8, 0x03, 0x9a, 0x98, 0xf8, 0xe0, 0xcc,
|
0x2b, 0xd6, 0x5e, 0xa9, 0x51, 0xae, 0x19, 0x41, 0xb5, 0x54, 0x50, 0xed, 0x2a, 0x15, 0xe4, 0xa7,
|
||||||
0x50, 0x48, 0xc6, 0xa7, 0xe9, 0xe1, 0xb2, 0x54, 0x23, 0x02, 0x23, 0xa4, 0x12, 0xfd, 0x92, 0x45,
|
0xd4, 0xea, 0x08, 0xd6, 0x52, 0x41, 0x32, 0xe2, 0x63, 0x89, 0xe4, 0x04, 0xd6, 0x27, 0xf7, 0xe1,
|
||||||
0xd2, 0x94, 0x6c, 0x40, 0x05, 0x63, 0x1e, 0x8e, 0xfd, 0x72, 0xa3, 0xb0, 0x57, 0x09, 0x6c, 0xa2,
|
0x18, 0x05, 0xed, 0xb2, 0x90, 0x29, 0x86, 0xd2, 0xb3, 0x74, 0x8b, 0xdb, 0xcb, 0x2d, 0xde, 0xcc,
|
||||||
0xbb, 0x53, 0x11, 0x8e, 0xfd, 0x8a, 0xed, 0xae, 0x63, 0xf2, 0x02, 0x5c, 0x29, 0x42, 0xab, 0x5d,
|
0xd1, 0xa6, 0xfe, 0xf2, 0x2d, 0x42, 0x20, 0x87, 0x5c, 0x86, 0x5a, 0xba, 0xe3, 0xeb, 0x73, 0xf5,
|
||||||
0xd5, 0x36, 0x91, 0x22, 0x34, 0xe2, 0xed, 0x42, 0x5d, 0x43, 0xd9, 0x70, 0xc7, 0xa0, 0x20, 0x45,
|
0xb7, 0x05, 0x76, 0xa2, 0x2c, 0xc6, 0xb5, 0x12, 0x33, 0x35, 0x7d, 0x26, 0x1e, 0xd8, 0x13, 0x14,
|
||||||
0x78, 0x9d, 0xce, 0x4f, 0x09, 0xd9, 0x0e, 0x6e, 0x4e, 0x08, 0xd2, 0x35, 0xb6, 0xa1, 0xa6, 0x09,
|
0x92, 0xf1, 0x71, 0x32, 0xb1, 0x34, 0x8c, 0x11, 0x81, 0x21, 0x52, 0x89, 0x5e, 0xd6, 0x20, 0x49,
|
||||||
0x76, 0x95, 0x9a, 0x59, 0x45, 0x4f, 0x3b, 0xd6, 0x79, 0x73, 0x04, 0x5e, 0x97, 0x0d, 0xfe, 0x73,
|
0x48, 0x36, 0x20, 0x8f, 0x11, 0x0f, 0x86, 0x7a, 0x24, 0x79, 0xdf, 0x04, 0x71, 0x75, 0x2a, 0x82,
|
||||||
0x79, 0xc4, 0x22, 0xec, 0xc7, 0x54, 0x8d, 0x33, 0x97, 0x75, 0xe1, 0x82, 0xaa, 0x31, 0x79, 0x0f,
|
0xa1, 0x9e, 0x45, 0xd1, 0xd7, 0x67, 0xf2, 0x02, 0x1c, 0x29, 0x02, 0x33, 0xbf, 0x82, 0x29, 0x22,
|
||||||
0xb5, 0x88, 0x0d, 0x04, 0x15, 0x5a, 0xff, 0xe2, 0xe3, 0x6e, 0x76, 0x0d, 0x21, 0x09, 0x1e, 0x98,
|
0x45, 0xa0, 0xa7, 0xb7, 0x0b, 0xa5, 0x18, 0x4a, 0x1f, 0xb7, 0x35, 0x0a, 0x52, 0x04, 0x37, 0xc9,
|
||||||
0xcd, 0x0f, 0xe0, 0xa4, 0xd5, 0xa7, 0xc9, 0xdb, 0xfc, 0x53, 0x84, 0xd5, 0x05, 0x3f, 0xc9, 0x6b,
|
0xfb, 0x09, 0x21, 0xed, 0xc1, 0x99, 0x11, 0xfc, 0xa4, 0x8d, 0x2d, 0x28, 0xc6, 0x04, 0xd3, 0x4a,
|
||||||
0xf0, 0xe6, 0x1d, 0x4d, 0xfa, 0x6c, 0x98, 0xf6, 0x5a, 0x70, 0x3a, 0xe9, 0x0c, 0xb5, 0xae, 0xf1,
|
0x51, 0xb7, 0x12, 0xbf, 0x76, 0x1c, 0xc7, 0xd5, 0x9f, 0x16, 0xb8, 0x2d, 0xd6, 0xfd, 0xcb, 0x3b,
|
||||||
0xdd, 0xed, 0xfc, 0x9d, 0x74, 0xe2, 0xbb, 0x5b, 0xa3, 0xeb, 0x5b, 0x78, 0xce, 0xa6, 0x52, 0xd1,
|
0x7d, 0x16, 0x62, 0x27, 0xa2, 0x6a, 0x98, 0x7a, 0x27, 0x4e, 0x5c, 0x50, 0x35, 0x24, 0x6f, 0xa1,
|
||||||
0x28, 0xc2, 0x61, 0xae, 0xae, 0x35, 0xd0, 0xcb, 0x81, 0x4c, 0xe3, 0x57, 0xb0, 0x3a, 0x62, 0xbf,
|
0x18, 0xb2, 0xae, 0xa0, 0x22, 0x5e, 0x40, 0xe6, 0x71, 0x8f, 0xb4, 0x34, 0x61, 0xea, 0x3f, 0x30,
|
||||||
0xe6, 0x88, 0x65, 0x43, 0x5c, 0x31, 0xc5, 0x8c, 0xb4, 0x01, 0x15, 0xc5, 0x54, 0x84, 0xa9, 0xb3,
|
0x97, 0x4c, 0x92, 0xfd, 0x87, 0x49, 0x72, 0xff, 0x6f, 0x92, 0x77, 0x60, 0x27, 0x4f, 0x3d, 0x6d,
|
||||||
0x36, 0x21, 0x0d, 0xa8, 0x0f, 0x51, 0x86, 0x82, 0xc5, 0x4a, 0x7f, 0x68, 0xdd, 0x9d, 0x2f, 0x91,
|
0x69, 0xd5, 0x1f, 0x19, 0x58, 0x5d, 0x70, 0x09, 0x79, 0x05, 0xee, 0xbc, 0x4f, 0xa6, 0x1d, 0xd6,
|
||||||
0x77, 0xe0, 0x4a, 0x9c, 0xa1, 0x60, 0x2a, 0x31, 0xf6, 0xae, 0xb5, 0xfd, 0x65, 0x41, 0x2f, 0x53,
|
0x4b, 0x6a, 0x2d, 0xf8, 0x67, 0xda, 0xec, 0xc5, 0xdb, 0x8a, 0xee, 0x06, 0xf3, 0x9f, 0x8f, 0x1d,
|
||||||
0x3c, 0xc8, 0x99, 0x64, 0x07, 0x40, 0xe0, 0x08, 0x05, 0x4e, 0x43, 0x94, 0xbe, 0xdb, 0x28, 0x69,
|
0xdd, 0x0d, 0xb4, 0x8c, 0x37, 0xf0, 0x9c, 0x8d, 0xa5, 0xa2, 0x61, 0x88, 0xbd, 0xd9, 0xce, 0x8c,
|
||||||
0xd7, 0x1f, 0x2a, 0x6f, 0x8e, 0xc0, 0xcd, 0xbe, 0x22, 0x75, 0x70, 0xae, 0x7a, 0x5f, 0x7b, 0xe7,
|
0x58, 0x77, 0x06, 0xa4, 0x9b, 0x7b, 0x09, 0xab, 0x7d, 0xf6, 0x7d, 0x8e, 0x68, 0x3e, 0x9d, 0x15,
|
||||||
0x37, 0x3d, 0xef, 0x19, 0x71, 0xa0, 0xd4, 0x3d, 0xbf, 0xf1, 0x0a, 0x04, 0xa0, 0x7a, 0x76, 0x7c,
|
0x9d, 0x4c, 0x49, 0x1b, 0x90, 0x57, 0x4c, 0x85, 0x98, 0xf8, 0xc5, 0x04, 0xa4, 0x02, 0xa5, 0x1e,
|
||||||
0xd4, 0xb9, 0x3a, 0xf3, 0x8a, 0xc4, 0x85, 0xf2, 0x69, 0xe7, 0xe4, 0xd4, 0x2b, 0x91, 0x15, 0x70,
|
0xca, 0x40, 0xb0, 0x48, 0xc5, 0x17, 0x8d, 0x67, 0xe6, 0x53, 0xe4, 0x00, 0x1c, 0x89, 0x13, 0x14,
|
||||||
0x0f, 0x83, 0xce, 0xb7, 0xce, 0xe1, 0xc7, 0xae, 0x57, 0x6e, 0xdf, 0x00, 0x64, 0x6f, 0x00, 0x17,
|
0x4c, 0x4d, 0xb5, 0x69, 0xd6, 0x1a, 0xde, 0xf2, 0x96, 0x2e, 0x13, 0xdc, 0x9f, 0x31, 0xc9, 0x0e,
|
||||||
0xa4, 0x03, 0x55, 0x1b, 0x93, 0xdd, 0xe5, 0x0d, 0x97, 0x5e, 0x8a, 0xad, 0x9d, 0x65, 0xc2, 0xe2,
|
0x80, 0xc0, 0x3e, 0x0a, 0x1c, 0x07, 0x28, 0x3d, 0xa7, 0x92, 0x8d, 0xbd, 0xf4, 0x90, 0x79, 0x7d,
|
||||||
0xcf, 0xdc, 0xfe, 0x0e, 0xf5, 0xfc, 0xde, 0x71, 0x41, 0xbe, 0xe4, 0x9d, 0x1b, 0x8f, 0x5c, 0xa6,
|
0x04, 0x4e, 0x7a, 0x8b, 0x94, 0xc0, 0xbe, 0x6e, 0x7f, 0x6e, 0x9f, 0xdf, 0xb6, 0xdd, 0x67, 0xc4,
|
||||||
0x27, 0xb5, 0xfe, 0x04, 0x3f, 0xdc, 0x0c, 0x1a, 0x54, 0xcd, 0xd3, 0x76, 0xf0, 0x2f, 0x00, 0x00,
|
0x86, 0x6c, 0xeb, 0xfc, 0xd6, 0xb5, 0x08, 0x40, 0xe1, 0xec, 0xf8, 0xa8, 0x79, 0x7d, 0xe6, 0x66,
|
||||||
0xff, 0xff, 0xde, 0x1c, 0x85, 0x42, 0xf8, 0x04, 0x00, 0x00,
|
0x88, 0x03, 0xb9, 0xd3, 0xe6, 0xc9, 0xa9, 0x9b, 0x25, 0x2b, 0xe0, 0x1c, 0xfa, 0xcd, 0xab, 0xe6,
|
||||||
|
0xe1, 0xfb, 0x96, 0x9b, 0x6b, 0xdc, 0x02, 0xa4, 0xbf, 0x2b, 0x2e, 0x48, 0x13, 0x0a, 0xe6, 0x4c,
|
||||||
|
0x76, 0x97, 0x3b, 0x5c, 0xfa, 0xa9, 0x95, 0x77, 0x96, 0x09, 0x8b, 0xbf, 0x88, 0xc6, 0x17, 0x28,
|
||||||
|
0xcd, 0xcc, 0xcc, 0x05, 0xf9, 0x34, 0xab, 0x5c, 0x79, 0xc4, 0xa1, 0x4f, 0x2a, 0xfd, 0x01, 0xbe,
|
||||||
|
0x3a, 0x29, 0xd4, 0x2d, 0x68, 0x4f, 0xee, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x65, 0x1f, 0xdb,
|
||||||
|
0x8d, 0xc5, 0x05, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user