This function returns a list of all includes in a profile and its
included files.
It's split off from is_known_rule() and get_file_perms() which shared
lots of common code to recursively get the include list. These functions
now use include_list_recursive().
... or calling is_known_rule() on events for non-existing hats.
It's the usual hasher() "fun" again - accessing a non-existing element
will create its parent.
In theory this commit might be worth a backport. In practise, it doesn't cause
any visible problem.
However, starting with the next commit, it will cause lots of test errors.
Also add a missing is_known_rule() call for dbus rules, which might have
caused similar hasher() "fun".
rule_obj.get_full_paths() handles directories and non-existing files
(depending on 'if exists'), so we can simply feed the resulting list
into load_include()
This function returns a list of paths for an include rule. This can be
- a single path if the include file is a file and exists
- a single path if the include file doesn't exist, but doesn't have
'if exists' (this will cause a 'file not found' error when used)
- a list of paths if the include is a directory
- an empty list if the rule has 'if exists' and the file doesn't exist
Also add some tests for get_full_paths()
IncludeRuleset needs to import it (next commit), which is impossible
when it lives in aa.py (would cause recursive import loop because aa.py
imports IncludeRuleset)
... because this is now done via IncludeRule, and keeping the separate
code would mean asking twice.
Note that the user interface changes slightly.
The old workflow was
1 - #include <foo>
2 - #include <bar>
3 - #include <baz>
[select 2 and (A)dd, then get the next question for the remainder]
1 - #include <foo>
2 - #include <baz>
[(A)dd another one, or (I)gnore the remainder]
The new workflow will ask separately for each abstraction, and you can
(A)dd or (I)gnore it. This is probably easier to understand because it's
basically a yes/no question.
... and write them (only) from 'inc_ie' (IncludeRuleset), which can
handle both "include" and "include if exists" rules.
This duplicates storage of include rules because 'include' is still used
and needed at various places that work on/with the include rules.
With this, we get removal of duplicate include lines insinde a profile
in aa-cleanprof "for free" - extend cleanprof_test.in to confirm this.
alid_include() checks if the given include file exists or is whitelisted in cfg\['settings'\]\['custom_includes'\].
The check if that include file is already part of the profile is unrelated to that. Move it to match_includes() where it fits much better (and drop the now superfluous profile parameter from valid_include())
In theory is_known_rule() should prevent that case from ever happening, but let's restrict this commit to moving the code around and keep this check just to be sure.
While on it, add some documentation to both functions.
PR: https://gitlab.com/apparmor/apparmor/-/merge_requests/534
Acked-by: John Johansen <john.johansen@canonical.com>
Also rename aa.py delete_duplicates() and make ruletypes a parameter.
See the commit messages for details.
This reduces usage of global variables.
The final change is that aa-genprof now asks about preamble rules that are \*Rule classes (currently `abi` and `include if exists`).
PR: https://gitlab.com/apparmor/apparmor/-/merge_requests/532
Acked-by: John Johansen <john.johansen@canonical.com>
valid_include() checks if the given include file exists or is
whitelisted in cfg['settings']['custom_includes'].
The check if that include file is already part of the profile is
unrelated to that. Move it to match_includes() where it fits much
better (and drop the now superfluous profile parameter from
valid_include())
In theory is_known_rule() should prevent that case from ever happening,
but let's restrict this commit to moving the code around and keep this
check just to be sure.
While on it, add some documentation to both functions.
For now, that means aa-mergeprof will ask for `abi` and `include if
exists` rules (currently hardcoded).
This needs storing of `active_profiles` in the Prof object - the
preamble `abi` and `include if exists` rules are stored there.
Since several functions expect an `include` dict, add an empty one to
ProfileList to prevent lots of errors and breakage. It can be removed
again when handling of `include` rules gets moved to IncludeRule.
Rename delete_duplicates() to delete_all_duplicates() to make the
function easier grep-able - the *rule classes have delete_duplicates()
which might be confused with the old name.
Also hand over 'ruletypes' as parameter to delete_all_duplicates()
instead of using the global variable.
ask_the_questions() stays the "main" function, loops over all profiles,
and calls ask_rule_questions() for each profile.
ask_rule_questions() asks the questions for all events in a specific
profile or hat.
This reduces the usage of global variables in ask_rule_questions().
The TODO in write_rules() was long solved - remove the safety net type
check, it's no longer needed.
Without this, the function becomes a simple .get_rules_clean() call
which can easily be inlined into write_piece() at the two places where
it's called.
... but not for abi rules, which (according to the simple_tests
profiles) do not share these bugs)
For unquoted paths, make sure that the path doesn't include whitespace.
... because after the previous three commits, nothing reads/needs this
anymore
Note: file_name in ask_exec() was only used in the (dropped) filelist
usage.
Instead of checking filelist[file]['profiles'] for duplicate hats, check
profile_data[profile][hat].
With this, the duplicate hat check is done in the same way as the check
for duplicate profiles and child profiles.
Also add tests for duplicate child profiles and duplicate hats.
Using a list as parameter for subprocess.call is more secure, and avoids
funny problems if the filename to display contains spaces or other funny
characters.