Split is_covered() in capability.py into
- is_covered_localparts() for rule-specific code
- is_covered() for common code - located in __init__.py
The object type comparison now uses type(self) and a slightly different
error message to make it usable everywhere.
Also rename rule_obj to other_rule which is more self-explaining
(inspired by the parameter name in the is_covered() dummy in __init__.py).
v2:
- remove check_allow_deny and check_audit parameters from
is_covered_localvars()
Acked-by: Steve Beattie <steve@nxnw.org>
If one of the testcases fail, this goes unnoticed in "make coverage".
This patch changes the Makefile so that test failures let
"make coverage" fail.
You can use make COVERAGE_IGNORE_FAILURES=true coverage to build
coverage data even if some tests fail.
Signed-off-by: Steve Beattie <steve@nxnw.org>
(which was most probably meant as an Acked-by)
Also Acked-by: <timeout> ;-)
For reasons that are unclear, python's setuptools doesn't install
recursively from a directory, meaning that on make install, the new
Rules/Ruleset classes were not being installed. This patch causes
the rule subdirectory to be included.
Bug: https://bugs.launchpad.net/bugs/1407437
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Tyler Hicks <tyhicks@canonical.com>
adds some tests for severity.py and improves the test coverage to
nearly 100% (only 3 partial left).
Added tests and details (all in SeverityVarsTest):
- move writing the tunables file from setUp() into _init_tunables() for
more flexibility (allows to specify other file content)
- test adding to a variable (+=)
- test #include
- make sure double definition of a variable fails
- make sure redefinition of non-existing variable fails
BTW: even the comment added to VARIABLE_DEFINITIONS contributes to
the coverage ;-)
severity.py passes all added tests, however I should note that including
a non-existing file is silently ignored.
Acked-by: Kshitij Gupta <kgupta8592@gmail.com>
This patch hides raw_rule within the BaseRule class by making parse() be
a class method for all the rule types, implemented via a rule-specific
abstract method _parse() that returns a parsed Rule object.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This patch integrated the new capability rule class into aa.py and
cleanprof.py.
Patch changes:
v6:
- fix logic around same_file in cleanprofile.py that was causing
capabilities to be deleted when they weren't covered by an
abstraction.
v5:
- merge my changes into Christian's original patches
- use CapabilityRule.parse() for parsing raw capability rules and
getting a CapabilityRule instance back
- cope with move of parse_modifiers back into rule/__init__.py.
Originally-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Patch changes:
v5:
- merge my changes into Christian's original patches
- update to use CapabilityRule.parse() as the entry point for
parsing raw rules and getting a CapabilityRule instance in
return.
Originally-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This patch adds four classes - two "base" classes and two specific for
capabilities:
utils/apparmor/rule/__init__.py:
class base_rule(object):
Base class to handle and store a single rule
class base_rules(object):
Base class to handle and store a collection of rules
utils/apparmor/rule/capability.py:
class capability_rule(base_rule):
Class to handle and store a single capability rule
class capability_rules(base_rules):
Class to handle and store a collection of capability rules
Changes:
v5:
- flattened my changes into Christian's patches
- pull parse_modifiers into rule/__init__.py
- pull parse_capability into rule/capability.py
- make CapabiltyRule.parse() be the class/static method for parsing
raw capability rules.
- parse_capability: renamed inlinecomment and rawrule to comment
and raw_rule to be consistent with CapabilityRule fields.
Originally-by: Christian Boltz <apparmor@cboltz.de>
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
When using recursive_print for debugging, RawRules objects weren't
reporting detailed information. This patch fixes that, as well as fixing
some indenting issues in the output.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Those *.spec{,.in} files were not updated for years (last change
2006/2007) and don't fit the current "one tarball for everything" model.
Acked-by: Steve Beattie <steve@nxnw.org>
LOG_MODE_RE (used in validate_log_mode() in aamode.py) just checked if
the given parameter contains one of the possible matches. This resulted
in "invalid" being a valid log mode (from audit.log requested_mask or
denied_mask) because it contains 'a', which is a valid file mode.
This patch wraps the regex into ^(...)+$ to make sure the full
string contains only allowed file modes.
The patch also adds some tests for validate_log_mode().
Acked-by: Steve Beattie <steve@nxnw.org>
aa.py uses profile_data[profile][hat]['change_profile'] at various
places. However, there are also two places that use 'changes_profile'
(note the additional 's'), which should also be 'change_profile'.
Acked-by: Steve Beattie <steve@nxnw.org>
This patch converts a ValueError raised when parsing of a permission
mode fails into an AppArmorBug with better diagnostic information, and
adds a test case to confirm that the exception is raised.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Also change check_for_apparmor() to allow easier testing by optionally
specifying alternative locations for /proc/filesystems and /proc/mounts
as parameter.
Note that the code in check_for_apparmor() differs from what the comment
says - valid_path() only does syntax checks, but doesn't check if the
directory exists. I added a comment saying exactly that.
Acked-by: Steve Beattie <steve@nxnw.org>
- replace MODE_MAP_RE regex with MODE_MAP_SET set
- change sub_str_to_mode() to use MODE_MAP_SET set instead of MODE_MAP_RE
- change split_log_mode to use split() instead of a regex
Patch by Peter Maloney <peter.maloney@brockmann-consult.de>
Acked-by: Christian Boltz <apparmor@cboltz.de>
split_log_mode() change also
Acked-by: Seth Arnold <seth.arnold@canonical.com>
performance improvement
Patch by Peter Maloney <peter.maloney@brockmann-consult.de>
Acked-by: Christian Boltz <apparmor@cboltz.de>
(previous patch version (with minor difference) also
Acked-by: Seth Arnold <seth.arnold@canonical.com>)
interpreters, it used
aa[profile][hat]['path'][interpreter_path]['mode']
instead of
aa[profile][hat]['allow']['path'][interpreter_path]['mode']
The ['allow'] part was missing.
Acked-by: Steve Beattie <steve@nxnw.org>
This patch pulls out all the common processing for writing out
each of the prior segments that need to be written before writing
the current segment into a function called 'write_prior_segments',
reducing a bunch of ugly duplication.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
The assignment for setting segments['include'] = True was wrong,
it occured inside the 'if not segments['include'] and True in
segments.values():' block, whereas it needed to always get set outside
of that if test.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This patch
- fixes a check that used if "aa[profile][hat][incname]:" instead of
"if aa[profile][hat]['include'].get(incname, False):" ("['include']"
was missing) which means the performance shortcut was never hit
- avoids auto-created empty and superfluous hashers in
aa[profile][hat]['allow']['path'] and
include[incfile][incfile][allow]['path']
- adds the filename to the "Can't find system log" exception
Patch by Peter Maloney <peter.maloney@brockmann-consult.de>
Changes compared to the original patch:
- change back quoting in the exception message to '...'
Acked-By: Christian Boltz <apparmor@cboltz.de>
present as a function (which it is not in Python3, even though it was
under an if else python version check).
The following patch:
- checks the __builtins__ module for existence of raw_input and sets
it up for Python3
Acked-by: Steve Beattie <steve@nxnw.org>
The diff displayed by (V)iew changes in aa-logprof lacks leading
whitespace because it bases the whitespace on the indention level of the
closing "}".
Besides that, it uses different values for the indention level for newly
added rule types than for existing rule types. (For example, if a
profile already had a network rule, added network rules will get a
different indention level.) However you won't notice this because
currently it doesn't indent the rules at all ;-)
This patch fixes serialize_profile_from_old_profile() in aa.py so that
it always uses the correct indention level.
Also clean up and simplify how the profile is written in the end (when
matching RE_PROFILE_END) - we already have "write_methods", so we can
just re-use it instead of "manually" calling one write_* function after
the other. Unfortunately dicts don't keep their original order,
therefore I had to introduce "default_write_order".
Finally, add some missing rule types to "segments" to avoid key errors.
Acked-by: Steve Beattie <steve@nxnw.org>
When aa-logprof asks for adding capability rules, it also offers the
Audi(t) option. Unfortunately, this option does nothing ;-)
This patch fixes ask_the_question() so that it really ;-) allows to
switch the audit flag on and off. It also initializes the "audit"
variable to make sure the next capability doesn't inherit the audit flag
used for the previous capability.
Acked-by: Steve Beattie <steve@nxnw.org>
This patch for recursive_print() in common.py fixes printing dicts with
py3. It also replaced the tabs() lambda function with a plain string,
and the brace() lambda function with a simple formatstring to make the
code easier to understand.
Also add support for nested lists - for the start and end of each list,
print a [ and ]. Without that, you get a long list of items without an
indicator if/when a new parent list starts.
Acked-by: Steve Beattie <steve@nxnw.org>
When aa-logprof asks for a capability, you'll see something like
WARN: unknown capability: CAP_block_suspend
The reason for the warning and "Severity: unknown" is that severity.db
contains the capability names in uppercase, but ask_the_question() calls
sev_db.rank with the capability in lowercase.
This patch converts the "CAP_$capability" string to uppercase before
doing the lookup.
Acked-by: Steve Beattie <steve@nxnw.org>
Also add a testcase (written by Steve Beattie) to ensure this stays fixed.
Acked-by: Seth Arnold <seth.arnold@canonical.com>
Acked-by: Christian Boltz <apparmor@cboltz.de>
utils/Makefile contains a grep -v "undefined name _". Some manual
testing shows that pyflakes doesn't print any warning about "_", so
this grep is superfluous.
Removing the grep also means we don't need a tempfile for the pyflakes
output anymore, which simplifies the pyflakes call a lot.
Acked-by: Steve Beattie <steve@nxnw.org>
The recent re-work of the severity.db tests were not verified to
pyflakes clean. All but one of pyflakes co are of marginal impact
(assigning to a variable that isn't later referenced); however, one
legitimate issue it detected is that I inadvertently created two test
cases with the same method name, so only one test case would actually
be used.
The following patch fixes the issues.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This commit renames the unit test script for the severity db so that it
will be included in the 'make check' and 'make coverage*' targets.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This patch fixes Severity.__init__() when it is not given an argument to
raise an AppArmor exception rather than returning a Severity object in
an incompletely initialized state. It also adjusts a test case covering
this situation.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
This patch is a re-work of the severity_test.py tests, to break them
up into individual unit tests, and to add coverage for detecting
an invalid severity database (it does reduce the coverage for walking
profiles to find variable declarations, but that should be pulled out of
the severity handling code anyway).
Note that the last test case will fail, because even though the code
path in Severity.__init__() looks like it will return None if no path
is given, a Severity object in a half-state of initialization will
actually be returned.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
for r2769, which only checked for "exists")
Also allow everything except directories as logfile argument in
aa-genprof.
Acked-by: Steve Beattie <steve@nxnw.org>
This patch adds support for generating test coverage information for the
python utils.
To view a text based report, in the test subdirectory do:
make coverage-report
To generate detailed html reports, do:
make coverage-html
And then point your web browser at
$(YOUR_CURRENT_WORKING_TREE)/utils/test/htmlcov/index.html .
An alternate output location can be specified by setting the
COVERAGE_OUT variable, e.g.
make coverage-html COVERAGE_OUT=/tmp/coverage/
(the output directory does not need to exist beforehand.)
To generate only the coverage data, do:
make coverage
or
make .coverage
(The coverage data generated by python is stored in the .coverage
file.) This essentially runs make check, using a single python
interpreter, and records which lines and branches of the python code
were exercised.
Signed-off-by: Steve Beattie <steve@nxnw.org>
Acked-by: Christian Boltz <apparmor@cboltz.de>
Acked-by: John Johansen <john.johansen@canonical.com>
From: Peter Maloney <peter.maloney@brockmann-consult.de>
This patch allows the common idiom 'aa-logprof -f <(SOME COMMAND)' to
work,
Acked-by: Steve Beattie <steve@nxnw.org>