Fix a broken HTTP link, add CIS profile based on RHEL8 CIS, fix its Crypto Policy usage

Resolves: rhbz#1962564
This commit is contained in:
Matej Tyc 2021-08-24 17:14:29 +02:00
parent c9032c1d61
commit bd64402d52
6 changed files with 8079 additions and 1 deletions

View File

@ -0,0 +1,702 @@
From 7901659fa169db8ac5ffd7c610a798c785a3556b Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Fri, 9 Jul 2021 14:41:03 +0200
Subject: [PATCH 01/12] ensure that higher policy levels can override variables
of lower levels
---
ssg/controls.py | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 297d80e46c5..165cdf0511a 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -202,9 +202,16 @@ def get_all_controls_of_level(self, policy_id, level_id):
all_policy_controls = self.get_all_controls(policy_id)
eligible_controls = []
- for c in all_policy_controls:
- if len(level_ids.intersection(c.levels)) > 0:
- eligible_controls.append(c)
+ defined_variables = []
+ # we will go level by level, from top to bottom
+ # this is done to enable overriding of variables by higher levels
+ for lv in level_ids:
+ for c in all_policy_controls:
+ if lv in c.levels:
+ # if the control has a variable, check if it is not already defined
+ if c.variables.keys().isdisjoint(defined_variables):
+ eligible_controls.append(c)
+ defined_variables += [*c.variables.keys()]
return eligible_controls
def get_all_controls(self, policy_id):
From 66e612a9668009cc553fcf1abbf2c9477155c0c2 Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Thu, 5 Aug 2021 14:02:25 +0200
Subject: [PATCH 02/12] use ordered sets emulated by ordereddict
because of compatibility with python2
---
ssg/controls.py | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 165cdf0511a..611a647e125 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -2,6 +2,7 @@
import logging
import os
from glob import glob
+from collections import OrderedDict
import ssg.build_yaml
import ssg.yaml
@@ -152,16 +153,18 @@ def get_level(self, level_id):
raise ValueError(msg)
def get_level_with_ancestors(self, level_id):
- levels = set()
+ # use OrderedDict for Python2 compatibility instead of ordered set
+ levels = OrderedDict()
level = self.get_level(level_id)
- levels.add(level)
+ levels[level] = ""
if level.inherits_from:
for lv in level.inherits_from:
- levels.update(self.get_level_with_ancestors(lv))
+ eligible_levels = [l for l in self.get_level_with_ancestors(lv).keys() if l not in levels.keys()]
+ for l in eligible_levels:
+ levels[l] = ""
return levels
-
class ControlsManager():
def __init__(self, controls_dir, env_yaml=None):
self.controls_dir = os.path.abspath(controls_dir)
@@ -198,20 +201,24 @@ def _get_policy(self, policy_id):
def get_all_controls_of_level(self, policy_id, level_id):
policy = self._get_policy(policy_id)
levels = policy.get_level_with_ancestors(level_id)
- level_ids = set([lv.id for lv in levels])
+ # we use OrderedDict here with empty values instead of ordered set
+ # cause we want to be compatible with python 2
+ level_ids = OrderedDict()
+ for lv in levels.keys():
+ level_ids[lv.id] = ""
all_policy_controls = self.get_all_controls(policy_id)
eligible_controls = []
defined_variables = []
# we will go level by level, from top to bottom
# this is done to enable overriding of variables by higher levels
- for lv in level_ids:
+ for lv in level_ids.keys():
for c in all_policy_controls:
if lv in c.levels:
# if the control has a variable, check if it is not already defined
if c.variables.keys().isdisjoint(defined_variables):
eligible_controls.append(c)
- defined_variables += [*c.variables.keys()]
+ defined_variables += list(c.variables.keys())
return eligible_controls
def get_all_controls(self, policy_id):
From 95a23a31293a0a63361ddf1831866cd5ae1ab61e Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Thu, 5 Aug 2021 16:30:10 +0200
Subject: [PATCH 03/12] rework handling of variables when returning all
controls of a level
currently only the top most level variables are kept in the controls
if there is a control with lower level which has the same variable defined, it is deep copied and the variable definition is removed only from the resulting control
the original control stays in tact
---
ssg/controls.py | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 611a647e125..4ebb8bda3d7 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -1,8 +1,8 @@
import collections
import logging
import os
+import copy
from glob import glob
-from collections import OrderedDict
import ssg.build_yaml
import ssg.yaml
@@ -154,7 +154,7 @@ def get_level(self, level_id):
def get_level_with_ancestors(self, level_id):
# use OrderedDict for Python2 compatibility instead of ordered set
- levels = OrderedDict()
+ levels = collections.OrderedDict()
level = self.get_level(level_id)
levels[level] = ""
if level.inherits_from:
@@ -201,24 +201,39 @@ def _get_policy(self, policy_id):
def get_all_controls_of_level(self, policy_id, level_id):
policy = self._get_policy(policy_id)
levels = policy.get_level_with_ancestors(level_id)
+ print ("getting levels of " + level_id)
+ print ([ l.id for l in levels.keys()])
# we use OrderedDict here with empty values instead of ordered set
# cause we want to be compatible with python 2
- level_ids = OrderedDict()
+ level_ids = collections.OrderedDict()
for lv in levels.keys():
level_ids[lv.id] = ""
-
+ print (level_ids.keys())
all_policy_controls = self.get_all_controls(policy_id)
eligible_controls = []
defined_variables = []
# we will go level by level, from top to bottom
# this is done to enable overriding of variables by higher levels
for lv in level_ids.keys():
+ print ("going through level " +lv)
for c in all_policy_controls:
+ print (c.levels)
if lv in c.levels:
# if the control has a variable, check if it is not already defined
- if c.variables.keys().isdisjoint(defined_variables):
+ variables = list(c.variables.keys())
+ if len(variables) == 0:
eligible_controls.append(c)
- defined_variables += list(c.variables.keys())
+ for var in variables:
+ if var in defined_variables:
+ # if it is, create new instance of the control and remove the variable
+ # we are going from the top level to the bottom
+ # so we don't want to overwrite variables
+ new_c = copy.deepcopy(c)
+ del new_c.variables[var]
+ eligible_controls.append(new_c)
+ else:
+ defined_variables.append(var)
+ eligible_controls.append(c)
return eligible_controls
def get_all_controls(self, policy_id):
From a2dd7e9386c757a523b57646bdc5a9ffa99f68c5 Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Thu, 5 Aug 2021 16:31:25 +0200
Subject: [PATCH 04/12] add tests for defining of variables
---
tests/unit/ssg-module/data/controls_dir/abcd-levels.yml | 6 ++++++
tests/unit/ssg-module/test_controls.py | 5 +++++
2 files changed, 11 insertions(+)
diff --git a/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml b/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
index aded77c12a6..b98a7cd4e19 100644
--- a/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
+++ b/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
@@ -19,10 +19,14 @@ controls:
- id: S2
levels:
- low
+ rules:
+ - var_password_pam_minlen=1
- id: S3
levels:
- medium
+ rules:
+ - var_password_pam_minlen=2
- id: S4
title: Configure authentication
@@ -36,3 +40,5 @@ controls:
title: Enforce password quality standards
levels:
- high
+ rules:
+ - var_password_pam_minlen=3
diff --git a/tests/unit/ssg-module/test_controls.py b/tests/unit/ssg-module/test_controls.py
index ff9b04f26c9..06fcb0c375d 100644
--- a/tests/unit/ssg-module/test_controls.py
+++ b/tests/unit/ssg-module/test_controls.py
@@ -87,6 +87,11 @@ def test_controls_levels():
assert len(low_controls) == 4
assert len(medium_controls) == 5
+ # test overriding of variables in levels
+ assert c_2.variables["var_password_pam_minlen"] == "1"
+ assert c_3.variables["var_password_pam_minlen"] == "2"
+ assert c_4b.variables["var_password_pam_minlen"] == "3"
+
def test_controls_load_product():
ssg_root = \
From 82b90a9720dadab7d6060f0ccbcd902b1c097904 Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Fri, 6 Aug 2021 09:30:47 +0200
Subject: [PATCH 05/12] make overriding of variables optional
---
ssg/controls.py | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 4ebb8bda3d7..90639fbe4c7 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -198,42 +198,42 @@ def _get_policy(self, policy_id):
raise ValueError(msg)
return policy
- def get_all_controls_of_level(self, policy_id, level_id):
+ def get_all_controls_of_level(self, policy_id, level_id, override_vars=True):
+ # if override_vars is enabled, then variables from higher levels will
+ # override variables efined in controls of lower levels
policy = self._get_policy(policy_id)
levels = policy.get_level_with_ancestors(level_id)
- print ("getting levels of " + level_id)
- print ([ l.id for l in levels.keys()])
# we use OrderedDict here with empty values instead of ordered set
# cause we want to be compatible with python 2
level_ids = collections.OrderedDict()
for lv in levels.keys():
level_ids[lv.id] = ""
- print (level_ids.keys())
all_policy_controls = self.get_all_controls(policy_id)
eligible_controls = []
defined_variables = []
# we will go level by level, from top to bottom
# this is done to enable overriding of variables by higher levels
for lv in level_ids.keys():
- print ("going through level " +lv)
for c in all_policy_controls:
- print (c.levels)
if lv in c.levels:
- # if the control has a variable, check if it is not already defined
- variables = list(c.variables.keys())
- if len(variables) == 0:
+ if override_vars == False:
eligible_controls.append(c)
- for var in variables:
- if var in defined_variables:
- # if it is, create new instance of the control and remove the variable
- # we are going from the top level to the bottom
- # so we don't want to overwrite variables
- new_c = copy.deepcopy(c)
- del new_c.variables[var]
- eligible_controls.append(new_c)
- else:
- defined_variables.append(var)
+ else:
+ # if the control has a variable, check if it is not already defined
+ variables = list(c.variables.keys())
+ if len(variables) == 0:
eligible_controls.append(c)
+ for var in variables:
+ if var in defined_variables:
+ # if it is, create new instance of the control and remove the variable
+ # we are going from the top level to the bottom
+ # so we don't want to overwrite variables
+ new_c = copy.deepcopy(c)
+ del new_c.variables[var]
+ eligible_controls.append(new_c)
+ else:
+ defined_variables.append(var)
+ eligible_controls.append(c)
return eligible_controls
def get_all_controls(self, policy_id):
From 47df80d086e96deb4eab88d5f813bffb380006a8 Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Wed, 11 Aug 2021 12:38:42 +0200
Subject: [PATCH 06/12] fix a typo
---
ssg/controls.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 90639fbe4c7..10a304bf8c2 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -200,7 +200,7 @@ def _get_policy(self, policy_id):
def get_all_controls_of_level(self, policy_id, level_id, override_vars=True):
# if override_vars is enabled, then variables from higher levels will
- # override variables efined in controls of lower levels
+ # override variables defined in controls of lower levels
policy = self._get_policy(policy_id)
levels = policy.get_level_with_ancestors(level_id)
# we use OrderedDict here with empty values instead of ordered set
From 8e59037ed07aad33a55e8297ee5bce0f51c0dee6 Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Wed, 11 Aug 2021 17:02:11 +0200
Subject: [PATCH 07/12] update tests to check that overriding of variables
works
---
.../ssg-module/data/controls_dir/abcd-levels.yml | 4 +---
tests/unit/ssg-module/test_controls.py | 16 ++++++++++++++--
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml b/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
index b98a7cd4e19..99efafd832e 100644
--- a/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
+++ b/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
@@ -25,8 +25,6 @@ controls:
- id: S3
levels:
- medium
- rules:
- - var_password_pam_minlen=2
- id: S4
title: Configure authentication
@@ -41,4 +39,4 @@ controls:
levels:
- high
rules:
- - var_password_pam_minlen=3
+ - var_password_pam_minlen=2
diff --git a/tests/unit/ssg-module/test_controls.py b/tests/unit/ssg-module/test_controls.py
index 06fcb0c375d..124b344d141 100644
--- a/tests/unit/ssg-module/test_controls.py
+++ b/tests/unit/ssg-module/test_controls.py
@@ -89,8 +89,20 @@ def test_controls_levels():
# test overriding of variables in levels
assert c_2.variables["var_password_pam_minlen"] == "1"
- assert c_3.variables["var_password_pam_minlen"] == "2"
- assert c_4b.variables["var_password_pam_minlen"] == "3"
+ assert "var_password_pam_minlen" not in c_3.variables.keys()
+ assert c_4b.variables["var_password_pam_minlen"] == "2"
+
+ for c in low_controls:
+ if "var_password_pam_minlen" in c.variables.keys():
+ assert c.variables["var_password_pam_minlen"] == "1"
+
+ for c in medium_controls:
+ if "var_password_pam_minlen" in c.variables.keys():
+ assert c.variables["var_password_pam_minlen"] == "1"
+
+ for c in high_controls:
+ if "var_password_pam_minlen" in c.variables.keys():
+ assert c.variables["var_password_pam_minlen"] == "2"
def test_controls_load_product():
From dae4fc52a627eac6595bb73e3ffb1a0c50e78fdd Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Wed, 11 Aug 2021 17:02:32 +0200
Subject: [PATCH 08/12] make overriding of variables hardcoded when requesting
controls of a certain level
---
ssg/controls.py | 34 +++++++++++++++-------------------
1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 10a304bf8c2..7923f0cb379 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -198,9 +198,7 @@ def _get_policy(self, policy_id):
raise ValueError(msg)
return policy
- def get_all_controls_of_level(self, policy_id, level_id, override_vars=True):
- # if override_vars is enabled, then variables from higher levels will
- # override variables defined in controls of lower levels
+ def get_all_controls_of_level(self, policy_id, level_id):
policy = self._get_policy(policy_id)
levels = policy.get_level_with_ancestors(level_id)
# we use OrderedDict here with empty values instead of ordered set
@@ -216,24 +214,22 @@ def get_all_controls_of_level(self, policy_id, level_id, override_vars=True):
for lv in level_ids.keys():
for c in all_policy_controls:
if lv in c.levels:
- if override_vars == False:
+ # if the control has a variable, check if it is not already defined
+ variables = list(c.variables.keys())
+ if len(variables) == 0:
eligible_controls.append(c)
- else:
- # if the control has a variable, check if it is not already defined
- variables = list(c.variables.keys())
- if len(variables) == 0:
+ continue
+ for var in variables:
+ if var in defined_variables:
+ # if it is, create new instance of the control and remove the variable
+ # we are going from the top level to the bottom
+ # so we don't want to overwrite variables
+ new_c = copy.deepcopy(c)
+ del new_c.variables[var]
+ eligible_controls.append(new_c)
+ else:
+ defined_variables.append(var)
eligible_controls.append(c)
- for var in variables:
- if var in defined_variables:
- # if it is, create new instance of the control and remove the variable
- # we are going from the top level to the bottom
- # so we don't want to overwrite variables
- new_c = copy.deepcopy(c)
- del new_c.variables[var]
- eligible_controls.append(new_c)
- else:
- defined_variables.append(var)
- eligible_controls.append(c)
return eligible_controls
def get_all_controls(self, policy_id):
From c051e11c70b7e23ce3d4a8e0670da4fae72833c6 Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Thu, 12 Aug 2021 15:30:39 +0200
Subject: [PATCH 09/12] get rid of one ordereddict
---
ssg/controls.py | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 7923f0cb379..891b13c891c 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -201,19 +201,14 @@ def _get_policy(self, policy_id):
def get_all_controls_of_level(self, policy_id, level_id):
policy = self._get_policy(policy_id)
levels = policy.get_level_with_ancestors(level_id)
- # we use OrderedDict here with empty values instead of ordered set
- # cause we want to be compatible with python 2
- level_ids = collections.OrderedDict()
- for lv in levels.keys():
- level_ids[lv.id] = ""
all_policy_controls = self.get_all_controls(policy_id)
eligible_controls = []
defined_variables = []
# we will go level by level, from top to bottom
# this is done to enable overriding of variables by higher levels
- for lv in level_ids.keys():
+ for lv in levels.keys():
for c in all_policy_controls:
- if lv in c.levels:
+ if lv.id in c.levels:
# if the control has a variable, check if it is not already defined
variables = list(c.variables.keys())
if len(variables) == 0:
From 4dd5cb1326932cf020785a8c2472998eb2e7775e Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Thu, 12 Aug 2021 16:44:57 +0200
Subject: [PATCH 10/12] fix overriding of variables
when there were multiple variables overridden, it caused problems by creating multiple copies of controls
---
ssg/controls.py | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 891b13c891c..8b69676313c 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -214,17 +214,19 @@ def get_all_controls_of_level(self, policy_id, level_id):
if len(variables) == 0:
eligible_controls.append(c)
continue
+ variables_to_remove = [] # contains list of variables which are already defined and should be removed from the control
for var in variables:
if var in defined_variables:
- # if it is, create new instance of the control and remove the variable
- # we are going from the top level to the bottom
- # so we don't want to overwrite variables
- new_c = copy.deepcopy(c)
- del new_c.variables[var]
- eligible_controls.append(new_c)
+ variables_to_remove.append(var)
else:
defined_variables.append(var)
- eligible_controls.append(c)
+ if len(variables_to_remove) == 0:
+ eligible_controls.append(c)
+ else:
+ new_c = copy.deepcopy(c)
+ for var in variables_to_remove:
+ del new_c.variables[var]
+ eligible_controls.append(new_c)
return eligible_controls
def get_all_controls(self, policy_id):
From fbebba524cab090bc4c2f92b75257a7cc881ef5e Mon Sep 17 00:00:00 2001
From: Vojtech Polasek <vpolasek@redhat.com>
Date: Thu, 12 Aug 2021 16:45:38 +0200
Subject: [PATCH 11/12] extended tests to test for multiple overridden
variables
---
.../data/controls_dir/abcd-levels.yml | 2 ++
tests/unit/ssg-module/test_controls.py | 19 +++++++++++++++++++
2 files changed, 21 insertions(+)
diff --git a/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml b/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
index 99efafd832e..2e60ec43532 100644
--- a/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
+++ b/tests/unit/ssg-module/data/controls_dir/abcd-levels.yml
@@ -21,6 +21,7 @@ controls:
- low
rules:
- var_password_pam_minlen=1
+ - var_some_variable=1
- id: S3
levels:
@@ -40,3 +41,4 @@ controls:
- high
rules:
- var_password_pam_minlen=2
+ - var_some_variable=3
diff --git a/tests/unit/ssg-module/test_controls.py b/tests/unit/ssg-module/test_controls.py
index 124b344d141..1465661b04a 100644
--- a/tests/unit/ssg-module/test_controls.py
+++ b/tests/unit/ssg-module/test_controls.py
@@ -104,6 +104,25 @@ def test_controls_levels():
if "var_password_pam_minlen" in c.variables.keys():
assert c.variables["var_password_pam_minlen"] == "2"
+ # now test if controls of lower level has the variable definition correctly removed
+ # because it is overriden by higher level controls
+ s2_high = [c for c in high_controls if c.id == "S2"]
+ assert len(s2_high) == 1
+ assert "var_some_variable" not in s2_high[0].variables.keys()
+ assert "var_password_pam_minlen" not in s2_high[0].variables.keys()
+ s4b_high = [c for c in high_controls if c.id == "S4.b"]
+ assert len(s4b_high) == 1
+ assert s4b_high[0].variables["var_some_variable"] == "3"
+ assert s4b_high[0].variables["var_password_pam_minlen"] == "2"
+
+ # check that in low level the variable is correctly placed there in S2
+ s2_low = [c for c in low_controls if c.id == "S2"]
+ assert len(s2_low) == 1
+ assert s2_low[0].variables["var_some_variable"] == "1"
+ assert s2_low[0].variables["var_password_pam_minlen"] == "1"
+
+
+
def test_controls_load_product():
ssg_root = \
From 369de6b8374084d9d607979b712285912dbb65aa Mon Sep 17 00:00:00 2001
From: Matej Tyc <matyc@redhat.com>
Date: Mon, 16 Aug 2021 10:39:22 +0200
Subject: [PATCH 12/12] Style improvements
- Renamed get_level_with_ancestors to get_level_with_ancestors_sequence,
and made it return a list - a dictionary result is quite confusing.
- Removed some optimization in the variable deletion loops.
- Extracted functionality to a _get_control_without_variables static
method.
- Defined variable removal steps using set operations.
---
ssg/controls.py | 54 +++++++++++++++++++++++++------------------------
1 file changed, 28 insertions(+), 26 deletions(-)
diff --git a/ssg/controls.py b/ssg/controls.py
index 8b69676313c..ca3187d5b16 100644
--- a/ssg/controls.py
+++ b/ssg/controls.py
@@ -152,17 +152,17 @@ def get_level(self, level_id):
)
raise ValueError(msg)
- def get_level_with_ancestors(self, level_id):
+ def get_level_with_ancestors_sequence(self, level_id):
# use OrderedDict for Python2 compatibility instead of ordered set
levels = collections.OrderedDict()
level = self.get_level(level_id)
levels[level] = ""
if level.inherits_from:
for lv in level.inherits_from:
- eligible_levels = [l for l in self.get_level_with_ancestors(lv).keys() if l not in levels.keys()]
+ eligible_levels = [l for l in self.get_level_with_ancestors_sequence(lv) if l not in levels.keys()]
for l in eligible_levels:
levels[l] = ""
- return levels
+ return list(levels.keys())
class ControlsManager():
@@ -200,35 +200,37 @@ def _get_policy(self, policy_id):
def get_all_controls_of_level(self, policy_id, level_id):
policy = self._get_policy(policy_id)
- levels = policy.get_level_with_ancestors(level_id)
+ levels = policy.get_level_with_ancestors_sequence(level_id)
all_policy_controls = self.get_all_controls(policy_id)
eligible_controls = []
- defined_variables = []
+ already_defined_variables = set()
# we will go level by level, from top to bottom
# this is done to enable overriding of variables by higher levels
- for lv in levels.keys():
- for c in all_policy_controls:
- if lv.id in c.levels:
- # if the control has a variable, check if it is not already defined
- variables = list(c.variables.keys())
- if len(variables) == 0:
- eligible_controls.append(c)
- continue
- variables_to_remove = [] # contains list of variables which are already defined and should be removed from the control
- for var in variables:
- if var in defined_variables:
- variables_to_remove.append(var)
- else:
- defined_variables.append(var)
- if len(variables_to_remove) == 0:
- eligible_controls.append(c)
- else:
- new_c = copy.deepcopy(c)
- for var in variables_to_remove:
- del new_c.variables[var]
- eligible_controls.append(new_c)
+ for lv in levels:
+ for control in all_policy_controls:
+ if lv.id not in control.levels:
+ continue
+
+ variables = set(control.variables.keys())
+
+ variables_to_remove = variables.intersection(already_defined_variables)
+ already_defined_variables.update(variables)
+
+ new_c = self._get_control_without_variables(variables_to_remove, control)
+ eligible_controls.append(new_c)
+
return eligible_controls
+ @staticmethod
+ def _get_control_without_variables(variables_to_remove, control):
+ if not variables_to_remove:
+ return control
+
+ new_c = copy.deepcopy(control)
+ for var in variables_to_remove:
+ del new_c.variables[var]
+ return new_c
+
def get_all_controls(self, policy_id):
policy = self._get_policy(policy_id)
return policy.controls_by_id.values()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,160 @@
From ac416fb6b73135b6fdeae850740ca4e10ad9fa1e Mon Sep 17 00:00:00 2001
From: Gabriel Becker <ggasparb@redhat.com>
Date: Wed, 18 Aug 2021 15:16:59 +0200
Subject: [PATCH] Fix RHEL7 documentation links.
---
linux_os/guide/services/ldap/openldap_client/group.yml | 2 +-
linux_os/guide/services/ldap/openldap_server/group.yml | 2 +-
.../ntp/chronyd_or_ntpd_specify_multiple_servers/rule.yml | 2 +-
.../ntp/chronyd_or_ntpd_specify_remote_server/rule.yml | 2 +-
linux_os/guide/services/ntp/group.yml | 2 +-
.../services/ntp/service_chronyd_or_ntpd_enabled/rule.yml | 2 +-
linux_os/guide/services/sssd/group.yml | 2 +-
.../screen_locking/smart_card_login/smartcard_auth/rule.yml | 4 +---
linux_os/guide/system/auditing/group.yml | 2 +-
.../software/disk_partitioning/encrypt_partitions/rule.yml | 2 +-
.../guide/system/software/gnome/gnome_login_screen/group.yml | 2 +-
11 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/linux_os/guide/services/ldap/openldap_client/group.yml b/linux_os/guide/services/ldap/openldap_client/group.yml
index bf17a053cd5..a64f105395f 100644
--- a/linux_os/guide/services/ldap/openldap_client/group.yml
+++ b/linux_os/guide/services/ldap/openldap_client/group.yml
@@ -13,7 +13,7 @@ description: |-
files, which is useful when trying to use SSL cleanly across several protocols.
Installation and configuration of OpenLDAP on {{{ full_name }}} is available at
{{% if product == "rhel7" %}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System-Level_Authentication_Guide/openldap.html") }}}.
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/openldap") }}}.
{{% elif product == "ol7" %}}
{{{ weblink(link="https://docs.oracle.com/en/operating-systems/oracle-linux/7/userauth/ol7-auth.html#ol7-s9-auth") }}}.
{{% endif %}}
diff --git a/linux_os/guide/services/ldap/openldap_server/group.yml b/linux_os/guide/services/ldap/openldap_server/group.yml
index c180820e9fc..d571867a7f8 100644
--- a/linux_os/guide/services/ldap/openldap_server/group.yml
+++ b/linux_os/guide/services/ldap/openldap_server/group.yml
@@ -7,5 +7,5 @@ description: |-
for an OpenLDAP server.
{{% if product == "rhel7" %}}
Installation and configuration of OpenLDAP on Red Hat Enterprise Linux 7 is available at:
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System-Level_Authentication_Guide/openldap.html") }}}.
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/openldap") }}}.
{{% endif %}}
diff --git a/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_multiple_servers/rule.yml b/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_multiple_servers/rule.yml
index 8f939356ab1..7dc188589ee 100644
--- a/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_multiple_servers/rule.yml
+++ b/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_multiple_servers/rule.yml
@@ -14,7 +14,7 @@ description: |-
{{% elif product == "ol8" %}}
{{{ weblink(link="https://docs.oracle.com/en/operating-systems/oracle-linux/8/network/ol-nettime.html") }}}
{{% else %}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-Configuring_NTP_Using_the_chrony_Suite.html") }}}
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-configuring_ntp_using_the_chrony_suite") }}}
{{% endif %}}
for more detailed comparison of the features of both of the choices, and for
further guidance how to choose between the two NTP daemons.
diff --git a/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_remote_server/rule.yml b/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_remote_server/rule.yml
index 503aecc0de2..27df8595efa 100644
--- a/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_remote_server/rule.yml
+++ b/linux_os/guide/services/ntp/chronyd_or_ntpd_specify_remote_server/rule.yml
@@ -14,7 +14,7 @@ description: |-
{{% elif product == "ol8" %}}
{{{ weblink(link="https://docs.oracle.com/en/operating-systems/oracle-linux/8/network/ol-nettime.html") }}}
{{% else %}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-Configuring_NTP_Using_the_chrony_Suite.html") }}}
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-configuring_ntp_using_the_chrony_suite") }}}
{{% endif %}}
for more detailed comparison of the features of both of the choices, and for
further guidance how to choose between the two NTP daemons.
diff --git a/linux_os/guide/services/ntp/group.yml b/linux_os/guide/services/ntp/group.yml
index 181b10dfd65..b944ee03116 100644
--- a/linux_os/guide/services/ntp/group.yml
+++ b/linux_os/guide/services/ntp/group.yml
@@ -54,7 +54,7 @@ description: |-
{{% elif product == "ol8" %}}
{{{ weblink(link="https://docs.oracle.com/en/operating-systems/oracle-linux/8/network/ol-nettime.html") }}}
{{% elif product == "rhel7" %}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-Configuring_NTP_Using_the_chrony_Suite.html") }}}
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-configuring_ntp_using_the_chrony_suite") }}}
{{% elif "ubuntu" in product %}}
{{{ weblink(link="https://help.ubuntu.com/lts/serverguide/NTP.html") }}}
{{% elif "debian" in product %}}
diff --git a/linux_os/guide/services/ntp/service_chronyd_or_ntpd_enabled/rule.yml b/linux_os/guide/services/ntp/service_chronyd_or_ntpd_enabled/rule.yml
index 065cf301b95..00739816f5e 100644
--- a/linux_os/guide/services/ntp/service_chronyd_or_ntpd_enabled/rule.yml
+++ b/linux_os/guide/services/ntp/service_chronyd_or_ntpd_enabled/rule.yml
@@ -17,7 +17,7 @@ description: |-
{{% elif product == "ol8" %}}
{{{ weblink(link="https://docs.oracle.com/en/operating-systems/oracle-linux/8/network/ol-nettime.html") }}}
{{% else %}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-Configuring_NTP_Using_the_chrony_Suite.html") }}}
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-configuring_ntp_using_the_chrony_suite") }}}
{{% endif %}}
for guidance which NTP daemon to choose depending on the environment used.
diff --git a/linux_os/guide/services/sssd/group.yml b/linux_os/guide/services/sssd/group.yml
index 5b0caf7d64b..3f4eced7ca7 100644
--- a/linux_os/guide/services/sssd/group.yml
+++ b/linux_os/guide/services/sssd/group.yml
@@ -11,7 +11,7 @@ description: |-
<br /><br />
For more information, see
{{%- if product == "rhel7" -%}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System-Level_Authentication_Guide/SSSD.html") }}}
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/sssd") }}}
{{%- elif product == "rhel8" -%}}
{{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/installing_identity_management/installing-an-ipa-client-basic-scenario_installing-identity-management#sssd-deployment-operations_install-client-basic") }}}
{{%- elif product == "ol7" -%}}
diff --git a/linux_os/guide/system/accounts/accounts-physical/screen_locking/smart_card_login/smartcard_auth/rule.yml b/linux_os/guide/system/accounts/accounts-physical/screen_locking/smart_card_login/smartcard_auth/rule.yml
index fc7f149bf40..62a343cf396 100644
--- a/linux_os/guide/system/accounts/accounts-physical/screen_locking/smart_card_login/smartcard_auth/rule.yml
+++ b/linux_os/guide/system/accounts/accounts-physical/screen_locking/smart_card_login/smartcard_auth/rule.yml
@@ -8,9 +8,7 @@ description: |-
To enable smart card authentication, consult the documentation at:
<ul>
{{% if product == "rhel7" %}}
- <li><b>{{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System-Level_Authentication_Guide/smartcards.html#authconfig-smartcards") }}}</b></li>
- {{% elif product == "rhel8" %}}
- <li><b>{{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System-Level_Authentication_Guide/smartcards.html#authconfig-smartcards") }}}</b></li>
+ <li><b>{{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/smartcards.html#authconfig-smartcards") }}}</b></li>
{{% elif product == "ol7" %}}
<li><b>{{{ weblink(link="https://docs.oracle.com/en/operating-systems/oracle-linux/7/userauth/ol7-auth.html#ol7-s4-auth") }}}</b></li>
{{% endif %}}
diff --git a/linux_os/guide/system/auditing/group.yml b/linux_os/guide/system/auditing/group.yml
index 82f87e81c47..5fce88db032 100644
--- a/linux_os/guide/system/auditing/group.yml
+++ b/linux_os/guide/system/auditing/group.yml
@@ -38,7 +38,7 @@ description: |-
Examining some example audit records demonstrates how the Linux audit system
satisfies common requirements.
The following example from Fedora Documentation available at
- <tt>{{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/SELinux_Users_and_Administrators_Guide/sect-Security-Enhanced_Linux-Troubleshooting-Fixing_Problems.html#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages") }}}</tt>
+ <tt>{{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html-single/selinux_users_and_administrators_guide/index#sect-Security-Enhanced_Linux-Fixing_Problems-Raw_Audit_Messages") }}}</tt>
shows the substantial amount of information captured in a
two typical "raw" audit messages, followed by a breakdown of the most important
fields. In this example the message is SELinux-related and reports an AVC
diff --git a/linux_os/guide/system/software/disk_partitioning/encrypt_partitions/rule.yml b/linux_os/guide/system/software/disk_partitioning/encrypt_partitions/rule.yml
index add0a41fa94..cd07fb4c0ca 100644
--- a/linux_os/guide/system/software/disk_partitioning/encrypt_partitions/rule.yml
+++ b/linux_os/guide/system/software/disk_partitioning/encrypt_partitions/rule.yml
@@ -38,7 +38,7 @@ description: |-
{{% elif product in ["sle12", "sle15"] %}}
{{{ weblink(link="https://www.suse.com/documentation/sled-12/book_security/data/sec_security_cryptofs_y2.html") }}}
{{% elif product == "rhel7" %}}
- {{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Encryption.html") }}}.
+ {{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/security_guide/sec-encryption") }}}.
{{% else %}}
{{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/encrypting-block-devices-using-luks_security-hardening") }}}.
{{% endif %}}
diff --git a/linux_os/guide/system/software/gnome/gnome_login_screen/group.yml b/linux_os/guide/system/software/gnome/gnome_login_screen/group.yml
index 8e8b32f1d79..299b96c0592 100644
--- a/linux_os/guide/system/software/gnome/gnome_login_screen/group.yml
+++ b/linux_os/guide/system/software/gnome/gnome_login_screen/group.yml
@@ -14,5 +14,5 @@ description: |-
the man page <tt>dconf(1)</tt>.
{{% else %}}
For more information about enforcing preferences in the GNOME3 environment using the DConf
- configuration system, see <b>{{{ weblink(link="https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Desktop_Migration_and_Administration_Guide/index.html") }}}/></b> and the man page <tt>dconf(1)</tt>.
+ configuration system, see <b>{{{ weblink(link="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/desktop_migration_and_administration_guide") }}}/></b> and the man page <tt>dconf(1)</tt>.
{{% endif %}}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
From bd790153e02c1d1725f59f5d88c65c77eb1421e9 Mon Sep 17 00:00:00 2001
From: Gabriel Becker <ggasparb@redhat.com>
Date: Tue, 24 Aug 2021 12:48:46 +0200
Subject: [PATCH] Add a new selector for var_system_crypto_policy and use it
RHEL8 CIS.
This new selector is used to select explicit DEFAULT value in RHEL8 CIS
L1 profiles. The "default" selector cannot be selected and it causes
errors if used.
---
controls/cis_rhel8.yml | 2 +-
.../software/integrity/crypto/var_system_crypto_policy.var | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/controls/cis_rhel8.yml b/controls/cis_rhel8.yml
index 29d972427cf..c0d3f5f40de 100644
--- a/controls/cis_rhel8.yml
+++ b/controls/cis_rhel8.yml
@@ -553,7 +553,7 @@ controls:
automated: yes
rules:
- configure_crypto_policy
- - var_system_crypto_policy=default
+ - var_system_crypto_policy=default_policy
# This rule works in conjunction with the configure_crypto_policy above.
# If a system is remediated to CIS Level 1, just the rule above will apply
diff --git a/linux_os/guide/system/software/integrity/crypto/var_system_crypto_policy.var b/linux_os/guide/system/software/integrity/crypto/var_system_crypto_policy.var
index ce301154a39..8b89848d122 100644
--- a/linux_os/guide/system/software/integrity/crypto/var_system_crypto_policy.var
+++ b/linux_os/guide/system/software/integrity/crypto/var_system_crypto_policy.var
@@ -13,6 +13,7 @@ interactive: false
options:
default: DEFAULT
+ default_policy: DEFAULT
default_nosha1: "DEFAULT:NO-SHA1"
fips: FIPS
fips_ospp: "FIPS:OSPP"

View File

@ -5,7 +5,7 @@
Name: scap-security-guide
Version: 0.1.57
Release: 3%{?dist}
Release: 4%{?dist}
Summary: Security guidance and baselines in SCAP formats
License: BSD-3-Clause
URL: https://github.com/ComplianceAsCode/content/
@ -20,6 +20,11 @@ Patch4: scap-security-guide-0.1.58-dont_remove_all_whitespace-PR_7393.patch
Patch5: scap-security-guide-0.1.58-fix_gpgkey-PR_7321.patch
Patch6: scap-security-guide-0.1.58-s390x_arch-PR_7385.patch
Patch7: scap-security-guide-0.1.58-ism_ks-PR_7392.patch
Patch8: scap-security-guide-0.1.58-cis_def-PR_6976.patch
Patch9: scap-security-guide-0.1.58-rhel9_cis_crypto_policy_default-PR_7452.patch
Patch10: scap-security-guide-0.1.58-fix_broken_link-PR_7409.patch
Patch11: scap-security-guide-0.1.58-cis_build_system_fix-PR_7226.patch
Patch12: scap-security-guide-0.1.58-rhel9_cis-PR_7415.patch
BuildRequires: libxslt
BuildRequires: expat
@ -106,6 +111,11 @@ rm %{buildroot}/%{_docdir}/%{name}/Contributors.md
%endif
%changelog
* Tue Aug 24 2021 Matej Tyc <matyc@redhat.com> - 0.1.57-4
- Fix a broken HTTP link
Add CIS profile based on RHEL8 CIS, fix its Crypto Policy usage
Resolves: rhbz#1962564
* Tue Aug 17 2021 Matej Tyc <matyc@redhat.com> - 0.1.57-3
- Use SSHD directory-based configuration.
Resolves: rhbz#1962564