#!@OSCAP_DOCKER_PYTHON@
# Copyright (C) 2015 Brent Baude <bbaude@redhat.com>
# Copyright (C) 2019 Dominique Blaze <contact@d0m.tech>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA
''' oscap docker command '''
import argparse
from oscap_docker_python.oscap_docker_util import OscapAtomicScan, \
OscapDockerScan, isAtomicLoaded
import docker
import traceback
import sys
from requests import exceptions
def ping_docker():
''' Simple check if the docker daemon is running '''
# Class docker.Client was renamed to docker.APIClient in
# python-docker-py 2.0.0.
try:
client = docker.APIClient()
except AttributeError:
client = docker.Client()
client.ping()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='oscap docker',
epilog='See `man oscap` to learn \
more about OSCAP-ARGUMENTS')
parser.add_argument('--oscap', dest='oscap_binary', default='',
help='Set the oscap binary to use')
parser.add_argument('--disable-atomic', dest='noatomic', action='store_true',
help="Force to use native docker API instead of atomic")
subparser = parser.add_subparsers(help="commands")
# Scan CVEs in image
image_cve = subparser.add_parser('image-cve', help='Scan a docker image \
for known vulnerabilities.')
image_cve.set_defaults(action="scan_cve", is_image=True)
image_cve.add_argument('scan_target', help='Container or image to scan')
# Scan an Image
image = subparser.add_parser('image', help='Scan a docker image')
image.add_argument('scan_target',
help='Container or image to scan')
image.set_defaults(action="scan", is_image=True)
# Scan a container
container = subparser.add_parser('container', help='Scan a running docker\
container of given name.')
container.add_argument('scan_target',
help='Container or image to scan')
container.set_defaults(action="scan", is_image=False)
# Scan CVEs in container
container_cve = subparser.add_parser('container-cve', help='Scan a \
running container for known \
vulnerabilities.')
container_cve.set_defaults(action="scan_cve", is_image=False)
container_cve.add_argument('scan_target',
help='Container or image to scan')
args, leftover_args = parser.parse_known_args()
if "action" not in args:
parser.print_help()
sys.exit(2)
try:
ping_docker()
except exceptions.ConnectionError:
print("The docker daemon does not appear to be running")
sys.exit(1)
try:
if isAtomicLoaded and not args.noatomic:
print("Using Atomic API")
OS = OscapAtomicScan(oscap_binary=args.oscap_binary)
if args.action == "scan":
rc = OscapAtomicScan.scan(OS, args.scan_target, leftover_args)
elif args.action == "scan_cve":
rc = OscapAtomicScan.scan_cve(OS, args.scan_target, leftover_args)
else:
parser.print_help()
sys.exit(2)
else: # without atomic
if args.noatomic:
print("Using native Docker API")
ODS = OscapDockerScan(args.scan_target, args.is_image, args.oscap_binary)
if args.action == "scan":
rc = OscapDockerScan.scan(ODS, leftover_args)
elif args.action == "scan_cve":
rc = OscapDockerScan.scan_cve(ODS, leftover_args)
else:
parser.print_help()
sys.exit(2)
except (ValueError, RuntimeError) as e:
raise e
sys.exit(255)
except(FileNotFoundError) as e:
sys.stderr.write("Target {0} not found.\n".format(target))
sys.exit(255)
except Exception as exc:
traceback.print_exc(file=sys.stdout)
sys.stderr.write("!!! WARNING !!! This software has crashed, so you should "
"check that no temporary container is still running\n")
sys.exit(255)
sys.exit(rc)