Commit graph

1970 commits

Author SHA1 Message Date
Ryan Lee
77cabf7dba utils: test: use sys.executable when launching aa-notify in tests
If the tests are running under a different Python, then the aa-notify bin should use the same Python

Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
2025-01-22 12:04:35 -08:00
Ryan Lee
3365e492a7 utils: test: test-aa-notify: Ensure aanotify_bin is always a list
os.environ returns a string, but the default value is a list, and the concatenation of __AA_CONFDIR assumes a list.
Thus, if APPARMOR_NOTIFY and __AA_CONFDIR were both specified, this would error out.

Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
2025-01-22 11:52:38 -08:00
Maxime Bélair
7049d7b0c6 aa-notify: Use a quieter default behavior 2025-01-16 19:31:18 +00:00
Christian Boltz
45e4c27cf0
Add support for lastlog2 to get last login
lastlog2 is the 2038-safe replacement for wtmp, and in the meantime
became part of util-linux.

This commit switches from trying to parse the lastlog2 output to
directly reading lastlog2.db with sqlite3.

Adjust get_last_login_timestamp() to use the lastlog2 database
(/var/lib/lastlog/lastlog2.db) if it exists, and adjust
get_last_login_timestamp_lastlog2() to actually do that.

(If lastlog2.db doesn't exist, aa-notify will read wtmp as usual.)

Unfortunately lastlog2 doesn't have a way to get machine-readable output
(for example json), therefore - after trying and failing to parse the
lastlog2 output - directly read from lastlog2.db. Let's hope the format
never changes ;-)

Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1228378

Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1216660

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/372
2025-01-14 19:36:43 +01:00
Christian Boltz
371a9ff9ec
Add support for lastlog2 to get last login
lastlog2 is the 2038-safe replacement for wtmp, and in the meantime
became part of util-linux.

Adjust get_last_login_timestamp() to use lastlog2 if it exists, and add
get_last_login_timestamp_lastlog2() to actually do that.

(If lastlog2 doesn't exist, aa-notify will read wtmp as usual.)

Unfortunately lastlog2 doesn't have a way to get machine-readable output
(for example json), therefore we have to parse the output that is meant
for humans. Let's hope the format never changes ;-)

(The alternative would have been to use squlite3 to once more read the
data behind the official program's back, but that was already a bad idea
for wtmp, therefore I decided against it.)

Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1228378

Fixes: https://bugzilla.opensuse.org/show_bug.cgi?id=1216660

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/372
2025-01-14 19:36:42 +01:00
Christian Boltz
7d537efcb0
Rename get_last_login_timestamp to get_last_login_timestamp_wtmp
... and add a wrapper function with the old name

Also rename the tests to the new name, and create a copy with the
original name. The copy will be adjusted to also check/expect lastlog2
results in a later commit.
2025-01-14 19:36:40 +01:00
Christian Boltz
1c2d79de7f
Support unloading profiles in kill and prompt mode
... in aa-teardown (actually everything that uses rc.apparmor.functions)
and aa-remove-unknown.

Fixes: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2093797
2025-01-13 18:07:39 +01:00
Christian Boltz
58664c106c
read_profile: rename active_profile parameter
... to is_active_profile to prevent confusion with active_profiles
2024-12-17 22:51:12 +01:00
Christian Boltz
0551be806e
ask_the_questions: use full_profile
... instead of combine_profname([profile, hat])
2024-12-17 22:51:12 +01:00
Christian Boltz
728a8717e9
aa.py: get rid of 'aa'
... which is no longer used - everything is in active_profiles now :-)
2024-12-17 22:51:12 +01:00
Christian Boltz
f66ada256a
Drop now-unused split_to_merged() and its tests 2024-12-17 22:51:12 +01:00
Christian Boltz
695e472b2c
Switch aa-mergeprof from aa to active_profiles 2024-12-17 22:51:12 +01:00
Christian Boltz
531f47676d
ProfileList: add get_all_profiles()
... and a test for it
2024-12-17 22:51:12 +01:00
Christian Boltz
c93d560f89
Switch test-libapparmor-test_multi.py from aa to active_profiles
Note that the old code assigned dummy_prof to aa[profile][hat] and
active_profiles[profile] (= the main/parent profile) - which is
diffferent when testing a log for a child profile.

aa[profile][hat] was the wrong place - but since we used exactly that
again when checking for added exec rules, this error was hidden.

Now that the test is switched to using active_profiles, only check the
main profile for exec rules added by ask_exec(). (This will need to be
adjusted when we add a test for exec rules/events in nested childs, but
not earlier ;-)
2024-12-17 22:51:12 +01:00
Christian Boltz
61a7ba2822
Switch usage of 'aa' to active_profiles
This is mostly a search-and-replace patch.

In most cases, that means replacing `aa[profile][hat]` with
`active_profiles[full_profile]`.

In cases where the main/parent profile is meant, switch from
`aa[profile][profile]` to `active_profiles[profile]`.

Checks like `p in apparmor.aa` that check if a (main) profile exists
become `active_profiles.profile_exists(p)`.

write_profile() gets changed to loop over
`active_profiles.get_profile_and_childs()` which makes the code simpler.

`split_to_merged(aa)` becomes just `active_profiles`.

The only change that is not search-and-replace style is in
write_piece(). It expects a dict (not a ProfileList), therefore adjust
serialize_profile() so that it always hands over a dict.
2024-12-17 22:51:12 +01:00
Christian Boltz
c5bbe79338
replace original_aa with original_profiles
This also changes the internal structure - instead of the nested dict
original_aa[profile][hat], we now have a ProfileList original_profiles[profile//hat].
2024-12-17 22:51:12 +01:00
Christian Boltz
c5e495c56d
ProfileList: add replace_profile()
... and some tests for it.
2024-12-17 22:51:12 +01:00
Christian Boltz
a37c65957f
ProfileList: add __getitem__()
... and add some tests for it.
2024-12-17 22:51:12 +01:00
Christian Boltz
b66dfd8bfb
Use active_profiles.profile_exists()
... to test if a given profile or hat exists
2024-12-17 22:51:12 +01:00
Christian Boltz
0da12fe7cb
Use extra_profiles.profile_exists()
... instead of accessing the internal storage directly.
2024-12-17 22:51:12 +01:00
Christian Boltz
3a02d6d14c
Use temporary object instead of working in aa[profile][hat]
... in ask_addhat() and ask_the_questions().

Also deduplicate some code in ask_the_questions().
2024-12-17 22:51:12 +01:00
Christian Boltz
f5ed9cffe3
serialize_profile(): simplify and cleanup
Drop `comment.replace('\\n', '\n')` because that doesn't make sense and
doesn't change anything - not even a comment that contains the literal
string '\n' (backslash + letter n).

Besides that, get rid of the 'string' variable and store everything in
'data'.
2024-12-17 22:51:11 +01:00
Christian Boltz
2e8a75195c
De-duplicate code in read_profile() 2024-12-17 22:51:11 +01:00
Christian Boltz
578ab8da9d
Store child profiles and hats in active_profiles
... including just-created child profiles and hats.

Also ensure that serialize_profile() doesn't print them out as child
profiles AND external hats.

This commit includes a bugfix for a rare corner case:
Since create_new_profile() can return more than one profile if the
program has required_hats, add all of them to active_profiles.
(aa only got the expected profile added, but not the required_hats.)
2024-12-17 22:51:11 +01:00
Christian Boltz
fe9b2542ca
ProfileList: add profile_exists()
... and extend the existing tests for add_profile to also check
profile_exists().
2024-12-17 22:51:11 +01:00
Christian Boltz
a0e6fbe32a
ProfileStorage: store parent profile
... and extend the tests to get some coverage.
2024-12-17 22:51:11 +01:00
Christian Boltz
792d1a5568
ProfileList addProfile(): always hand over ProfileStorage
... and make it non-optional

Note that read_profile() in aa.py skips child profiles and hats,
therefore active_profiles for now only contains the main profiles.
2024-12-17 22:51:11 +01:00
Christian Boltz
5fb91616e3 Merge python 3.13 fixes/workarounds
Fixes/workarounds for python 3.13 support.

fail.py: handle missing cgitb - workaround for https://gitlab.com/apparmor/apparmor/-/issues/447

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1439
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Christian Boltz <apparmor@cboltz.de>
2024-12-05 17:35:13 +00:00
Mikko Rapeli
434e34bb51 fail.py: handle missing cgitb
It's no longer in python standard library starting
at version 3.13. Fixes:

root@qemuarm64:~# aa-complain /etc/apparmor.d/*
Traceback (most recent call last):
  File "/usr/sbin/aa-complain", line 18, in <module>
    from apparmor.fail import enable_aa_exception_handler
  File "/usr/lib/python3.13/site-packages/apparmor/fail.py", line 12, in <module>
    import cgitb
ModuleNotFoundError: No module named 'cgitb'

Signed-off-by: Mikko Rapeli <mikko.rapeli@linaro.org>
2024-12-05 06:58:01 +00:00
Zygmunt Krynicki
1df91e2c8c Third iteration of spread support
- Tests defined in utils/test are now described by a task.yaml in the same
  directory and can run concurrently across many machines.
- Tests for utils/ are now executed on openSUSE Tumbleweed since ttk themes is
  no longer a hard dependency in master.
- Tests no longer run on openSUSE Leap 15.6 due to the age of default
  Python (3.6) and gcc/g++. The tight integration with SWIG which does
  not seem to support other Python versions very well. Perl hard-codes
  old GCC for extension modules. The upcoming openSUSE Leap 16 should be
  a viable target. In the meantime we can still test everything through
  rolling-release Tumbleweed.
- Formatting of YAML files is now more uniform, at four spaces per tab.
- The run-spread.sh script is now in the root of the tree. The script allows
  running all spread tests sequentially on one system, while collecting logs
  and artifacts for convenient analysis after the fact.
- All systems are adjusted to run _four_ workers in parallel with _two_ virtual
  cores each and equipped with 1.5GB of virtual memory. This aims to best
  utilize the capacity of a typical CI worker with two to four cores and about
  8GB of available memory.
- Failing tests are marked as such, so that as a whole the entire spread suite
  can pass and be useful at catching regressions.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-12-05 02:17:07 +01:00
Zygmunt Krynicki
9588b06e0f Allow running exactly one test in utils/test
The new check-one-test-% pattern rule allows running individual test scripts.
This allows them to be tested in parallel across many Make worker threads or
across many distinct machines with spread.

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-12-05 02:17:07 +01:00
Georgia Garcia
ea7e75cde7 Merge Drop useless code in test-regex_matches.py
No need to assign a variable to itsself, not even conditionally.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1442
Approved-by: Ryan Lee <rlee287@yahoo.com>
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
2024-12-03 16:35:17 +00:00
Christian Boltz
ce0cfccfd7
Drop useless code in test-regex_matches.py
No need to assign a variable to itsself, not even conditionally.
2024-12-02 21:33:34 +01:00
Ryan Lee
2068ea8720 Remove match statements in utils for older Python compatibility
Signed-off-by: Ryan Lee <ryan.lee@canonical.com>
2024-12-02 10:47:16 -08:00
Andreas Wiese
b4aa00de51
aa-remove-unknown: fix readability check
This check is intended for ensuring that the profiles file can actually
be opened.  The *actual* check is performed by the shell, not the read
utility, which won't even be executed if the input redirection (and
hence the test) fails.

If the test succeeds, though, using `read` here might actually
jeopardize the test result if there are no profiles loaded and the file
is empty.

This commit fixes that case by simply using `true` instead of `read`.
2024-11-29 12:20:48 +01:00
Georgia Garcia
9d2cde168e Merge aa-notify: Adding support for merging notification.
The new flag --merge-notifications enables the merging of all
notifications from a fixed time period into a single one, thus
preventing notification flooding.
A new GUI allows users to choose either a synthetic or a comprehensive
view of the notifications.

Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1324
Approved-by: Christian Boltz <apparmor@cboltz.de>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
2024-11-26 18:35:37 +00:00
Maxime Bélair
f63fcdc8d2 aa-notify: Adding support for merging notification. 2024-11-26 18:35:37 +00:00
Zygmunt Krynicki
92fcdcab9e Quote trailing backslash in test case
This fixes an error with Python 3.11:

```
test/test-parser-simple-tests.py:420:21: E502 the backslash is redundant between brackets
```

Signed-off-by: Zygmunt Krynicki <zygmunt.krynicki@canonical.com>
2024-11-25 13:55:05 +01:00
Christian Boltz
508ace452d
test-logprof: Increase timeout once more
Builds for risc64 are much slower than on other architectures (4-5
seconds with qemu-user or on Litchi Pi 4A).

Since the timeout is only meant as a safety net, increase it generously,
and hopefully for the last time.

Fixes: https://gitlab.com/apparmor/apparmor/-/issues/463
2024-11-09 19:57:00 +01:00
John Johansen
8df57ba89c Merge aa.py is_known_rule(): remove obsolete sanity check
We use ProfileStorage everywhere, which makes checking if a specific
rule_type exists obsolete.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1405
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
2024-11-06 03:13:36 +00:00
John Johansen
e36ef0ed43 Merge aa.py: drop unused function profile_exists()
I don't know when (or even: if) this function was in use. A quick look
at the git history of aa.py shows that the function was (blindly?)
updated a few times. However, I didn't find a commit that uses or stops
using profile_exists(), so maybe it was never used at all.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1404
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
2024-11-06 03:12:38 +00:00
Christian Boltz
db1ca4f5e8
aa.py is_known_rule(): remove obsolete sanity check
We use ProfileStorage everywhere, which makes checking if a specific
rule_type exists obsolete.
2024-11-03 21:21:39 +01:00
Christian Boltz
c10b39f3fe
aa.py: drop unused function profile_exists()
I don't know when (or even: if) this function was in use. A quick look
at the git history of aa.py shows that the function was (blindly?)
updated a few times. However, I didn't find a commit that uses or stops
using profile_exists(), so maybe it was never used at all.
2024-11-03 21:06:27 +01:00
Christian Boltz
e5479bd7ef
aa-mergeprof: prevent backtrace if file not found
If a user specifies a non-existing file to merge into the profiles
(`aa-mergeprof /file/not/found`), this results in a backtrace showing an
AppArmorBug because that file unsurprisingly doesn't end up in the
active_profiles filelist.

Handle this more gracefully by adding a read_error_fatal parameter to
read_profile() that, if set, forwards the exception. With that,
aa-mergeprof doesn't try to list the profiles in this non-existing file.

Note that all other callers of read_profile() continue to ignore read
errors, because aborting just because a single file in /etc/apparmor.d/
(for example a broken symlink) isn't readable would be a bad idea.
2024-11-01 22:39:32 +01:00
John Johansen
d5777c0403 Merge ProfileStorage: store correct name
Instead of always storing the name of the main profile, store the child
profile/hat name if we are in a child profile or hat.

As a result, we always get the correct "profile xy" header even for
child profiles when dumping the ProfileStorage object.

Also extend the tests to check that the name gets stored correctly.

.

Add aa-complain tests for profile with hats and subprofiles

So far, change_profile_flags() in aa.py is the only user of
ProfileStorage's 'name'.

Rewrite minitools test_cleanprof() so that most of its code can be
reused, and add a test that runs 'aa-complain
/usr/bin/a/simple/cleanprof/test/profile' on cleanprof.in to ensure
aa-complain still works as expected on subprofiles and hats.

Note: aa-complain $profilename will change the flags of hats, but not
child profiles. This is a known issue, and doesn't change with this MR.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1359
Approved-by: John Johansen <john@jjmx.net>
Merged-by: John Johansen <john@jjmx.net>
2024-10-29 13:48:30 +00:00
Georgia Garcia
a8b6c90d29 Merge common_test setup_aa(): drop try/except
... which only existed for historical reasons

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1389
Approved-by: Ryan Lee <rlee287@yahoo.com>
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
2024-10-29 11:16:30 +00:00
Georgia Garcia
45a3bbb2c9 Merge Several test-libapparmor-test_multi.py fixes
Several fixes for test-libapparmor-test_multi.py and the expected profiles. The most important fix is that testing exec events/rules now works.

Please check the individual commits for details and readable diffs.

MR: https://gitlab.com/apparmor/apparmor/-/merge_requests/1390
Approved-by: Georgia Garcia <georgia.garcia@canonical.com>
Merged-by: Georgia Garcia <georgia.garcia@canonical.com>
2024-10-29 11:15:09 +00:00
Christian Boltz
1f8227e671
Add a test for aa-autodep 2024-10-27 21:55:35 +01:00
Christian Boltz
8eff7cd98f
test-multi: no longer expect testcase01, 12 and 13 to fail
'testcase01', 'testcase12' and 'testcase13' contain a strange mix of
exec and network events.

Nevertheless, there's enough information to parse them as good-enough
exec events. While this is not perfectly correct, it's better than
skipping these logs in this test.

Stop expecting that these profiles have a wrong content, and adjust them
so that they contain the (somewhat) expected exec rule.
2024-10-23 19:25:35 +02:00
Christian Boltz
02e2ce0ad9
test exec events/rules in test-libapparmor-test_multi.py
So far, exec events were accidentally skipped in
test-libapparmor-test_multi.py because aa[profile][hat] was not
initialized, and ask_exec() exited early because of this.

Initialize aa[profile][hat] in the test to fix this.

To avoid that someone needs to select "inherit" each time the tests run,
add an optional default_ans parameter to ask_exec(), and let the test
call it with 'CMD_ix'.

(In case you wonder - defaulting to CMD_cx would ask to sanitize the
environment. CMD_ix avoids this.)

Also, we have to copy over aa[profile][hat] to log_dict in the test
because ask_exec() modifies aa[...], but the test only checks its local
log_dict.

Finally, add the expected exec rules to the *.profile files
2024-10-23 19:25:35 +02:00