From 85e664520271128110718cc741579587b3917048 Mon Sep 17 00:00:00 2001 From: rusty-snake Date: Mon, 24 Jun 2019 17:13:29 +0000 Subject: Improve profile PRs (Related to #2739) (#2784) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add contrib/sort.py and .github/pull_request_temp… * Add usage to sort.py * Install sort.py if contrib-install is set * sort.py: 0644 -> 0755 * Update sort.py * Update pull_request_template.md * Remove checkboxes from PR-Template * Update sort.py * Add examples to sort.py * Update pull_request_template.md Fix path to sort.py, it depend on the distro. * Update pull_request_template.md * Update pull_request_template.md add hint about template --- contrib/sort.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100755 contrib/sort.py (limited to 'contrib') diff --git a/contrib/sort.py b/contrib/sort.py new file mode 100755 index 000000000..d0fcabac2 --- /dev/null +++ b/contrib/sort.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +""" +Sort the items of multi-item options in profiles, the following options are supported: + private-bin, private-etc, private-lib, caps.drop, caps.keep, seccomp.drop, seccomp.drop, protocol + +Usage: + $ ./sort.py /path/to/profile [ /path/to/profile2 /path/to/profile3 ... ] +Keep in mind that this will overwrite your profile(s). + +Examples: + $ ./sort.py MyAwesomeProfile.profile + $ ./sort.py new_profile.profile second_new_profile.profile + $ ./sort.py ~/.config/firejail/*.{profile,inc,local} + $ sudo ./sort.py /etc/firejail/*.{profile,inc,local} + +Exit-Codes: + 0: No Error; No Profile Fixed. + 1: Error, one or more profiles were not processed correctly. + 101: No Error; One or more profile were fixed. +""" + +# Requirements: +# python >= 3.6 +from sys import argv + +def sort_alphabetical(raw_items): + items = raw_items.split(",") + items.sort(key=lambda s: s.casefold()) + return ",".join(items) + +def sort_protocol(protocols): + """sort the given protocole into this scheme: unix,inet,inet6,netlink,packet""" + # shortcut for common protocol lines + if protocols in ("unix", "unix,inet,inet6"): + return protocols + fixed_protocols = "" + present_protocols = { + "unix": False, + "inet": False, + "inet6": False, + "netlink": False, + "packet": False, + } + for protocol in protocols.split(","): + if protocol == "unix": + present_protocols["unix"] = True + elif protocol == "inet": + present_protocols["inet"] = True + elif protocol == "inet6": + present_protocols["inet6"] = True + elif protocol == "netlink": + present_protocols["netlink"] = True + elif protocol == "packet": + present_protocols["packet"] = True + if present_protocols["unix"]: + fixed_protocols += "unix," + if present_protocols["inet"]: + fixed_protocols += "inet," + if present_protocols["inet6"]: + fixed_protocols += "inet6," + if present_protocols["netlink"]: + fixed_protocols += "netlink," + if present_protocols["packet"]: + fixed_protocols += "packet," + return fixed_protocols[:-1] + +def fix_profile(filename): + with open(filename, "r+") as profile: + lines = profile.read().split("\n") + was_fixed = False + fixed_profile = [] + for line in lines: + if line[:12] in ("private-bin ", "private-etc ", "private-lib "): + fixed_line = f"{line[:12]}{sort_alphabetical(line[12:])}" + elif line[:13] in ("seccomp.drop ", "seccomp.keep "): + fixed_line = f"{line[:13]}{sort_alphabetical(line[13:])}" + elif line[:10] in ("caps.drop ", "caps.keep "): + fixed_line = f"{line[:10]}{sort_alphabetical(line[10:])}" + elif line[:8] == "protocol": + fixed_line = f"protocol {sort_protocol(line[9:])}" + else: + fixed_line = line + if fixed_line != line: + was_fixed = True + fixed_profile.append(fixed_line) + if was_fixed: + profile.seek(0) + profile.truncate() + profile.write("\n".join(fixed_profile)) + profile.flush() + print(f"[ Fixed ] {filename}") + return 101 + return 0 + +def main(args): + exit_code = 0 + for filename in args: + try: + if exit_code not in (1, 101): + exit_code = fix_profile(filename) + else: + fix_profile(filename) + except FileNotFoundError: + print(f"[ Error ] Can't find {filename}") + exit_code = 1 + except PermissionError: + print(f"[ Error ] Can't read/write {filename}") + exit_code = 1 + except: + print(f"[ Error ] An error occurred while processing {filename}") + exit_code = 1 + return exit_code + +if __name__ == "__main__": + exit(main(argv[1:])) -- cgit v1.2.3-54-g00ecf