71 lines
2.3 KiB
Python
Executable file
71 lines
2.3 KiB
Python
Executable file
#!/usr/bin/env python
|
|
|
|
import argparse
|
|
import os
|
|
import shutil
|
|
import sys
|
|
|
|
from pathlib import Path
|
|
|
|
def prune_unused_profiles(dest_profile_folder: Path) -> None:
|
|
for root, dirs, files in os.walk(dest_profile_folder):
|
|
for name in files:
|
|
target_binary = Path('/' + name.replace('.', '/'))
|
|
if not target_binary.exists():
|
|
profile_path = os.path.join(root, name)
|
|
print(f'Removing {profile_path}')
|
|
os.remove(profile_path)
|
|
|
|
for folder in dirs:
|
|
fullpath = os.path.join(root, folder)
|
|
if not os.listdir(fullpath):
|
|
print(f'Removing empty directory {fullpath}')
|
|
os.rmdir(fullpath)
|
|
|
|
|
|
def install_profiles(source_folder: Path, dest_profile_folder: Path) -> None:
|
|
for root, dirs, files in os.walk(source_folder):
|
|
for name in files:
|
|
target_binary = Path('/' + name.replace('.', '/'))
|
|
print(f'Testing {target_binary}')
|
|
if target_binary.exists():
|
|
print(f'Adding profile for {target_binary}')
|
|
profile_path = os.path.join(root, name)
|
|
shutil.copy2(profile_path, dest_profile_folder)
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description='Install or prune apparmor profiles',
|
|
usage='/sync-apparmor.py ~/playground/apparmor-profiles/ /etc/apparmor.d/local/',
|
|
)
|
|
parser.add_argument(
|
|
'--dry-run', '-d', action='store_true',
|
|
help="Don't change files, only output what would be done")
|
|
parser.add_argument(
|
|
'--prune-destination', '-r', action='store_true',
|
|
help="Check whether target binaries for profiles in dest exist. Delete profiles if not.")
|
|
parser.add_argument(
|
|
'--sync-source', '-s', action='store_true',
|
|
help="Check whether target binaries for profiles in dest exist. Copy profiles from source if so.")
|
|
parser.add_argument(
|
|
'source_folder', type=Path,
|
|
help='Folder to copy AppArmor profiles from')
|
|
parser.add_argument(
|
|
'dest', type=Path,
|
|
help='Folder to copy AppArmor profiles to')
|
|
args = parser.parse_args()
|
|
|
|
if Path.home() == Path('/root'):
|
|
print('$HOME is /root, maybe you forgot to use sudo -E?')
|
|
|
|
if args.dry_run:
|
|
shutil.copy2 = lambda *args: None
|
|
os.remove = lambda *args: None
|
|
os.rmdir = lambda *args: None
|
|
none_defined = not(args.prune_destination and args.sync_source)
|
|
if none_defined:
|
|
prune_unused_profiles(args.dest)
|
|
install_profiles(args.source_folder, args.dest)
|
|
if args.prune_destination:
|
|
prune_unused_profiles(args.dest)
|
|
if args.sync_source:
|
|
install_profiles(args.source_folder, args.dest)
|