Skip to content

Commit 3fae916

Browse files
authored
Merge pull request #1187 from matejak/oscap-docker-fix_rc
Refactored the oscap-docker script.
2 parents 5f24bfd + 31cdbba commit 3fae916

File tree

2 files changed

+45
-48
lines changed

2 files changed

+45
-48
lines changed

utils/oscap-docker.in

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,31 +26,18 @@ import sys
2626
from requests import exceptions
2727

2828

29-
class OscapDocker(object):
30-
''' Generic class to call the scans '''
31-
def __init__(self):
32-
pass
33-
34-
def set_args(self, args, unknown):
35-
'''
36-
Sets arguments for argparse into the oscapDocker class
37-
'''
38-
self.args = args
39-
self.unknown_args = unknown
40-
41-
def cve_scan(self):
42-
''' Wrapper function for container/image scanning '''
43-
OS = OscapScan()
44-
result = OS.scan_cve(self.args.scan_target, self.unknown_args)
45-
if result is not None:
46-
print(result)
47-
48-
def scan(self):
49-
''' Wrapper functiopn to scan with openscap'''
50-
OS = OscapScan()
51-
result = OS.scan(self.args.scan_target, self.unknown_args)
52-
if result is not None:
53-
print(result)
29+
def cve_scan(scan_target, other_scan_args):
30+
''' Wrapper function for container/image scanning '''
31+
OS = OscapScan()
32+
result = OS.scan_cve(scan_target, other_scan_args)
33+
return result
34+
35+
36+
def scan(scan_target, other_scan_args):
37+
''' Wrapper function to scan with openscap'''
38+
OS = OscapScan()
39+
result = OS.scan(scan_target, other_scan_args)
40+
return result
5441

5542

5643
def ping_docker():
@@ -63,10 +50,8 @@ def ping_docker():
6350
client = docker.Client()
6451
client.ping()
6552

66-
if __name__ == '__main__':
67-
68-
OD = OscapDocker()
6953

54+
if __name__ == '__main__':
7055
parser = argparse.ArgumentParser(description='oscap docker',
7156
epilog='See `man oscap` to learn \
7257
more about OSCAP-ARGUMENTS')
@@ -75,32 +60,32 @@ if __name__ == '__main__':
7560
# Scan CVEs in image
7661
image_cve = subparser.add_parser('image-cve', help='Scan a docker image \
7762
for known vulnerabilities.')
78-
image_cve.set_defaults(func=OD.cve_scan)
63+
image_cve.set_defaults(func=cve_scan)
7964
image_cve.add_argument('scan_target', help='Container or image to scan')
8065

8166
# Scan an Image
8267
image = subparser.add_parser('image', help='Scan a docker image')
8368
image.add_argument('scan_target',
8469
help='Container or image to scan')
8570

86-
image.set_defaults(func=OD.scan)
71+
image.set_defaults(func=scan)
8772
# Scan a container
8873
container = subparser.add_parser('container', help='Scan a running docker\
8974
container of given name.')
9075
container.add_argument('scan_target',
9176
help='Container or image to scan')
92-
container.set_defaults(func=OD.scan)
77+
container.set_defaults(func=scan)
9378

9479
# Scan CVEs in container
9580
container_cve = subparser.add_parser('container-cve', help='Scan a \
9681
running container for known \
9782
vulnerabilities.')
9883

99-
container_cve.set_defaults(func=OD.cve_scan)
84+
container_cve.set_defaults(func=cve_scan)
10085
container_cve.add_argument('scan_target',
10186
help='Container or image to scan')
10287

103-
args, unknown = parser.parse_known_args()
88+
args, leftover_args = parser.parse_known_args()
10489

10590
if "func" not in args:
10691
parser.print_help()
@@ -113,5 +98,10 @@ if __name__ == '__main__':
11398
print("The docker daemon does not appear to be running")
11499
sys.exit(1)
115100

116-
OD.set_args(args, unknown)
117-
args.func()
101+
try:
102+
rc = args.func(args.scan_target, leftover_args)
103+
except Exception as exc:
104+
sys.exit(255)
105+
raise exc
106+
107+
sys.exit(rc)

utils/oscap_docker_python/oscap_docker_util.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
''' Utilities for oscap-docker '''
1919

20+
from __future__ import print_function
21+
2022
import os
2123
import tempfile
2224
import subprocess
@@ -25,6 +27,7 @@
2527
from oscap_docker_python.get_cve_input import getInputCVE
2628
import sys
2729
import docker
30+
import collections
2831

2932
try:
3033
from Atomic.mount import DockerMount
@@ -68,6 +71,9 @@ class OscapError(Exception):
6871
pass
6972

7073

74+
OscapResult = collections.namedtuple("OscapResult", ("returncode", "stdout", "stderr"))
75+
76+
7177
class OscapHelpers(object):
7278
''' oscap class full of helpers for scanning '''
7379
CPE = 'oval:org.open-scap.cpe.rhel:def:'
@@ -102,10 +108,10 @@ def _get_dist(self, chroot, target):
102108
if not os.path.exists(cpe_dict):
103109
raise OscapError()
104110
for dist in self.DISTS:
105-
output = self.oscap_chroot(chroot, target, 'oval', 'eval',
111+
result = self.oscap_chroot(chroot, target, 'oval', 'eval',
106112
'--id', self.CPE + dist, cpe_dict,
107113
'2>&1', '>', '/dev/null')
108-
if "{0}{1}: true".format(self.CPE, dist) in output:
114+
if "{0}{1}: true".format(self.CPE, dist) in result.stdout:
109115
return dist
110116

111117
def _get_target_name(self, target):
@@ -149,15 +155,8 @@ def oscap_chroot(self, chroot_path, target, *oscap_args):
149155
cmd = ['oscap'] + [x for x in oscap_args]
150156
oscap_process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
151157
oscap_stdout, oscap_stderr = oscap_process.communicate()
152-
if oscap_process.returncode not in [0, 2]:
153-
sys.stderr.write("\nCommand: {0} failed!\n".format(" ".join(cmd)))
154-
sys.stderr.write("Command returned exit code {0}.\n".format(oscap_process.returncode))
155-
sys.stderr.write(oscap_stderr.decode("utf-8") + "\n")
156-
157-
sys.exit(1)
158-
159-
sys.stderr.write(oscap_stderr.decode("utf-8") + "\n")
160-
return oscap_stdout.decode("utf-8")
158+
return OscapResult(oscap_process.returncode,
159+
oscap_stdout.decode("utf-8"), oscap_stderr.decode("utf-8"))
161160

162161
def _scan_cve(self, chroot, target, dist, scan_args):
163162
'''
@@ -272,13 +271,17 @@ def scan_cve(self, image, scan_args):
272271
fetch._fetch_single(dist)
273272

274273
# Scan the chroot
275-
sys.stdout.write(self.helper._scan_cve(chroot, image, dist, scan_args))
274+
scan_result = self.helper._scan_cve(chroot, image, dist, scan_args)
275+
print(scan_result.stdout)
276+
print(scan_result.stderr, file=sys.stderr)
276277

277278
finally:
278279
# Clean up
279280
self.helper._cleanup_by_path(_tmp_mnt_dir, DM)
280281
self._remove_mnt_dir(mnt_dir)
281282

283+
return scan_result.returncode
284+
282285
def scan(self, image, scan_args):
283286
'''
284287
Wrapper function for basic security scans using
@@ -299,9 +302,13 @@ def scan(self, image, scan_args):
299302
chroot = self._find_chroot_path(_tmp_mnt_dir)
300303

301304
# Scan the chroot
302-
sys.stdout.write(self.helper._scan(chroot, image, scan_args))
305+
scan_result = self.helper._scan(chroot, image, scan_args)
306+
print(scan_result.stdout)
307+
print(scan_result.stderr, file=sys.stderr)
303308

304309
finally:
305310
# Clean up
306311
self.helper._cleanup_by_path(_tmp_mnt_dir, DM)
307312
self._remove_mnt_dir(mnt_dir)
313+
314+
return scan_result.returncode

0 commit comments

Comments
 (0)