File: oval.template

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 (182 lines) | stat: -rw-r--r-- 9,779 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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<def-group oval_version="5.11">
  <definition class="compliance" id="{{{_RULE_ID }}}" version="1">
    {{{ oval_metadata("All syslog log files should have appropriate ownership.") }}}
    <criteria operator="AND">
      {{% if product in ["debian11", "debian12", "ubuntu1604"] %}}
      <extend_definition definition_ref="package_rsyslog_installed"
        comment="rsyslog daemon is used as local logging daemon"/>
      {{% endif %}}
      <criterion test_ref="test_{{{ _RULE_ID }}}"
        comment="Check if all system log files have appropriate {{{ ATTRIBUTE }}} set"/>
    </criteria>
  </definition>

  <!-- First obtain rsyslog's $IncludeConfig directive and include() object values.
       The last was introduced in rsyslog v8.33.0). -->
  <ind:textfilecontent54_object id="object_{{{ _RULE_ID }}}_include_config_value" version="1"
       comment="rsyslog's $IncludeConfig and include() statements values.">
    <ind:filepath>/etc/rsyslog.conf</ind:filepath>
    <ind:pattern
      operation="pattern match">^(?:include\([\n\s]*file="([^\s;]+)".*|\$IncludeConfig[\s]+([^\s;]+))$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
  </ind:textfilecontent54_object>

  <!-- Turn that glob value into Perl's regex so it can be used as filepath pattern below -->
  <local_variable id="var_{{{ _RULE_ID }}}_include_config_regex" datatype="string" version="1"
    comment="rsyslog's include config values converted to regex.">
    <unique>
      <glob_to_regex>
        <object_component item_field="subexpression"
          object_ref="object_{{{ _RULE_ID }}}_include_config_value"/>
      </glob_to_regex>
    </unique>
  </local_variable>

  <!-- Create a variable_object from the regex variable.
       If the variable has no values, there won't be any objects. -->
  <ind:variable_object id="object_var_{{{ _RULE_ID }}}_include_config_regex" version="1"
    comment="Make variable object from regex variable.">
    <ind:var_ref>var_{{{ _RULE_ID }}}_include_config_regex</ind:var_ref>
  </ind:variable_object>

  <local_variable id="var_{{{ _RULE_ID }}}_syslog_config" datatype="string" version="1"
    comment="Main rsyslog configuration file.">
    <literal_component datatype="string">^/etc/rsyslog.conf$</literal_component>
  </local_variable>

  <ind:variable_object id="object_var_{{{ _RULE_ID }}}_syslog_config" version="1"
    comment="Make variable object from local variable.">
    <ind:var_ref>var_{{{ _RULE_ID }}}_syslog_config</ind:var_ref>
  </ind:variable_object>

  <!-- Combine the two variable_objects into one variable_object.
       We do it this way to avoid referencing an empty variable in a state comparison, which will
       cause a test to evaluate to fail. Combining an empty set of objects is fine though. -->
  <ind:variable_object id="object_var_{{{ _RULE_ID }}}_all_conf_files" version="1"
    comment="Variable containing all rsyslog configuration files.">
    <set>
      <object_reference>object_var_{{{ _RULE_ID }}}_include_config_regex</object_reference>
      <object_reference>object_var_{{{ _RULE_ID }}}_syslog_config</object_reference>
    </set>
  </ind:variable_object>

  <!-- In element filepath of object_rfg_log_files_paths we need to pass a list of values,
       a list of objects won't do. So we make a local_variable from the variable_objects. -->
  <local_variable id="var_{{{ _RULE_ID }}}_all_conf_files" datatype="string" version="1"
    comment="Locations of all rsyslog configuration files as collection.">
    <object_component object_ref="object_var_{{{ _RULE_ID }}}_all_conf_files" item_field="value"/>
  </local_variable>

  <!-- For each item from that collection (particular rsyslog's configuration files paths) search
       that rsyslog's configuration files to select file paths for log files directives -->
  <ind:textfilecontent54_object id="object_{{{ _RULE_ID }}}_log_files_paths" version="1"
    comment="All rsyslog log files collected from rsyslog configuration files." >
    <ind:filepath operation="pattern match" var_check="at least one"
      var_ref="var_{{{ _RULE_ID }}}_all_conf_files"/>
      <!-- Chunk of text retrieved from rsyslog's configuration file is considered to constitute
           a log file path if all of the following conditions are met:
            * the string represents a regular file on particular file system
              (verified via corresponding file_state below),
            * the chunk of text is in the last column in the row,
              (possibly suffixed by ';' character and rsyslog Template name),
            * contains at least one slash '/' character, and simultaneously doesn't contain any
              of ';', ':' and space characters,
            * the chunk was retrieved from a row not starting with space, '#', or '$' characters
      -->
    <ind:pattern
      operation="pattern match">^\s*[^(\s|#|\$)]+\s+.*(?:\bFile="|\s|\/|-)(\/[^:;\s"]+).*$</ind:pattern>
    <ind:instance datatype="int" operation="greater than or equal">1</ind:instance>
    <filter action="exclude">state_{{{ _RULE_ID }}}_ignore_include_paths</filter>
  </ind:textfilecontent54_object>

  <ind:textfilecontent54_state id="state_{{{ _RULE_ID }}}_ignore_include_paths"
    comment="ignore" version="1">
    <!-- Among the paths matched in object_{{{ _RULE_ID }}}_log_files_paths there can be paths
         from include() or $IncludeConfig statements. These paths are conf files, not log files.
         Their properties don't need to be as required for log files, thus, lets exclude them
         from the list of objects found. -->
    <ind:text
    operation="pattern match">(?:file="[^\s;]+"|\$IncludeConfig[\s]+[^\s;]+|\/dev\/.*)</ind:text>
  </ind:textfilecontent54_state>

  <!-- Define OVAL variable to hold all the various system log files locations
       retrieved from the different rsyslog configuration files. -->
  <local_variable id="var_{{{ _RULE_ID }}}_log_files_paths" datatype="string" version="1"
    comment="File paths of all rsyslog log files">
    <object_component item_field="subexpression"
      object_ref="object_{{{ _RULE_ID }}}_log_files_paths" />
  </local_variable>

  <!-- Perform the test if all rsyslog system log files have appropriate attribute -->
  <unix:file_test id="test_{{{ _RULE_ID }}}" check="all" check_existence="all_exist" version="1"
    comment="System log files have appropriate {{{ ATTRIBUTE }}} set">
    <unix:object object_ref="object_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}" />
    <unix:state state_ref="state_{{{ _RULE_ID }}}" />
  </unix:file_test>

  <unix:file_object id="object_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}" version="1"
    comment="All system log files collected from rsyslog configuration files">
    <unix:filepath datatype="string" var_check="at least one"
      var_ref="var_{{{ _RULE_ID }}}_log_files_paths"/>
  </unix:file_object>

  {{% if ATTRIBUTE == "groupowner" %}}
    {{% if VALUE is number %}}
  <!-- store groupowner GID in variable -->
  <constant_variable id="var_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_gid" datatype="int" version="1" comment="GID of {{{ ATTRIBUTE }}}"><value>{{{ VALUE }}}</value></constant_variable>

    {{% else %}}
  <!-- get groupowner GID from name -->
  <ind:textfilecontent54_object id="obj_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_gid" version="1" comment="GID of group {{{ VALUE }}}">
      {{# Copied from file_groupowner template, assuming logic is still valid #}}
      {{%- if product in ["rhcos4","ocp4"] %}}
    <ind:filepath>/usr/lib/group</ind:filepath>
      {{%- else %}}
    <ind:filepath>/etc/group</ind:filepath>
      {{%- endif %}}
    <ind:pattern operation="pattern match">^{{{ VALUE }}}:\w+:(\w+):.*</ind:pattern>
    <ind:instance datatype="int" operation="equals">1</ind:instance>
  </ind:textfilecontent54_object>

  <local_variable id="var_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_gid" datatype="int" version="1"
      comment="GID of group {{{ VALUE }}}">
    <object_component item_field="subexpression" object_ref="obj_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_gid"/>
  </local_variable>
    {{% endif %}}

  {{% elif ATTRIBUTE == "owner" %}}
    {{% if VALUE is number %}}
  <!-- store owner UID in variable -->
  <constant_variable id="var_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_uid" datatype="int" version="1" comment="UID of {{{ ATTRIBUTE }}}"><value>{{{ VALUE }}}</value></constant_variable>

    {{% else %}}
  <!-- get owner UID from name -->
  <ind:textfilecontent54_object id="obj_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_uid" version="1" comment="UID of user {{{ VALUE }}}">
      {{# Assuming same logic as above applies to users #}}
      {{%- if product in ["rhcos4","ocp4"] %}}
    <ind:filepath>/usr/lib/passwd</ind:filepath>
      {{%- else %}}
    <ind:filepath>/etc/passwd</ind:filepath>
      {{%- endif %}}
    <ind:pattern operation="pattern match">^{{{ VALUE }}}:\w+:(\w+):.*</ind:pattern>
    <ind:instance datatype="int" operation="equals">1</ind:instance>
  </ind:textfilecontent54_object>

  <local_variable id="var_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_uid" datatype="int" version="1"
          comment="UID of user {{{ VALUE }}}">
    <object_component item_field="subexpression" object_ref="obj_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_uid"/>
  </local_variable>
    {{% endif %}}
  {{% endif %}}

  <unix:file_state id="state_{{{ _RULE_ID }}}" version="1">
    <unix:type operation="equals">regular</unix:type>
    {{% if ATTRIBUTE == "groupowner" %}}
    <unix:group_id datatype="int" var_ref="var_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_gid"></unix:group_id>
    {{% elif ATTRIBUTE == "owner" %}}
    <unix:user_id datatype="int" var_ref="var_{{{ _RULE_ID }}}_{{{ ATTRIBUTE }}}_uid"></unix:user_id>
    {{% else %}}
    {{{ STATEMODE | indent(4) }}}
   {{% endif %}}
  </unix:file_state>
</def-group>