From 3d01d2e744f6d9119365f9f4689f67506d59608f Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Nov 05 2017 18:07:23 +0000 Subject: Rework grouping and fix line continuation support --- diff --git a/analyze-protections.py b/analyze-protections.py old mode 100644 new mode 100755 index b08516b..4e7c03a --- a/analyze-protections.py +++ b/analyze-protections.py @@ -49,7 +49,7 @@ def slurp(name, contents): if line.startswith('#') or not line: break if line.endswith('\\'): - logical_line += line + ' ' + logical_line += line[:-1].rstrip() + ' ' continue else: logical_line += line @@ -61,18 +61,18 @@ def slurp(name, contents): if not logical_line: continue - m = re.match(r'\[(\w+)\]', line) + m = re.match(r'\[(\w+)\]', logical_line) if m: section = m.group(1) continue - m = re.match(r'(\w+)=(.*)', line) + m = re.match(r'(\w+)=(.*)', logical_line) if m: key, value = m.group(1), m.group(2) config[section][key].append(value) continue - raise SyntaxError(f'{name}, line {line_num}: cannot parse "{line}"') + print(f'{name}, line {line_num}: cannot parse {logical_line!r}') return config def get_single_config(config, section, name, default=None): @@ -172,12 +172,11 @@ def count_protections(Protections, name, config): Protections['none'] += 1 def analyze(Types, Protections, name): - print(f'============================== {name} ==============================') - # We use systemctl cat to include any drop-ins. It is likely that # this makes no difference (the distribution doesn't include any harderning # features in drop-ins), but let's do this just in case. - contents = subprocess.check_output(['systemctl', 'cat', name], universal_newlines=True) + contents = subprocess.check_output(['systemctl', 'cat', '--root=/', name], + universal_newlines=True) config = slurp(name, contents) # pprint.pprint(config) @@ -188,16 +187,40 @@ def analyze(Types, Protections, name): if type in {'simple', 'forking', 'dbus', 'notify'}: count_protections(Protections, name, config) +def find_srpm_names(files): + ans = collections.defaultdict(list) + + for file in files: + cmd = ['rpm', '--qf', r'%{name}\n', '-qf', str(file)] + out = subprocess.run(cmd, stdout=subprocess.PIPE, universal_newlines=True) + # source rpm name would be nicer, but that's beyond the capabilities of rpm apparently + + line = out.stdout.strip() + if line.startswith('file '): + print(line) + continue + ans[line].append(file) + + return ans + if __name__ == '__main__': opts = parser().parse_args() + by_srpm = find_srpm_names(opts.files) + Types = collections.Counter() Protections = collections.Counter() - for file in opts.files: - if file.is_symlink(): - # an alias, ignore - continue - analyze(Types, Protections, file.name) + + for srpm, files in by_srpm.items(): + for file in files: + if file.is_symlink(): + # an alias, ignore + continue + print(f'==================== {file.name:<20} {"(" + srpm + ")":<15} =======================') + try: + analyze(Types, Protections, file.name) + except SyntaxError as e: + print(e) pprint.pprint(Types) pprint.pprint(Protections)