def run_profile(domain_ip, profile, stage, datastream, benchmark_id, remediation=False): """Run `oscap-ssh` command with provided parameters to check given profile. Log output into LogHelper.LOG_DIR. Return True if command ends with exit codes 0 or 2 """ formatting = { 'domain_ip': domain_ip, 'profile': profile, 'datastream': datastream, 'benchmark_id': benchmark_id } formatting['rem'] = "--remediate" if remediation else "" report_path = os.path.join(LogHelper.LOG_DIR, '{0}-{1}'.format(profile, stage)) verbose_path = os.path.join(LogHelper.LOG_DIR, '{0}-{1}'.format(profile, stage)) formatting['report'] = LogHelper.find_name(report_path, '.html') verbose_path = LogHelper.find_name(verbose_path, '.verbose.log') command = shlex.split(('oscap-ssh root@{domain_ip} 22 xccdf eval ' '--benchmark-id {benchmark_id} ' '--profile {profile} ' '--progress --oval-results ' '--report {report} ' '--verbose DEVEL ' '{rem} ' '{datastream}').format(**formatting)) logging.debug('Running ' + ' '.join(command)) success = True try: with open(verbose_path, 'w') as verbose_file: output = subprocess.check_output(command, stderr=verbose_file) except subprocess.CalledProcessError, e: # non-zero exit code if e.returncode != 2: success = False logging.error(('Profile run should end with return code 0 or 2 ' 'not "{0}" as it did!').format(e.returncode))
def get_logging_dir(options): body = 'custom' if 'ALL' in options.target: body = 'ALL' generic_logdir_stem = "{0}-{1}".format(options.subparser_name, body) if options.logdir is None: date_string = time.strftime('%Y-%m-%d-%H%M', time.localtime()) logging_dir = os.path.join( os.getcwd(), 'logs', '{0}-{1}'.format( generic_logdir_stem, date_string)) logging_dir = LogHelper.find_name(logging_dir) else: logging_dir = LogHelper.find_name(options.logdir) return logging_dir
def main(): options = parse_args() log = logging.getLogger() # this is general logger level - needs to be # debug otherwise it cuts silently everything log.setLevel(logging.DEBUG) try: bench_id = xml_operations.infer_benchmark_id_from_component_ref_id( options.datastream, options.xccdf_id) options.benchmark_id = bench_id except RuntimeError as exc: msg = "Error inferring benchmark ID: {}".format(str(exc)) logging.error(msg) sys.exit(1) LogHelper.add_console_logger(log, options.loglevel) # logging dir needs to be created based on other options # thus we have to postprocess it if 'ALL' in options.target: options.target = ['ALL'] if options.logdir is None: # default! prefix = options.subparser_name body = "" if 'ALL' in options.target: body = 'ALL' else: body = 'custom' date_string = time.strftime('%Y-%m-%d-%H%M', time.localtime()) logging_dir = os.path.join(os.getcwd(), 'logs', '{0}-{1}-{2}'.format(prefix, body, date_string)) logging_dir = LogHelper.find_name(logging_dir) else: logging_dir = LogHelper.find_name(options.logdir) LogHelper.add_logging_dir(log, logging_dir) options.func(options)
def _make_results_path(self): results_basename = self._get_results_basename() results_path = os.path.join(LogHelper.LOG_DIR, results_basename) self.results_path = LogHelper.find_name(results_path, '.xml')
def _make_verbose_path(self): verbose_basename = self._get_verbose_basename() verbose_path = os.path.join(LogHelper.LOG_DIR, verbose_basename) self.verbose_path = LogHelper.find_name(verbose_path, '.verbose.log')
def _make_report_path(self): report_file = self._get_report_file() report_path = os.path.join(LogHelper.LOG_DIR, report_file) self.report_path = LogHelper.find_name(report_path, '.html')
def _make_results_path(self): results_file = self._get_results_file() results_path = os.path.join(LogHelper.LOG_DIR, results_file) self.results_path = LogHelper.find_name(results_path, '.xml')
def _make_verbose_path(self): verbose_file = self._get_verbose_file() verbose_path = os.path.join(LogHelper.LOG_DIR, verbose_file) self.verbose_path = LogHelper.find_name(verbose_path, '.verbose.log')
options.datastream, options.xccdf_id) options.benchmark_id = bench_id except RuntimeError as exc: msg = "Error inferring benchmark ID: {}".format(str(exc)) logging.error(msg) sys.exit(1) LogHelper.add_console_logger(log, options.loglevel) # logging dir needs to be created based on other options # thus we have to postprocess it if 'ALL' in options.target: options.target = ['ALL'] if options.logdir is None: # default! prefix = options.subparser_name body = "" if 'ALL' in options.target: body = 'ALL' else: body = 'custom' date_string = time.strftime('%Y-%m-%d-%H%M', time.localtime()) logging_dir = os.path.join(os.getcwd(), 'logs', '{0}-{1}-{2}'.format(prefix, body, date_string)) logging_dir = LogHelper.find_name(logging_dir) else: logging_dir = LogHelper.find_name(options.logdir) LogHelper.add_logging_dir(log, logging_dir) options.func(options)
def run_rule(domain_ip, profile, stage, datastream, benchmark_id, rule_id, context, script_name, remediation=False, dont_clean=False): """Run `oscap-ssh` command with provided parameters to check given rule, utilizing --rule option. Log output to LogHelper.LOG_DIR directory. Return True if result is as expected by context parameter. Check both exit code and output message. """ formatting = { 'domain_ip': domain_ip, 'profile': profile, 'datastream': datastream, 'benchmark_id': benchmark_id, 'rule_id': rule_id } formatting['rem'] = "--remediate" if remediation else "" report_path = os.path.join( LogHelper.LOG_DIR, '{0}-{1}-{2}'.format(rule_id, script_name, stage)) verbose_path = os.path.join( LogHelper.LOG_DIR, '{0}-{1}-{2}'.format(rule_id, script_name, stage)) formatting['report'] = LogHelper.find_name(report_path, '.html') verbose_path = LogHelper.find_name(verbose_path, '.verbose.log') command = shlex.split(('oscap-ssh root@{domain_ip} 22 xccdf eval ' '--benchmark-id {benchmark_id} ' '--profile {profile} ' '--progress --oval-results ' '--rule {rule_id} ' '--report {report} ' '--verbose DEVEL ' '{rem} ' '{datastream}').format(**formatting)) logging.debug('Running ' + ' '.join(command)) success = True # check expected return code expected_return_code = _CONTEXT_RETURN_CODES[context] try: with open(verbose_path, 'w') as verbose_file: output = subprocess.check_output(command, stderr=verbose_file) except subprocess.CalledProcessError, e: if e.returncode != expected_return_code: LogHelper.preload_log(logging.ERROR, ('Scan has exited with return code {0}, ' 'instead of expected {1} ' 'during stage {2}').format( e.returncode, expected_return_code, stage), 'fail') success = False output = e.output
logging.error(msg) sys.exit(1) LogHelper.add_console_logger(log, options.loglevel) # logging dir needs to be created based on other options # thus we have to postprocess it if 'ALL' in options.target: options.target = ['ALL'] if options.logdir is None: # default! prefix = options.subparser_name body = "" if 'ALL' in options.target: body = 'ALL' else: body = 'custom' date_string = time.strftime('%Y-%m-%d-%H%M', time.localtime()) logging_dir = os.path.join(os.getcwd(), 'logs', '{0}-{1}-{2}'.format(prefix, body, date_string)) logging_dir = LogHelper.find_name(logging_dir) else: logging_dir = LogHelper.find_name(options.logdir) LogHelper.add_logging_dir(log, logging_dir) options.func(options)