Change aa-notify parse_message() to also honor complain mode log events.
This affects both modes - desktop notifications and the summary report.
Acked-by: Steve Beattie <steve@nxnw.org>
Add setUp() to AATest that sets "self.maxDiff = None" (unlimited).
This gives us unlimited array diffs everywhere where AATest is used.
Also rename several setUp() functions in test-regex_matches.py to
AASetup() to avoid that the shiny new AATest setUp() gets overwritten.
Acked-by: Steve Beattie <steve@nxnw.org>
As requested by Steve, also add an example AASetup() to test-example.py.
This ignores the sniplets generated by profiles/Makefile, but doesn't
ignore local/README because it doesn't have a dot in its name.
Acked-by: John Johansen <john.johansen@canonical.com>
Add several missing network DOMAINs to the apparmor.d manpage.
The list is based on the list that utils/vim/Makefile generates.
Acked-by: John Johansen <john.johansen@canonical.com>
reported by darix on IRC. This is needed if you have a bigger setup with
dovecot on a different (or multiple) machines
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
Replace usage of RE_PROFILE_CAP and RE_PROFILE_NETWORK with
CapabilityRule.match() and NetworkRule.match() calls.
This also means aa.py doesn't need to import those regexes anymore.
As a side effect of this change, test-regex_matches.py needs a small
fix because it imported RE_PROFILE_CAP from apparmor.aa instead of
apparmor.regex.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Add match() and _match() class methods to rule classes:
- _match() returns a regex match object for the given raw_rule
- match() converts the _match() result to True or False
The primary usage is to get an answer to the question "is this raw_rule
your job?". (For a moment, I thought about naming the function
*Rule.myjob() instead of *Rule.match() ;-)
My next patch will change aa.py to use *Rule.match() instead of directly
using RE_*, which will make the import list much shorter and hide
another implementation detail inside the rule classes.
Also change _parse() to use _match() instead of the regex, and add some
tests for match() and _match().
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Change aa.py to use NetworkRule and NetworkRuleset instead of a
sub-hasher to store, check and write network rules. In detail:
- drop profile_known_network() and use is_known_rule() instead
- replace match_net_includes() usage with match_includes() calls
- drop delete_net_duplicates(), use the code in NetworkRule and
NetworkRuleset instead
- make match_net_includes() (still used by aa-mergeprof) a wrapper for
match_includes()
- drop all the network rule parsing from parse_profile_data() and
serialize_profile_from_old_profile() - instead, just call
NetworkRule.parse()
- now that write_net_rules() got fixed, drop it ;-)
- change write_netdomain to use NetworkRuleset
- drop netrules_access_check() - that's is_covered() now
- use 'network' instead of 'netdomain' as storage keyword (log events
still use 'netdomain')
Also update cleanprofile.py to use the NetworkRuleset class.
This also means to delete the (now superfluous) delete_net_duplicates()
function.
Finally, there are some changes in regex.py:
- change RE_PROFILE_NETWORK in regex.py to named matches and to use
RE_COMMA_EOL (not only RE_EOL)
- drop the no longer needed RE_NETWORK_FAMILY and RE_NETWORK_FAMILY_TYPE
(rule/network.py has regexes that check against the list of available
keywords)
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Add utils/test/test-network.py with tests for NetworkRule and
NetworkRuleset.
The tests are hopefully self-explaining, so let me just mention the most
important things:
- I started to play with namedtuple, which looks very useful (see "exp")
- the test loops make the tests much more readable (compare with
test-capability.py!) and make it easy to add some more tests
- 100% coverage :-)
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Add utils/apparmor/rule/network.py with the NetworkRule and
NetworkRuleset classes. These classes are meant to handle network rules.
In comparison to the existing code in aa.py, relevant news are:
- the keywords are checked against a list of allowed domains, types and
protocols (these lists are based on what the utils/vim/Makefile
generates - on the long term an autogenerated file with the keywords
for all rule types would be nice ;-)
- there are variables for domain and type_or_protocol instead of
first_param and second_param. (If someone is bored enough to map the
protocol "shortcuts" to their expanded meaning, that shouldn't be too
hard.)
- (obviously) more readable code because we have everything at one place
now
- some bugs are fixed along the way (for example, "network foo," will now
be kept, not "network foo bar," - see my last mail about
write_net_rules() for details)
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
CleanProf.remove_duplicate_rules() didn't call
$profile['capability'].delete_duplicates()
because aa-cleanprof sets same_file=True.
Fix this by calling delete_duplicates(None) so that it
only checks the profile against itsself.
Note: this is only needed if the to-be-cleaned profile doesn't
contain any include rules - with includes present, the
"for inc in includes:" block already called delete_duplicates()
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Implement in-profile de-duplication in BaseRuleset (currently affects
"only" CapabilityRuleset, but will also work for all future *Ruleset
classes).
Also change 'deleted' to be a simple counter and add some tests that
verify the in-profile deduplication.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
test_parse_modifiers_invalid() uses a hand-broken ;-) regex to parse
only the allow/deny/audit keywords. This test applies to all rule types
and doesn't contain anything specific to capability or other rules,
therefore it should live in test-baserule.py
Moving that test also means to move the imports for parse_modifiers and
re around (nothing else in test-capability.py needs them).
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Add some tests for the Baserule class to cover the 3 functions that must
be re-implemented in each rule class. This means we finally get 100%
test coverage for apparmor/rule/__init__.py ;-)
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Ensure nosetests sees all tests in the tests[] tuples. This requires
some name changes because nosetests thinks all function names containing
"test" are tests. (A "not a test" docorator would be an alternative, but
that would require some try/except magic to avoid a dependency on nose.)
To avoid nosetests thinks the functions are a test,
- rename setup_all_tests() to setup_all_loops()
- rename regex_test() to _regex_test() (in test-regex_matches.py)
Also add the module_name as parameter to setup_all_loops and always run
it (not only if __name__ == '__main__').
Known issue: nosetests errors out with
ValueError: no such test method in <class ...>: stub_test
when trying to run a single test generated out of tests[].
(debugging hint: stub_test is the name used in setup_test_loop().)
But that's still an improvement over not seeing those tests at all ;-)
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
Assume you have a profile like
/bin/foo {
/etc/ r,
network,
/usr/ r,
}
(important: there must be be a non-path rule between the two path blocks)
Then run aa-logprof and add another path event. When choosing (V)iew changes,
it will crash with a misleading
File ".../utils/apparmor/aamode.py", line 205, in split_mode
other = mode - user
TypeError: unsupported operand type(s) for -: 'collections.defaultdict' and 'set'
The reason for this is our beloved hasher, which is playing funny games
another time.
The patch wraps the hasher usage with a check for the parent element to
avoid auto-creation of empty childs, which then lead to the above crash.
BTW: This is another issue uncovered by the LibreOffice profile ;-)
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
Update the postfix-common abstraction to cope with signal and unix
socket mediation, update the access to the sasl library locations
in a multiarch compliant way, and allow access to limited bits
of the filesystem paths under which postfix chroots itself to
(/var/spool/postfix/ on Ubuntu).
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
serialize_profile_from_old_profiles() calls store_list_var() with an
empty hasher. This fails for "+=" because in this case store_list_var()
expects a non-empty hasher with the variable already defined, and raises
an exception because of the empty hasher.
This patch sets "correct = False" if a "+=" operation appears, which
means the variable will be written in "clean" mode instead.
Adding proper support for "add to variable" needs big changes (like
storing a variable's "history" - where it was initially defined and what
got added where).
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
the LibreOffice profile uncovered that handling of @{var} += is broken:
File ".../utils/apparmor/aa.py", line 3272, in store_list_var
var[list_var] = set(var[list_var] + vlist)
TypeError: unsupported operand type(s) for +: 'set' and 'list'
This patch fixes it:
- change separate_vars() to use and return a set instead of a list
(FYI: separate_vars() is only called by store_list_var())
- adoptstore_list_var() to expect a set
- remove some old comments in these functions
- explain the less-intuitive parameters of store_list_var()
Also add some tests for separate_vars() and store_list_var().
The tests were developed based on the old code, but not all of them
succeed with the old code.
As usual, the tests uncovered some interesting[tm] behaviour in
separate_vars() (see the XXX comments and tell me what the really
expected behaviour is ;-)
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
Move the code that does the c -> a and d -> w replacement in denied_mask
and requested_mask so that it only runs for path and exec events, but not
for other events (like dbus and ptrace). The validate_log_mode() and
log_str_to_mode() calls are also moved.
Technically, this means moving code from parse_event() to the path
and exec sections in add_event_to_tree().
This also means aa-logprof no longer crashes if it hits a ptrace or
dbus event in the log.
The "if dmask:" and "if rmask:" checks are removed - if a path event
doesn't have these two, it is totally broken and worth a aa-logprof
crash ;-)
Also adjust the parse_event() tests to expect the "raw" mask instead of
a set.
This patch fixes
https://bugs.launchpad.net/apparmor/+bug/1426651 and
https://bugs.launchpad.net/apparmor/+bug/1243932
I manually tested that
- c and d log events are still converted to a and w
- aa-logprof handles exec events correctly
- ptrace events no longer crash aa-logprof
Note: add_event_to_tree() is not covered by tests.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
"capability foo".is_covered("deny capability foo") should return False
even if check_allow_deny is False.
Also add some tests with check_allow_deny=False.
Acked-by: Steve Beattie <steve@nxnw.org>
Also add libraries/libapparmor/swig/perl/Makefile.perle (noticed and
proposed by Steve)
With these changes, "bzr status" is clean again after "make distclean"
Acked-by: Steve Beattie <steve@nxnw.org>.
Acked-by: Tyler Hicks <tyhicks@canonical.com>
Thanks to the used data structure, write_net_rules() replaces bare
'network,' rules with the invalid 'network all,' when saving a profile.
This patch makes sure a correct 'network,' rule is written.
Also reset 'audit' to avoid all (remaining) rules get the audit flag
after writing an audit network rule.
Note: The first section of the function (that claims to be responsible
for bare 'network,' rules) is probably never hit - but I'm not too keen
to remove it and try it out ;-)
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
When parsing a profile with named exec rules, the exec target included
the arrow. This resulted in two arrows when writing the profile (and one
more each time the profile was updated).
Fix this by using the match group that only contains the exec target
without the arrow in parse_profile_data() and
serialize_profile_from_old_profile().
References: https://bugs.launchpad.net/apparmor/+bug/1437901
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9.
When evince opens a dvi file, it updates the user fonts using
texlive commands in /usr/share/texlive/texmf-dist/web2c/ (or possibly
/usr/share/texlive/texmf/web2c/ in older releases). This patch adjusts
the sanitized_helper profile to allow these tools to run.
Bug: https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1010909
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-By: Jamie Strandboge <jamie@canonical.com>
write_net_rules() doesn't add a space after 'audit' in two of three
cases, leading to invalid network rules.
This patch adds the missing spaces.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9
write_net_rules() creates invalid rules for network rules with one
parameter (for example "network bluetooth").
Add a trailing comma to create valid rules.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9.
Change serialize_parse_profile_start() to use parse_profile_start()
instead of using duplicated code.
The behaviour is mostly kept, with the exception that the function is
more strict now and raises exceptions instead of ignoring errors.
In practise, this won't change anything because the profiles are parsed
with parse_profile() (which calls parse_profile_start()) - and that
already errors out.
The tests are updated to match the more strict behaviour.
The next step would be to drop serialize_parse_profile_start()
completely, but this isn't urgent and can/should be done when we have
test coverage for serialize_profile_from_old_profile() one day ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
Fix is_skippable_dir() - the regex also matched things like
/etc/apparmor.d/dont_disable, while it should match on the full
directory name.
Also add some tests based on a real-world aa-logprof run (with "print (path)"
in is_skippable_dir()) and some additional "funny"[tm] dirs.
Needless to say that the tests
('dont_disable', False),
('/etc/apparmor.d/cache_foo', False),
will fail with the old is_skippable_dir().
Acked-by: Steve Beattie <steve@nxnw.org>
Replace RE_PROFILE_START with RE_PROFILE_START_2 and adjust all
code sections that used RE_PROFILE_START_2.
The only real change is that test_get_flags_invalid_01 and
test_get_flags_invalid_02 now expect AppArmorException instead of
AppArmorBug.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk
This patch implements attachment handling - aa-logprof now works with
profiles that have an attachment defined, instead of ignoring audit.log
entries for those profiles.
Changes:
- parse_profile_start_line(): remove workaround that merged the
attachment into the profile name
- parse_profile_data(): store attachment when parsing a profile
- update test_parse_profile_start_03, test_serialize_parse_profile_start_03,
test_set_flags_nochange_09 and some parse_profile_start_line() tests -
they now expect correct attachment handling
Acked-by: Steve Beattie <steve@nxnw.org>
this patch makes set_profile_flags more strict:
- raise AppArmorBug if newflags contains only whitespace
- raise AppArmorBug if the file doesn't contain the specified profile or
no profile at all
The tests are adjusted to expect AppArmorBug instead of a silent
failure. Also, some tests are added for profile=None, which means to
change the flags for all profiles in a file.
- test_set_flags_08 is now test_set_flags_invalid_04
- test_set_flags_invalid_03 is changed to only contain one reason for a
failure, not two ;-)
Acked-by: Steve Beattie <steve@nxnw.org>
Changes in set_profile_flags():
- rewrite set_profile_flags to use parse_profile_start_line() and
write_header().
- replace the silent failure for non-existing files with a proper
exception (using lazy programming - the check is done by removing the
"if os.path.isfile()" check, open_file_read then raises the
exception ;-)
- comment out regex_hat_flag and the code that was supposed to handle
hat flags, which were totally broken. We'll need another patch to fix
it, and we also need to decide if we want to do that because it
introduces a behaviour change (currently, aa-complain etc. don't
change hat flags).
The tests for set_profile_flags() are also updated:
- prepend a space to comments because write_header always adds a space
between '{' and the comment
- remove a test with superfluous quotes that are no longer kept (that's
just a profile cleanup, so dropping that test is the easiest way)
- update test_set_flags_10 and test_set_flags_12 to use the correct
profile name
- enable the tests for invalid (empty) flags
- update the test for a non-existing file
Note: test_set_flags_10, test_set_flags_12 and test_set_flags_nochange_09
will fail with this patch applied. The next patch will fix that.
Acked-by: Steve Beattie <steve@nxnw.org>
The Makefiles don't create/need the 'common' symlinks since some time,
which also means we no longer need to have them in .bzrignore.
Acked-by: Steve Beattie <steve@nxnw.org>
if 3/2 == 1:
print("python2 inside")
Add "from __future__ import division" so that python2 returns the
correct result (if needed, as float)
On related news: At least python3 knows how to calculate correctly.
Acked-by: Steve Beattie <steve@nxnw.org> for trunk and 2.9
Merge path handling for 'inode_*' in add_event_to_tree() with the
handling for other path events.
The code is slightly more strict now - 'inode_' in e['operation'] is
replaced with e['operation'].startswith('inode_').
This patch is a cleanup and also a preparation to fix
https://bugs.launchpad.net/apparmor/+bug/1426651 and
https://bugs.launchpad.net/apparmor/+bug/1243932
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked for both 2.9 and trunk.
aa-logprof doesn't ask anything for
type=AVC msg=audit(1427633461.202:281): apparmor="DENIED" operation="chmod" profile="/usr/lib64/firefox/plugin-container" name="/home/cb/.config/ibus/bus/" pid=7779 comm="plugin-containe" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000
This patch fixes this by adding 'chmod' to the list of file operation
types in logparser.py.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
for both trunk and 2.9.
Rewrite parse_profile_start() in aa.py to a more readable version.
The behaviour remains unchanged (and is covered by tests).
The patch also updates the comment about the internal struct of
aa[profile][hat] - initial_comment was missing.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
Change the write_header tests so that the 'profile_keyword' and
'header_comment' parameters can be (and are) tested:
- add a None for both to the existing tests
- add some tests that come with the profile keyword and/or a comment
Acked-by: Steve Beattie <steve@nxnw.org>
- add support for prof_data['header_comment'] (comment after '{')
and prof_data['profile_keyword'] (to force the 'profile' keyword, even
if it isn't needed) to write_header().
(set_profile_flags() will be the only user of these two for now)
- fix a crash if depth is not an integer - for example,
len(' ')/2 # 3 spaces = 1.5
would cause a crash.
Also add a test for 1.5 and 1.3 spaces.
- rewrite the handling of flags to avoid we have to maintain two
different template lines.
- update the tests to set 'profile_keyword' and 'header_comment' to None.
This avoids big changes in the test code. I'll send another patch that
makes sure profile_keyword and header_comment are tested ;-)
Acked-by: Steve Beattie <steve@nxnw.org>