|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
# Copyright (C) 2013 Red Hat, Inc.
|
|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
# This copyrighted material is made available to anyone wishing to use,
|
|
Packit Service |
39273c |
# modify, copy, or redistribute it subject to the terms and conditions of
|
|
Packit Service |
39273c |
# the GNU General Public License v.2, or (at your option) any later version.
|
|
Packit Service |
39273c |
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit Service |
39273c |
# ANY WARRANTY expressed or implied, including the implied warranties of
|
|
Packit Service |
39273c |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit Service |
39273c |
# Public License for more details. You should have received a copy of the
|
|
Packit Service |
39273c |
# GNU General Public License along with this program; if not, write to the
|
|
Packit Service |
39273c |
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
39273c |
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
|
|
Packit Service |
39273c |
# source code or documentation are not subject to the GNU General Public
|
|
Packit Service |
39273c |
# License and may only be used or replicated with the express permission of
|
|
Packit Service |
39273c |
# Red Hat, Inc.
|
|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
# Red Hat Author(s): Vratislav Podzimek <vpodzime@redhat.com>
|
|
Packit Service |
39273c |
#
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Module with various classes for SCAP content processing and retrieving data
|
|
Packit Service |
39273c |
from it.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
import os.path
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
from collections import namedtuple, OrderedDict
|
|
Packit Service |
39273c |
from openscap_api import OSCAP
|
|
Packit Service |
39273c |
from pyanaconda.core.util import execReadlines
|
|
Packit Service |
39273c |
try:
|
|
Packit Service |
39273c |
from html.parser import HTMLParser
|
|
Packit Service |
39273c |
except ImportError:
|
|
Packit Service |
39273c |
from HTMLParser import HTMLParser
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class ContentHandlingError(Exception):
|
|
Packit Service |
39273c |
"""Exception class for errors related to SCAP content handling."""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
pass
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class DataStreamHandlingError(ContentHandlingError):
|
|
Packit Service |
39273c |
"""Exception class for errors related to data stream handling."""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
pass
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class BenchmarkHandlingError(ContentHandlingError):
|
|
Packit Service |
39273c |
"""Exception class for errors related to benchmark handling."""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
pass
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class ContentCheckError(ContentHandlingError):
|
|
Packit Service |
39273c |
"""Exception class for errors related to content (integrity,...) checking.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
pass
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class ParseHTMLContent(HTMLParser):
|
|
Packit Service |
39273c |
"""Parser class for HTML tags within content"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def __init__(self):
|
|
Packit Service |
39273c |
HTMLParser.__init__(self)
|
|
Packit Service |
39273c |
self.content = ""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def handle_starttag(self, tag, attrs):
|
|
Packit Service |
39273c |
if tag == "html:ul":
|
|
Packit Service |
39273c |
self.content += "\n"
|
|
Packit Service |
39273c |
elif tag == "html:li":
|
|
Packit Service |
39273c |
self.content += "\n"
|
|
Packit Service |
39273c |
elif tag == "html:br":
|
|
Packit Service |
39273c |
self.content += "\n"
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def handle_endtag(self, tag):
|
|
Packit Service |
39273c |
if tag == "html:ul":
|
|
Packit Service |
39273c |
self.content += "\n"
|
|
Packit Service |
39273c |
elif tag == "html:li":
|
|
Packit Service |
39273c |
self.content += "\n"
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def handle_data(self, data):
|
|
Packit Service |
39273c |
self.content += data.strip()
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_content(self):
|
|
Packit Service |
39273c |
return self.content
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def parse_HTML_from_content(content):
|
|
Packit Service |
39273c |
"""This is a very simple HTML to text parser.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
HTML tags will be removed while trying to maintain readability
|
|
Packit Service |
39273c |
of content.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param content: content whose HTML tags will be parsed
|
|
Packit Service |
39273c |
:return: content without HTML tags
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
parser = ParseHTMLContent()
|
|
Packit Service |
39273c |
parser.feed(content)
|
|
Packit Service |
39273c |
return parser.get_content()
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# namedtuple class (not a constant, pylint!) for info about a XCCDF profile
|
|
Packit Service |
39273c |
# pylint: disable-msg=C0103
|
|
Packit Service |
39273c |
ProfileInfo = namedtuple("ProfileInfo", ["id", "title", "description"])
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# namedtuple class for info about content files found
|
|
Packit Service |
39273c |
# pylint: disable-msg=C0103
|
|
Packit Service |
39273c |
ContentFiles = namedtuple("ContentFiles", ["xccdf", "cpe", "tailoring"])
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def oscap_text_itr_get_text(itr):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Helper function for getting a text from the oscap_text_iterator.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param itr: oscap_text_iterator to get the text from
|
|
Packit Service |
39273c |
:type itr: oscap_text_iterator
|
|
Packit Service |
39273c |
:return: text gotten from the iterator
|
|
Packit Service |
39273c |
:rtype: str
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
ret = ""
|
|
Packit Service |
39273c |
while OSCAP.oscap_text_iterator_has_more(itr):
|
|
Packit Service |
39273c |
text_item = OSCAP.oscap_text_iterator_next(itr)
|
|
Packit Service |
39273c |
ret += OSCAP.oscap_text_get_text(text_item)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return ret
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def explore_content_files(fpaths):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Function for finding content files in a list of file paths. SIMPLY PICKS
|
|
Packit Service |
39273c |
THE FIRST USABLE CONTENT FILE OF A PARTICULAR TYPE AND JUST PREFERS DATA
|
|
Packit Service |
39273c |
STREAMS OVER STANDALONE BENCHMARKS.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param fpaths: a list of file paths to search for content files in
|
|
Packit Service |
39273c |
:type fpaths: [str]
|
|
Packit Service |
39273c |
:return: a tuple containing the content handling class and an ContentFiles
|
|
Packit Service |
39273c |
instance containing the file names of the XCCDF file, CPE
|
|
Packit Service |
39273c |
dictionary and tailoring file or "" in place of those items if not
|
|
Packit Service |
39273c |
found
|
|
Packit Service |
39273c |
:rtype: (class, ContentFiles)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_doc_type(file_path):
|
|
Packit Service |
39273c |
try:
|
|
Packit Service |
39273c |
for line in execReadlines("oscap", ["info", file_path]):
|
|
Packit Service |
39273c |
if line.startswith("Document type:"):
|
|
Packit Service |
39273c |
_prefix, _sep, type_info = line.partition(":")
|
|
Packit Service |
39273c |
return type_info.strip()
|
|
Packit Service |
39273c |
except OSError:
|
|
Packit Service |
39273c |
# 'oscap info' exitted with a non-zero exit code -> unknown doc
|
|
Packit Service |
39273c |
# type
|
|
Packit Service |
39273c |
return None
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
xccdf_file = ""
|
|
Packit Service |
39273c |
cpe_file = ""
|
|
Packit Service |
39273c |
tailoring_file = ""
|
|
Packit Service |
39273c |
found_ds = False
|
|
Packit Service |
39273c |
content_class = None
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
for fpath in fpaths:
|
|
Packit Service |
39273c |
doc_type = get_doc_type(fpath)
|
|
Packit Service |
39273c |
if not doc_type:
|
|
Packit Service |
39273c |
continue
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# prefer DS over standalone XCCDF
|
|
Packit Service |
39273c |
if doc_type == "Source Data Stream" and (not xccdf_file or not found_ds):
|
|
Packit Service |
39273c |
xccdf_file = fpath
|
|
Packit Service |
39273c |
content_class = DataStreamHandler
|
|
Packit Service |
39273c |
found_ds = True
|
|
Packit Service |
39273c |
elif doc_type == "XCCDF Checklist" and not xccdf_file:
|
|
Packit Service |
39273c |
xccdf_file = fpath
|
|
Packit Service |
39273c |
content_class = BenchmarkHandler
|
|
Packit Service |
39273c |
elif doc_type == "CPE Dictionary" and not cpe_file:
|
|
Packit Service |
39273c |
cpe_file = fpath
|
|
Packit Service |
39273c |
elif doc_type == "XCCDF Tailoring" and not tailoring_file:
|
|
Packit Service |
39273c |
tailoring_file = fpath
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# TODO: raise exception if no xccdf_file is found?
|
|
Packit Service |
39273c |
files = ContentFiles(xccdf_file, cpe_file, tailoring_file)
|
|
Packit Service |
39273c |
return (content_class, files)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class DataStreamHandler(object):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Class for handling data streams in the data stream collection and
|
|
Packit Service |
39273c |
retrieving data from it. For example a list of data stream indices,
|
|
Packit Service |
39273c |
checklists in a given data stream of profiles.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def __init__(self, dsc_file_path, tailoring_file_path=""):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Constructor for the DataStreamHandler class.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param dsc_file_path: path to a file with a data stream collection
|
|
Packit Service |
39273c |
:type dsc_file_path: str
|
|
Packit Service |
39273c |
:param tailoring_file_path: path to a tailoring file
|
|
Packit Service |
39273c |
:type tailoring_file_path: str
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# is used to speed up getting lists of profiles
|
|
Packit Service |
39273c |
self._profiles_cache = dict()
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if not os.path.exists(dsc_file_path):
|
|
Packit Service |
39273c |
msg = "Invalid file path: '%s'" % dsc_file_path
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
self._dsc_file_path = dsc_file_path
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# create an XCCDF session for the file
|
|
Packit Service |
39273c |
self._session = OSCAP.xccdf_session_new(dsc_file_path)
|
|
Packit Service |
39273c |
if not self._session:
|
|
Packit Service |
39273c |
msg = "'%s' is not a valid SCAP content file" % dsc_file_path
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(msg)
|
|
Packit Service |
39273c |
if OSCAP.xccdf_session_load(self._session) != 0:
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(OSCAP.oscap_err_desc())
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if tailoring_file_path:
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_set_user_tailoring_file(self._session,
|
|
Packit Service |
39273c |
tailoring_file_path)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if not OSCAP.xccdf_session_is_sds(self._session):
|
|
Packit Service |
39273c |
msg = "'%s' is not a data stream collection" % dsc_file_path
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# dictionary holding the items gathered from DSC processing
|
|
Packit Service |
39273c |
self._items = OrderedDict()
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# create an sds index for the content
|
|
Packit Service |
39273c |
self._sds_idx = OSCAP.xccdf_session_get_sds_idx(self._session)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# iterate over streams and get checklists from each stream
|
|
Packit Service |
39273c |
streams_itr = OSCAP.ds_sds_index_get_streams(self._sds_idx)
|
|
Packit Service |
39273c |
while OSCAP.ds_stream_index_iterator_has_more(streams_itr):
|
|
Packit Service |
39273c |
stream_idx = OSCAP.ds_stream_index_iterator_next(streams_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# will be used to store the checklists for streams
|
|
Packit Service |
39273c |
stream_id = OSCAP.ds_stream_index_get_id(stream_idx)
|
|
Packit Service |
39273c |
checklists = []
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# iterate over checklists and append their ids to the list
|
|
Packit Service |
39273c |
chklist_itr = OSCAP.ds_stream_index_get_checklists(stream_idx)
|
|
Packit Service |
39273c |
while OSCAP.oscap_string_iterator_has_more(chklist_itr):
|
|
Packit Service |
39273c |
checklists.append(OSCAP.oscap_string_iterator_next(chklist_itr))
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# store the list of checklist for the current stream
|
|
Packit Service |
39273c |
self._items[stream_id] = checklists
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
OSCAP.oscap_string_iterator_free(chklist_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
OSCAP.ds_stream_index_iterator_free(streams_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def __del__(self):
|
|
Packit Service |
39273c |
"""Destructor for the DataStreamHandler class."""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if '_session' in locals():
|
|
Packit Service |
39273c |
# we should free the session
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_free(self._session)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_data_streams(self):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Method to get a list of data streams found in the data stream
|
|
Packit Service |
39273c |
collection.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:return: list of data stream IDs
|
|
Packit Service |
39273c |
:rtype: list of strings
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return list(self._items.keys())
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_data_streams_checklists(self):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Method to get data streams and their checklists found in the data
|
|
Packit Service |
39273c |
stream collection.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:return: a dictionary consisting of the IDs of the data streams as keys
|
|
Packit Service |
39273c |
and lists of their checklists' IDs as values
|
|
Packit Service |
39273c |
:rtype: dict(str -> list of strings)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# easy, we already have exactly what should be returned, just create a
|
|
Packit Service |
39273c |
# copy, so that the caller cannot modify our internal attributes
|
|
Packit Service |
39273c |
return dict(self._items)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_checklists(self, data_stream_id):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Method to get a list of checklists found in the data stream given by
|
|
Packit Service |
39273c |
the data_stream_id.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param data_stream_id: ID of the data stream to get checklists from
|
|
Packit Service |
39273c |
:type data_stream_id: str
|
|
Packit Service |
39273c |
:return: list of checklist IDs found in the data stream given by the ID
|
|
Packit Service |
39273c |
:rtype: list of strings
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if data_stream_id not in self._items:
|
|
Packit Service |
39273c |
msg = "Invalid data stream id given: '%s'" % data_stream_id
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return self._items[data_stream_id]
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def get_profiles(self, data_stream_id, checklist_id):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Method to get a list of profiles defined in the checklist given by the
|
|
Packit Service |
39273c |
checklist_id that is defined in the data stream given by the
|
|
Packit Service |
39273c |
data_stream_id.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param data_stream_id: ID of the data stream to get checklists from
|
|
Packit Service |
39273c |
:type data_stream_id: str
|
|
Packit Service |
39273c |
:param checklist_id: ID of the checklist to get profiles from
|
|
Packit Service |
39273c |
:type checklist_id: str
|
|
Packit Service |
39273c |
:return: list of profiles found in the checklist
|
|
Packit Service |
39273c |
:rtype: list of ProfileInfo instances
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
cache_id = "%s;%s" % (data_stream_id, checklist_id)
|
|
Packit Service |
39273c |
if cache_id in self._profiles_cache:
|
|
Packit Service |
39273c |
# found in cache, return the value
|
|
Packit Service |
39273c |
return self._profiles_cache[cache_id]
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# not found in the cache, needs to be gathered
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# set the data stream and component (checklist) for the session
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_free(self._session)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
self._session = OSCAP.xccdf_session_new(self._dsc_file_path)
|
|
Packit Service |
39273c |
if not self._session:
|
|
Packit Service |
39273c |
msg = "'%s' is not a valid SCAP content file" % self._dsc_file_path
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_set_datastream_id(self._session, data_stream_id)
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_set_component_id(self._session, checklist_id)
|
|
Packit Service |
39273c |
if OSCAP.xccdf_session_load(self._session) != 0:
|
|
Packit Service |
39273c |
raise DataStreamHandlingError(OSCAP.oscap_err_desc())
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# get the benchmark (checklist)
|
|
Packit Service |
39273c |
policy_model = OSCAP.xccdf_session_get_policy_model(self._session)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
default_policy = OSCAP.xccdf_policy_new(policy_model, None)
|
|
Packit Service |
39273c |
default_rules_count = OSCAP.xccdf_policy_get_selected_rules_count(default_policy)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# will hold items for the profiles for the speficied DS and checklist
|
|
Packit Service |
39273c |
profiles = []
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if default_rules_count > 0:
|
|
Packit Service |
39273c |
profiles.append(ProfileInfo("default", "Default",
|
|
Packit Service |
39273c |
"The implicit XCCDF profile. Usually, the default contains no rules."))
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
benchmark = OSCAP.xccdf_policy_model_get_benchmark(policy_model)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# iterate over the profiles in the benchmark and store them
|
|
Packit Service |
39273c |
profile_itr = OSCAP.xccdf_benchmark_get_profiles(benchmark)
|
|
Packit Service |
39273c |
while OSCAP.xccdf_profile_iterator_has_more(profile_itr):
|
|
Packit Service |
39273c |
profile = OSCAP.xccdf_profile_iterator_next(profile_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
id_ = OSCAP.xccdf_profile_get_id(profile)
|
|
Packit Service |
39273c |
title = oscap_text_itr_get_text(OSCAP.xccdf_profile_get_title(profile))
|
|
Packit Service |
39273c |
desc = parse_HTML_from_content(
|
|
Packit Service |
39273c |
oscap_text_itr_get_text(OSCAP.xccdf_profile_get_description(profile)))
|
|
Packit Service |
39273c |
info = ProfileInfo(id_, title, desc)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
profiles.append(info)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
OSCAP.xccdf_profile_iterator_free(profile_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# cache the result
|
|
Packit Service |
39273c |
self._profiles_cache[cache_id] = profiles
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return profiles
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
class BenchmarkHandler(object):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Class for handling XCCDF benchmark and retrieving data from it (mainly the
|
|
Packit Service |
39273c |
list of profiles).
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
def __init__(self, xccdf_file_path, tailoring_file_path=""):
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
Constructor for the BenchmarkHandler class.
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
:param xccdf_file_path: path to a file with an XCCDF benchmark
|
|
Packit Service |
39273c |
:type xccdf_file_path: str
|
|
Packit Service |
39273c |
:param tailoring_file_path: path to a tailoring file
|
|
Packit Service |
39273c |
:type tailoring_file_path: str
|
|
Packit Service |
39273c |
"""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if not os.path.exists(xccdf_file_path):
|
|
Packit Service |
39273c |
msg = "Invalid file path: '%s'" % xccdf_file_path
|
|
Packit Service |
39273c |
raise BenchmarkHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
session = OSCAP.xccdf_session_new(xccdf_file_path)
|
|
Packit Service |
39273c |
if not session:
|
|
Packit Service |
39273c |
msg = "'%s' is not a valid SCAP content file" % xccdf_file_path
|
|
Packit Service |
39273c |
raise BenchmarkHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if tailoring_file_path:
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_set_user_tailoring_file(session,
|
|
Packit Service |
39273c |
tailoring_file_path)
|
|
Packit Service |
39273c |
if OSCAP.xccdf_session_load(session) != 0:
|
|
Packit Service |
39273c |
raise BenchmarkHandlingError(OSCAP.oscap_err_desc())
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# get the benchmark object
|
|
Packit Service |
39273c |
policy_model = OSCAP.xccdf_session_get_policy_model(session)
|
|
Packit Service |
39273c |
benchmark = OSCAP.xccdf_policy_model_get_benchmark(policy_model)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
default_policy = OSCAP.xccdf_policy_new(policy_model, None)
|
|
Packit Service |
39273c |
default_rules_count = OSCAP.xccdf_policy_get_selected_rules_count(default_policy)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# stores a list of profiles in the benchmark
|
|
Packit Service |
39273c |
self._profiles = []
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if default_rules_count > 0:
|
|
Packit Service |
39273c |
self._profiles.append(
|
|
Packit Service |
39273c |
ProfileInfo(
|
|
Packit Service |
39273c |
"default", "Default",
|
|
Packit Service |
39273c |
"The implicit XCCDF profile. Usually, the default contains no rules."))
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if not benchmark:
|
|
Packit Service |
39273c |
msg = "Not a valid benchmark file: '%s'" % xccdf_file_path
|
|
Packit Service |
39273c |
raise BenchmarkHandlingError(msg)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
# iterate over the profiles in the benchmark and store them
|
|
Packit Service |
39273c |
profile_itr = OSCAP.xccdf_benchmark_get_profiles(benchmark)
|
|
Packit Service |
39273c |
while OSCAP.xccdf_profile_iterator_has_more(profile_itr):
|
|
Packit Service |
39273c |
profile = OSCAP.xccdf_profile_iterator_next(profile_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
id_ = OSCAP.xccdf_profile_get_id(profile)
|
|
Packit Service |
39273c |
title = oscap_text_itr_get_text(OSCAP.xccdf_profile_get_title(profile))
|
|
Packit Service |
39273c |
desc = parse_HTML_from_content(oscap_text_itr_get_text(OSCAP.xccdf_profile_get_description(profile)))
|
|
Packit Service |
39273c |
info = ProfileInfo(id_, title, desc)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
self._profiles.append(info)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
if tailoring_file_path:
|
|
Packit Service |
39273c |
tailoring = OSCAP.xccdf_policy_model_get_tailoring(policy_model)
|
|
Packit Service |
39273c |
profile_itr = OSCAP.xccdf_tailoring_get_profiles(tailoring)
|
|
Packit Service |
39273c |
while OSCAP.xccdf_profile_iterator_has_more(profile_itr):
|
|
Packit Service |
39273c |
profile = OSCAP.xccdf_profile_iterator_next(profile_itr)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
id_ = OSCAP.xccdf_profile_get_id(profile)
|
|
Packit Service |
39273c |
title = oscap_text_itr_get_text(OSCAP.xccdf_profile_get_title(profile))
|
|
Packit Service |
39273c |
desc = parse_HTML_from_content(oscap_text_itr_get_text(OSCAP.xccdf_profile_get_description(profile)))
|
|
Packit Service |
39273c |
info = ProfileInfo(id_, title, desc)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
self._profiles.append(info)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
OSCAP.xccdf_profile_iterator_free(profile_itr)
|
|
Packit Service |
39273c |
OSCAP.xccdf_session_free(session)
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
@property
|
|
Packit Service |
39273c |
def profiles(self):
|
|
Packit Service |
39273c |
"""Property for the list of profiles defined in the benchmark."""
|
|
Packit Service |
39273c |
|
|
Packit Service |
39273c |
return self._profiles
|