File: test_build_cpe.py

package info (click to toggle)
scap-security-guide 0.1.76-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 110,644 kB
  • sloc: xml: 241,883; sh: 73,777; python: 32,527; makefile: 27
file content (155 lines) | stat: -rw-r--r-- 5,584 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import pytest

import os
import re
import ssg.build_cpe
import ssg.xml
from ssg.yaml import open_raw

ET = ssg.xml.ElementTree
DATADIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "data"))


def test_extract_element():
    obj = """<?xml version="1.0"?>
    <variables>
        <var>
            <subelement>
                <random id="test">This</random>
            </subelement>
        </var>
        <var>
            <subelement>
                <random random="not-me">That</random>
            </subelement>
        </var>
    </variables>
    """
    tree = ET.fromstring(obj)

    assert ssg.build_cpe.extract_subelement(tree, 'id') == 'test'
    assert ssg.build_cpe.extract_subelement(tree, 'random') == 'not-me'
    assert ssg.build_cpe.extract_subelement(tree, 'missing') is None
    assert ssg.build_cpe.extract_subelement(tree, 'subelement') is None


def test_extract_env_obj():
    local_var_text = """
    <var>
        <subelement>
            <random object_ref="magical">elements</random>
        </subelement>
    </var>
    """
    local_var = ET.fromstring(local_var_text)

    local_var_missing_text = """
    <var>
        <subelement>
            <random object_ref="nothing">here</random>
        </subelement>
    </var>
    """
    local_var_missing = ET.fromstring(local_var_missing_text)

    objects_text = """
    <objects>
        <object id="something">something</object>
        <object id="magical">magical</object>
        <object id="here">here</object>
    </objects>
    """
    objects = ET.fromstring(objects_text)

    present = ssg.build_cpe.extract_env_obj(objects, local_var)
    assert present is not None
    assert present.text == 'magical'

    missing = ssg.build_cpe.extract_env_obj(objects, local_var_missing)
    assert missing is None


def test_extract_referred_nodes():
    tree_with_refs_text = """
    <references>
        <reference object_ref="something_borrowed" />
        <reference object_ref="something_missing" />
    </references>
    """
    tree_with_refs = ET.fromstring(tree_with_refs_text)

    tree_with_ids_text = """
    <objects>
        <object id="something_old">Brno</object>
        <object id="something_new">Boston</object>
        <object id="something_borrowed">Source Code</object>
        <object id="something_blue">Fedora</object>
    </objects>
    """
    tree_with_ids = ET.fromstring(tree_with_ids_text)

    results = ssg.build_cpe.extract_referred_nodes(tree_with_refs, tree_with_ids, 'object_ref')

    assert len(results) == 1
    assert results[0].text == 'Source Code'


#############################################
# Unit tests for ProductCPEs.get_cpe() method
#############################################
#
# Note that there are 2 types of CPE definitions that differ by the source they
# come from:
# * Product CPEs, loaded from product YAML
# * Content CPEs, loaded from directory specified by the `cpes_root` key in
#   product YML, usually from the `/applicability` directory
#
# This test case test that both types are used by the ProductCPEs class and
# that both CPE types are handled equally.
def test_product_cpes():

    # CPEs are loaded from `DATADIR/product.yml` but also from
    # `DATADIR/applicability` because `DATADIR/product.yml` references the
    # `DATADIR/applicability` directory in the `cpes_root` key
    product_yaml_path = os.path.join(DATADIR, "product.yml")
    product_yaml = open_raw(product_yaml_path)
    product_yaml["product_dir"] = os.path.dirname(product_yaml_path)
    product_cpes = ssg.build_cpe.ProductCPEs()
    product_cpes.load_product_cpes(product_yaml)
    product_cpes.load_content_cpes(product_yaml)

    # get a product CPE by name and verify it's loaded
    # this CPE is defined in `DATADIR/product.yml`
    rhel9_cpe = product_cpes.get_cpe("rhel9")
    assert(rhel9_cpe.name == "cpe:/o:redhat:enterprise_linux:9")
    assert(rhel9_cpe.title == "Red Hat Enterprise Linux 9")
    assert(rhel9_cpe.check_id == "installed_OS_is_rhel9")
    assert(rhel9_cpe.bash_conditional == "")
    assert(rhel9_cpe.ansible_conditional == "")

    # get CPE by ID and verify it's loaded, the get_cpe method should return
    # the same object as when CPE name was used above
    rhel9_cpe_2 = product_cpes.get_cpe("cpe:/o:redhat:enterprise_linux:9")
    assert(rhel9_cpe_2.name == rhel9_cpe.name)
    assert(rhel9_cpe_2.title == rhel9_cpe.title)
    assert(rhel9_cpe_2.check_id == rhel9_cpe.check_id)
    assert(rhel9_cpe_2.bash_conditional == rhel9_cpe.bash_conditional)
    assert(rhel9_cpe_2.ansible_conditional == rhel9_cpe.ansible_conditional)

    # get a content CPE by name and verify it's loaded
    # this CPE is defined in `DATADIR/applicability/virtualization.yml`
    cpe1 = product_cpes.get_cpe("machine")
    assert(cpe1.name == "cpe:/a:machine")
    assert(cpe1.title == "Bare-metal or Virtual Machine")
    assert(cpe1.check_id == "installed_env_is_a_machine")
    assert(cpe1.ansible_conditional == "ansible_virtualization_type not in [\"docker\", \"lxc\", \"openvz\", \"podman\", \"container\"]")
    assert(cpe1.bash_conditional == "[ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ]")

    # get CPE by ID and verify it's loaded, the get_cpe method should return
    # the same object as when CPE name was used above
    cpe2 = product_cpes.get_cpe("cpe:/a:machine")
    assert(cpe2.name == cpe1.name)
    assert(cpe2.title == cpe1.title)
    assert(cpe2.check_id == cpe1.check_id)
    assert(cpe2.ansible_conditional == cpe1.ansible_conditional)
    assert(cpe2.bash_conditional == cpe1.bash_conditional)