test_kickstart.test_no_profile()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 19
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nop 1
dl 0
loc 19
rs 10
c 0
b 0
f 0
1
#
2
# Copyright (C) 2021  Red Hat, Inc.
3
#
4
# This copyrighted material is made available to anyone wishing to use,
5
# modify, copy, or redistribute it subject to the terms and conditions of
6
# the GNU General Public License v.2, or (at your option) any later version.
7
# This program is distributed in the hope that it will be useful, but WITHOUT
8
# ANY WARRANTY expressed or implied, including the implied warranties of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
10
# Public License for more details.  You should have received a copy of the
11
# GNU General Public License along with this program; if not, write to the
12
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
13
# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
14
# source code or documentation are not subject to the GNU General Public
15
# License and may only be used or replicated with the express permission of
16
# Red Hat, Inc.
17
#
18
import pytest
19
from textwrap import dedent
20
from unittest.mock import Mock
21
from org_fedora_oscap.service.oscap import OSCAPService
22
23
24
ADDON_NAME = "org_fedora_oscap"
25
26
27
@pytest.fixture()
28
def service():
29
    return OSCAPService()
30
31
32
@pytest.fixture()
33
def mock_ssg_available(monkeypatch):
34
    mocked_function = Mock(return_value=True)
35
    monkeypatch.setattr("org_fedora_oscap.common.ssg_available", mocked_function)
36
    return mocked_function
37
38
39
def check_ks_input(ks_service, ks_in, errors=None, warnings=None):
40
    """Read a provided kickstart string.
41
42
    :param ks_service: the kickstart service
43
    :param ks_in: a kickstart string
44
    :param errors: a list of expected errors
45
    :param warnings: a list of expected warning
46
    """
47
    errors = errors or []
48
    warnings = warnings or []
49
    report = ks_service.read_kickstart(ks_in)
50
51
    for index, error in enumerate(report.error_messages):
52
        assert errors[index] in error.message
53
54
    for index, warning in enumerate(report.warning_messages):
55
        assert warnings[index] in warning.message
56
57
58
def check_ks_output(ks_service, ks_out):
59
    """Generate a new kickstart string.
60
61
    :param ks_service: a kickstart service
62
    :param ks_out: an expected kickstart string
63
    """
64
    output = ks_service.generate_kickstart()
65
    assert output.strip() == dedent(ks_out).strip()
66
67
68
def test_default(service):
69
    check_ks_output(service, "")
70
71
72
def test_data(service):
73
    ks_in = f"""
74
    %addon {ADDON_NAME}
75
        content-type = datastream
76
        content-url = "https://example.com/hardening.xml"
77
    %end
78
    """
79
    check_ks_input(service, ks_in)
80
81
    assert service.policy_data.content_type == "datastream"
82
    assert service.policy_data.content_url == "https://example.com/hardening.xml"
83
84
85
def test_datastream(service):
86
    ks_in = f"""
87
    %addon {ADDON_NAME}
88
        content-type = datastream
89
        content-url = "https://example.com/hardening.xml"
90
        datastream-id = id_datastream_1
91
        xccdf-id = id_xccdf_new
92
        content-path = /usr/share/oscap/testing_ds.xml
93
        cpe-path = /usr/share/oscap/cpe.xml
94
        tailoring-path = /usr/share/oscap/tailoring.xml
95
        profile = "Web Server"
96
    %end
97
    """
98
    check_ks_input(service, ks_in)
99
100
    ks_out = f"""
101
    %addon {ADDON_NAME}
102
        content-type = datastream
103
        content-url = https://example.com/hardening.xml
104
        datastream-id = id_datastream_1
105
        xccdf-id = id_xccdf_new
106
        content-path = /usr/share/oscap/testing_ds.xml
107
        cpe-path = /usr/share/oscap/cpe.xml
108
        tailoring-path = /usr/share/oscap/tailoring.xml
109
        profile = Web Server
110
    %end
111
    """
112
    check_ks_output(service, ks_out)
113
114
115
def test_no_content_type(service):
116
    ks_in = f"""
117
    %addon {ADDON_NAME}
118
        content-url = http://example.com/test_ds.xml
119
        profile = Web Server
120
    %end
121
    """
122
    check_ks_input(service, ks_in, errors=[
123
        f"content-type missing for the {ADDON_NAME} addon"
124
    ])
125
126
127
def test_no_content_url(service):
128
    ks_in = f"""
129
    %addon {ADDON_NAME}
130
        content-type = datastream
131
        profile = Web Server
132
    %end
133
    """
134
    check_ks_input(service, ks_in, errors=[
135
        f"content-url missing for the {ADDON_NAME} addon"
136
    ])
137
138
139
def test_no_profile(service):
140
    ks_in = f"""
141
    %addon {ADDON_NAME}
142
        content-url = http://example.com/test_ds.xml
143
        content-type = datastream
144
    %end
145
    """
146
    check_ks_input(service, ks_in)
147
148
    ks_out = f"""
149
    %addon {ADDON_NAME}
150
        content-type = datastream
151
        content-url = http://example.com/test_ds.xml
152
        profile = default
153
    %end
154
    """
155
    check_ks_output(service, ks_out)
156
157
    assert service.policy_data.profile_id == "default"
158
159
160
def test_rpm(service):
161
    ks_in = f"""
162
    %addon {ADDON_NAME}
163
        content-url = http://example.com/oscap_content.rpm
164
        content-type = RPM
165
        profile = Web Server
166
        xccdf-path = /usr/share/oscap/xccdf.xml
167
    %end
168
    """
169
    check_ks_input(service, ks_in)
170
171
    ks_out = f"""
172
    %addon {ADDON_NAME}
173
        content-type = rpm
174
        content-url = http://example.com/oscap_content.rpm
175
        content-path = /usr/share/oscap/xccdf.xml
176
        profile = Web Server
177
    %end
178
    """
179
    check_ks_output(service, ks_out)
180
181
182
def test_rpm_without_path(service):
183
    ks_in = f"""
184
    %addon {ADDON_NAME}
185
        content-url = http://example.com/oscap_content.rpm
186
        content-type = RPM
187
        profile = Web Server
188
    %end
189
    """
190
    check_ks_input(service, ks_in, errors=[
191
        "Path to the XCCDF file has to be given if content in RPM or archive is used"
192
    ])
193
194
195
def test_rpm_with_wrong_suffix(service):
196
    ks_in = f"""
197
    %addon {ADDON_NAME}
198
        content-url = http://example.com/oscap_content.xml
199
        content-type = RPM
200
        profile = Web Server
201
        xccdf-path = /usr/share/oscap/xccdf.xml
202
    %end
203
    """
204
    check_ks_input(service, ks_in, errors=[
205
        "Content type set to RPM, but the content URL doesn't end with '.rpm'"
206
    ])
207
208
209
def test_archive(service):
210
    ks_in = f"""
211
    %addon {ADDON_NAME}
212
        content-url = http://example.com/oscap_content.tar
213
        content-type = archive
214
        profile = Web Server
215
        xccdf-path = oscap/xccdf.xml
216
    %end
217
    """
218
    check_ks_input(service, ks_in)
219
220
    ks_out = f"""
221
    %addon {ADDON_NAME}
222
        content-type = archive
223
        content-url = http://example.com/oscap_content.tar
224
        content-path = oscap/xccdf.xml
225
        profile = Web Server
226
    %end
227
    """
228
    check_ks_output(service, ks_out)
229
230
231
def test_archive_without_path(service):
232
    ks_in = f"""
233
    %addon {ADDON_NAME}
234
        content-url = http://example.com/oscap_content.tar
235
        content-type = archive
236
        profile = Web Server
237
    %end
238
    """
239
    check_ks_input(service, ks_in, errors=[
240
        "Path to the XCCDF file has to be given if content in RPM or archive is used"
241
    ])
242
243
244
def test_org_fedora_oscap(service):
245
    ks_in = """
246
    %addon org_fedora_oscap
247
        content-type = datastream
248
        content-url = "https://example.com/hardening.xml"
249
    %end
250
    """
251
    check_ks_input(service, ks_in, warnings=[
252
        "org_fedora_oscap"
253
    ])
254
255
256
def test_section_confusion(service):
257
    ks_in = """
258
    %addon org_fedora_oscap
259
        content-type = datastream
260
        content-url = "https://example.com/hardening.xml"
261
    %end
262
263
    %addon com_redhat_oscap
264
        content-type = datastream
265
        content-url = "https://example.com/hardening.xml"
266
    %end
267
    """
268
    check_ks_input(service, ks_in, errors=[
269
        "You have used more than one oscap addon sections in the kickstart."
270
    ])
271
272
273
def test_scap_security_guide(service, mock_ssg_available):
274
    ks_in = f"""
275
    %addon {ADDON_NAME}
276
        content-type = scap-security-guide
277
        profile = Web Server
278
    %end
279
    """
280
281
    mock_ssg_available.return_value = False
282
    check_ks_input(service, ks_in, errors=[
283
        "SCAP Security Guide not found on the system"
284
    ])
285
286
    ks_out = f"""
287
    %addon {ADDON_NAME}
288
        content-type = scap-security-guide
289
        profile = Web Server
290
    %end
291
    """
292
293
    mock_ssg_available.return_value = True
294
    check_ks_input(service, ks_in, ks_out)
295
296
297
def test_fingerprints(service):
298
    ks_template = f"""
299
    %addon {ADDON_NAME}
300
        content-url = http://example.com/test_ds.xml
301
        content-type = datastream
302
        fingerprint = {{}}
303
    %end
304
    """
305
306
    # invalid character
307
    ks_in = ks_template.format("a" * 31 + "?")
308
    check_ks_input(service, ks_in, errors=[
309
        "Unsupported or invalid fingerprint"
310
    ])
311
312
    # invalid lengths (odd and even)
313
    for repetitions in (31, 41, 54, 66, 98, 124):
314
        ks_in = ks_template.format("a" * repetitions)
315
        check_ks_input(service, ks_in, errors=[
316
            "Unsupported fingerprint"
317
        ])
318
319
    # valid values
320
    for repetitions in (32, 40, 56, 64, 96, 128):
321
        ks_in = ks_template.format("a" * repetitions)
322
        check_ks_input(service, ks_in)
323