diff options
author | rusty-snake <print_hello_world+Public@protonmail.com> | 2019-06-24 17:13:29 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-24 17:13:29 +0000 |
commit | 85e664520271128110718cc741579587b3917048 (patch) | |
tree | d6f73acb1f61d93dc9a5ff6c7812010082201bb3 /contrib | |
parent | disable firetunnel at config time (#2793) (diff) | |
download | firejail-85e664520271128110718cc741579587b3917048.tar.gz firejail-85e664520271128110718cc741579587b3917048.tar.zst firejail-85e664520271128110718cc741579587b3917048.zip |
* 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
Diffstat (limited to 'contrib')
-rwxr-xr-x | contrib/sort.py | 115 |
1 files changed, 115 insertions, 0 deletions
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 @@ | |||
1 | #!/usr/bin/env python3 | ||
2 | """ | ||
3 | Sort the items of multi-item options in profiles, the following options are supported: | ||
4 | private-bin, private-etc, private-lib, caps.drop, caps.keep, seccomp.drop, seccomp.drop, protocol | ||
5 | |||
6 | Usage: | ||
7 | $ ./sort.py /path/to/profile [ /path/to/profile2 /path/to/profile3 ... ] | ||
8 | Keep in mind that this will overwrite your profile(s). | ||
9 | |||
10 | Examples: | ||
11 | $ ./sort.py MyAwesomeProfile.profile | ||
12 | $ ./sort.py new_profile.profile second_new_profile.profile | ||
13 | $ ./sort.py ~/.config/firejail/*.{profile,inc,local} | ||
14 | $ sudo ./sort.py /etc/firejail/*.{profile,inc,local} | ||
15 | |||
16 | Exit-Codes: | ||
17 | 0: No Error; No Profile Fixed. | ||
18 | 1: Error, one or more profiles were not processed correctly. | ||
19 | 101: No Error; One or more profile were fixed. | ||
20 | """ | ||
21 | |||
22 | # Requirements: | ||
23 | # python >= 3.6 | ||
24 | from sys import argv | ||
25 | |||
26 | def sort_alphabetical(raw_items): | ||
27 | items = raw_items.split(",") | ||
28 | items.sort(key=lambda s: s.casefold()) | ||
29 | return ",".join(items) | ||
30 | |||
31 | def sort_protocol(protocols): | ||
32 | """sort the given protocole into this scheme: unix,inet,inet6,netlink,packet""" | ||
33 | # shortcut for common protocol lines | ||
34 | if protocols in ("unix", "unix,inet,inet6"): | ||
35 | return protocols | ||
36 | fixed_protocols = "" | ||
37 | present_protocols = { | ||
38 | "unix": False, | ||
39 | "inet": False, | ||
40 | "inet6": False, | ||
41 | "netlink": False, | ||
42 | "packet": False, | ||
43 | } | ||
44 | for protocol in protocols.split(","): | ||
45 | if protocol == "unix": | ||
46 | present_protocols["unix"] = True | ||
47 | elif protocol == "inet": | ||
48 | present_protocols["inet"] = True | ||
49 | elif protocol == "inet6": | ||
50 | present_protocols["inet6"] = True | ||
51 | elif protocol == "netlink": | ||
52 | present_protocols["netlink"] = True | ||
53 | elif protocol == "packet": | ||
54 | present_protocols["packet"] = True | ||
55 | if present_protocols["unix"]: | ||
56 | fixed_protocols += "unix," | ||
57 | if present_protocols["inet"]: | ||
58 | fixed_protocols += "inet," | ||
59 | if present_protocols["inet6"]: | ||
60 | fixed_protocols += "inet6," | ||
61 | if present_protocols["netlink"]: | ||
62 | fixed_protocols += "netlink," | ||
63 | if present_protocols["packet"]: | ||
64 | fixed_protocols += "packet," | ||
65 | return fixed_protocols[:-1] | ||
66 | |||
67 | def fix_profile(filename): | ||
68 | with open(filename, "r+") as profile: | ||
69 | lines = profile.read().split("\n") | ||
70 | was_fixed = False | ||
71 | fixed_profile = [] | ||
72 | for line in lines: | ||
73 | if line[:12] in ("private-bin ", "private-etc ", "private-lib "): | ||
74 | fixed_line = f"{line[:12]}{sort_alphabetical(line[12:])}" | ||
75 | elif line[:13] in ("seccomp.drop ", "seccomp.keep "): | ||
76 | fixed_line = f"{line[:13]}{sort_alphabetical(line[13:])}" | ||
77 | elif line[:10] in ("caps.drop ", "caps.keep "): | ||
78 | fixed_line = f"{line[:10]}{sort_alphabetical(line[10:])}" | ||
79 | elif line[:8] == "protocol": | ||
80 | fixed_line = f"protocol {sort_protocol(line[9:])}" | ||
81 | else: | ||
82 | fixed_line = line | ||
83 | if fixed_line != line: | ||
84 | was_fixed = True | ||
85 | fixed_profile.append(fixed_line) | ||
86 | if was_fixed: | ||
87 | profile.seek(0) | ||
88 | profile.truncate() | ||
89 | profile.write("\n".join(fixed_profile)) | ||
90 | profile.flush() | ||
91 | print(f"[ Fixed ] {filename}") | ||
92 | return 101 | ||
93 | return 0 | ||
94 | |||
95 | def main(args): | ||
96 | exit_code = 0 | ||
97 | for filename in args: | ||
98 | try: | ||
99 | if exit_code not in (1, 101): | ||
100 | exit_code = fix_profile(filename) | ||
101 | else: | ||
102 | fix_profile(filename) | ||
103 | except FileNotFoundError: | ||
104 | print(f"[ Error ] Can't find {filename}") | ||
105 | exit_code = 1 | ||
106 | except PermissionError: | ||
107 | print(f"[ Error ] Can't read/write {filename}") | ||
108 | exit_code = 1 | ||
109 | except: | ||
110 | print(f"[ Error ] An error occurred while processing {filename}") | ||
111 | exit_code = 1 | ||
112 | return exit_code | ||
113 | |||
114 | if __name__ == "__main__": | ||
115 | exit(main(argv[1:])) | ||