mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 10:07:12 +00:00
test_profile.sh contained some bash-specific code and a bug in a regex that failed to flag some profiles where read access to their attachment path was not allowed. Replace it with a Python script, more robust and maintenable. Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
91 lines
2.5 KiB
Python
Executable File
91 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys
|
|
import subprocess
|
|
import re
|
|
import os
|
|
|
|
|
|
VERBOSE = bool(os.environ.get('VERBOSE'))
|
|
|
|
NAME_RE = re.compile(r'^Name:\s*(\S+)')
|
|
PERMS_ALL = re.compile(r'^Perms:.*r.*:.*:.*\(/\{?,?\*\*,?}?\)')
|
|
ATTACH_RE = re.compile(r'^Attachment:\s*(.+)')
|
|
|
|
RED = '\033[0;31m'
|
|
GREEN = '\033[0;32m'
|
|
NORMAL = '\033[0m'
|
|
|
|
def die(msg):
|
|
print(RED + msg + NORMAL, file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
def check_profile(name, prof_file, skip, attachment, lines):
|
|
if skip:
|
|
if VERBOSE:
|
|
print('Profile "{}" skipped: {}'.format(name, skip))
|
|
return
|
|
|
|
pat = re.compile(r'^Perms:.*r.*:.*:.*\({}\)'.format(re.escape(attachment)))
|
|
for l in lines:
|
|
if pat.match(l):
|
|
if VERBOSE:
|
|
print(GREEN + 'Profile {} ({}): OK "{}" found'.format(prof_file, name, attachment) + NORMAL)
|
|
return
|
|
|
|
die('Profile {} ({}): ERROR: no Perms rule for "{}".'.format(prof_file, name, attachment))
|
|
|
|
def process_profile(profile, extra_args):
|
|
cmd = ['../parser/apparmor_parser'] + extra_args + ['-d', profile]
|
|
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)
|
|
if proc.returncode != 0:
|
|
die('ERROR: Failed to parse "{}": {}'.format(profile, proc.stdout.strip()))
|
|
|
|
lines = proc.stdout.splitlines()
|
|
curr_name = ''
|
|
attachment = ''
|
|
skip = None
|
|
in_entries = False
|
|
block = []
|
|
|
|
for line in lines:
|
|
m = NAME_RE.match(line)
|
|
if m:
|
|
if curr_name:
|
|
# check previously found profile
|
|
check_profile(curr_name, profile, skip, attachment, block)
|
|
|
|
# remember newly found profile
|
|
curr_name = m.group(1)
|
|
attachment = ''
|
|
skip = None
|
|
in_entries = False
|
|
block = []
|
|
continue
|
|
|
|
if PERMS_ALL.match(line):
|
|
skip = 'All files available'
|
|
continue
|
|
|
|
m = ATTACH_RE.match(line)
|
|
if m:
|
|
attachment = m.group(1)
|
|
if attachment == '<NULL>':
|
|
skip = 'no attachment'
|
|
continue
|
|
|
|
if line.strip() == '--- Entries ---':
|
|
in_entries = True
|
|
continue
|
|
|
|
if in_entries:
|
|
block.append(line)
|
|
|
|
# Last profile
|
|
check_profile(curr_name, profile, skip, attachment, block)
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) < 2:
|
|
print('Usage: {0} <profile-file> [parser_extra_args]'.format(sys.argv[0]))
|
|
sys.exit(1)
|
|
process_profile(sys.argv[1], sys.argv[2:])
|