Also added code to track tempfile creation and handle their cleanup.
Fixes bug #8096 --- src/bin/secstate | 39 +++++++++++++++++++++------------------ src/secstate/main.py | 19 +++++++++++++++---- src/secstate/util.py | 1 - 3 files changed, 36 insertions(+), 23 deletions(-)
diff --git a/src/bin/secstate b/src/bin/secstate index ebaf9c8..31fb4f7 100644 --- a/src/bin/secstate +++ b/src/bin/secstate @@ -24,6 +24,7 @@ import sys import ConfigParser import os +import shutil from optparse import OptionParser
import openscap_api as oscap @@ -57,67 +58,69 @@ def main(): subcommand = sys.argv[1] except IndexError, e: usage() - return -1 + return_code = -1
arg_num = 2 if (subcommand == '-c') or (subcommand == '--config'): if not sec_instance.setConfigFile(sys.argv[arg_num]): usage() - return -1 + return_code = -1 arg_num += 2 try: subcommand = sys.argv[arg_num - 1] except IndexError: usage() - return -1 + return_code = -1
if subcommand == 'help': - return help(sys.argv[arg_num:]) + return_code = help(sys.argv[arg_num:])
elif subcommand == 'export': - return export(sys.argv[arg_num:]) + return_code = export(sys.argv[arg_num:])
elif subcommand == 'search': - return search(sys.argv[arg_num:]) + return_code = search(sys.argv[arg_num:])
elif subcommand == 'list': - return list_content(sys.argv[arg_num:]) + return_code = list_content(sys.argv[arg_num:])
elif subcommand == 'show': - return show(sys.argv[arg_num:]) + return_code = show(sys.argv[arg_num:])
elif os.geteuid() != 0: sys.stderr.write("secstate must be run as root!\n") - return -1 + return_code = -1
elif subcommand == 'import': - return import_content(sys.argv[arg_num:]) + return_code = import_content(sys.argv[arg_num:])
elif subcommand == 'remove': - return remove_content(sys.argv[arg_num:]) + return_code = remove_content(sys.argv[arg_num:])
elif subcommand == 'select': - return select(sys.argv[arg_num:], True) + return_code = select(sys.argv[arg_num:], True)
elif subcommand == 'deselect': - return select(sys.argv[arg_num:], False) + return_code = select(sys.argv[arg_num:], False)
elif subcommand == 'audit': - return audit(sys.argv[arg_num:]) + return_code = audit(sys.argv[arg_num:])
elif subcommand == 'remediate': - return remediate(sys.argv[arg_num:]) + return_code = remediate(sys.argv[arg_num:])
elif subcommand == 'mitigate': - return mitigate(sys.argv[arg_num:]) + return_code = mitigate(sys.argv[arg_num:])
elif subcommand == 'save': - return save_profile(sys.argv[arg_num:]) + return_code = save_profile(sys.argv[arg_num:])
else: sys.stderr.write("Uknown subcommand: %(command)s" % {'command':subcommand}) usage() - return -1 + return_code = -1 + + return return_code
def help(arg): if arg == []: diff --git a/src/secstate/main.py b/src/secstate/main.py index f2025cd..c8a603e 100644 --- a/src/secstate/main.py +++ b/src/secstate/main.py @@ -54,6 +54,17 @@ class Secstate: self.load_content() self.log = self.getLogger() self.benchmark_dir = self.config.get('secstate', 'benchmark_dir') + self.tempfiles = {'dirs':[], 'files':[]} + + def __del__(self): + try: + for dir in self.tempfiles['dirs']: + shutil.rmtree(dir) + + for tmpfile in self.tempfiles['files']: + os.remove(tmpfile) + except IOError,e: + sec_instance.log.error("Error cleaning up temporary files: %(err)s" % {'err':e})
def setConfigFile(self, conf): config = ConfigParser.ConfigParser() @@ -349,6 +360,7 @@ class Secstate: Output: Success of failure of the import """ extract_path = tempfile.mkdtemp() + self.tempfiles['dirs'].append(extract_path)
if type[0] == "application/x-tar": tar_file = None @@ -407,11 +419,8 @@ class Secstate: if benchmark == None: return None
- # Delete temporary directory now that we are done with it - shutil.rmtree(extract_path) return benchmark
- def import_content(self, content, changes=True, save=False, active_profile=NONE_PROFILE): """ Function: Validates XCCDF/OVAL content and optionally saves it to the data store @@ -474,6 +483,7 @@ class Secstate: benchmark_file = self.content[benchmark_id] else: benchmark_file = tempfile.mktemp() + self.tempfiles['files'].append(benchmark_file) benchmark = self.import_content(benchmark_id) if benchmark.export(benchmark_file) == None: self.log.error("Error exporting benchmark to %(file)s" % {'file':new_file}) @@ -1049,6 +1059,7 @@ class Secstate: site_pp = self.config.get('secstate', 'site_pp') else: (site_pp_buf, site_pp) = tempfile.mkstemp() + self.tempfiles['files'].append(site_pp) for puppet in benchmark.puppet: os.write(site_pp_buf, 'import "%(file)s"\n' % {'file':puppet}) os.close(site_pp_buf) @@ -1073,6 +1084,7 @@ class Secstate:
else: handle, fname = tempfile.mkstemp(suffix='.yaml') + self.tempfiles['files'].append(fname) os.write(handle, template % dict_to_external(puppet_content)) os.close(handle) puppet_args = ['/usr/bin/puppet', '--external_node', '/usr/libexec/secstate/secstate_external_node %s' % fname, '--node_terminus', 'exec', site_pp] @@ -1083,7 +1095,6 @@ class Secstate: if verbose: puppet_args.append('--verbose') subprocess.call(puppet_args) - os.unlink(fname)
return True
diff --git a/src/secstate/util.py b/src/secstate/util.py index d30a169..1b208cd 100644 --- a/src/secstate/util.py +++ b/src/secstate/util.py @@ -27,7 +27,6 @@ import time import re import ConfigParser import json -import tempfile import zipfile import libxml2 import libxslt