diff options
author | Hank Leininger <hlein@korelogic.com> | 2020-10-15 18:12:01 -0600 |
---|---|---|
committer | Hank Leininger <hlein@korelogic.com> | 2020-10-15 18:12:01 -0600 |
commit | 9cb663b2ce2431b95402c8972b5efd8b4bf11c20 (patch) | |
tree | 141b4a6eee61822ef8fc0f0b93c75d5b6514c14a /contrib/jail_prober.py | |
parent | Formatting for better PEP-8 compliance (diff) | |
download | firejail-9cb663b2ce2431b95402c8972b5efd8b4bf11c20.tar.gz firejail-9cb663b2ce2431b95402c8972b5efd8b4bf11c20.tar.zst firejail-9cb663b2ce2431b95402c8972b5efd8b4bf11c20.zip |
Strip out \r's.
As is, this will not execute because env attempts to locate the
executable 'python\r', which does not exist.
Signed-off-by: Hank Leininger <hlein@korelogic.com>
Diffstat (limited to 'contrib/jail_prober.py')
-rwxr-xr-x | contrib/jail_prober.py | 372 |
1 files changed, 186 insertions, 186 deletions
diff --git a/contrib/jail_prober.py b/contrib/jail_prober.py index 67a5186ae..67e851282 100755 --- a/contrib/jail_prober.py +++ b/contrib/jail_prober.py | |||
@@ -1,186 +1,186 @@ | |||
1 | #!/usr/bin/env python3 | 1 | #!/usr/bin/env python3 |
2 | # This file is part of Firejail project | 2 | # This file is part of Firejail project |
3 | # Copyright (C) 2014-2020 Firejail Authors | 3 | # Copyright (C) 2014-2020 Firejail Authors |
4 | # License GPL v2 | 4 | # License GPL v2 |
5 | """ | 5 | """ |
6 | Figure out which profile options may be causing a particular program to break | 6 | Figure out which profile options may be causing a particular program to break |
7 | when run in firejail. | 7 | when run in firejail. |
8 | 8 | ||
9 | Instead of having to comment out each line in a profile by hand, and then | 9 | Instead of having to comment out each line in a profile by hand, and then |
10 | enable each line individually until the bad line or lines are found, this | 10 | enable each line individually until the bad line or lines are found, this |
11 | largely automates the process. Users only have to provide the path to the | 11 | largely automates the process. Users only have to provide the path to the |
12 | profile, program name, and answer 'y' for yes or 'n' for no when prompted. | 12 | profile, program name, and answer 'y' for yes or 'n' for no when prompted. |
13 | 13 | ||
14 | After completion, you'll be provided with some information to copy and then | 14 | After completion, you'll be provided with some information to copy and then |
15 | paste into a GitHub issue in the Firejail project repository: | 15 | paste into a GitHub issue in the Firejail project repository: |
16 | https://github.com/netblue30/firejail/issues | 16 | https://github.com/netblue30/firejail/issues |
17 | 17 | ||
18 | Paths to the profile should be absolute. If the program is in your path, then | 18 | Paths to the profile should be absolute. If the program is in your path, then |
19 | you only have to type the profile name. Else, you'll need to provide the | 19 | you only have to type the profile name. Else, you'll need to provide the |
20 | absolute path to the profile. | 20 | absolute path to the profile. |
21 | 21 | ||
22 | Examples: | 22 | Examples: |
23 | python jail_prober.py /etc/firejail/spotify.profile spotify | 23 | python jail_prober.py /etc/firejail/spotify.profile spotify |
24 | python jail_prober.py /usr/local/etc/firejail/firefox.profile /usr/bin/firefox | 24 | python jail_prober.py /usr/local/etc/firejail/firefox.profile /usr/bin/firefox |
25 | """ | 25 | """ |
26 | 26 | ||
27 | import sys | 27 | import sys |
28 | import os | 28 | import os |
29 | import subprocess | 29 | import subprocess |
30 | 30 | ||
31 | 31 | ||
32 | def check_params(profile_path): | 32 | def check_params(profile_path): |
33 | """ | 33 | """ |
34 | Ensure the path to the profile is valid and that an actual profile has been | 34 | Ensure the path to the profile is valid and that an actual profile has been |
35 | passed (as opposed to a config or .local file). | 35 | passed (as opposed to a config or .local file). |
36 | 36 | ||
37 | Args: | 37 | Args: |
38 | profile_path: The absolute path to the problematic profile | 38 | profile_path: The absolute path to the problematic profile |
39 | 39 | ||
40 | Raises: | 40 | Raises: |
41 | FileNotFoundError: If the provided path isn't real | 41 | FileNotFoundError: If the provided path isn't real |
42 | 42 | ||
43 | ValueError: If the provided path is real but doesn't point to | 43 | ValueError: If the provided path is real but doesn't point to |
44 | a Firejail profile | 44 | a Firejail profile |
45 | """ | 45 | """ |
46 | if not os.path.isfile(profile_path): | 46 | if not os.path.isfile(profile_path): |
47 | raise FileNotFoundError('The path %s is not a valid system path.' % | 47 | raise FileNotFoundError('The path %s is not a valid system path.' % |
48 | profile_path) | 48 | profile_path) |
49 | if not profile_path.endswith('.profile'): | 49 | if not profile_path.endswith('.profile'): |
50 | raise ValueError('%s is not a valid Firejail profile.' % profile_path) | 50 | raise ValueError('%s is not a valid Firejail profile.' % profile_path) |
51 | 51 | ||
52 | 52 | ||
53 | def get_args(profile_path): | 53 | def get_args(profile_path): |
54 | """ | 54 | """ |
55 | Read the profile, stripping out comments and newlines | 55 | Read the profile, stripping out comments and newlines |
56 | 56 | ||
57 | Args: | 57 | Args: |
58 | profile_path: The absolute path to the problematic profile. | 58 | profile_path: The absolute path to the problematic profile. |
59 | 59 | ||
60 | Returns: | 60 | Returns: |
61 | A list containing all active profile arguments | 61 | A list containing all active profile arguments |
62 | """ | 62 | """ |
63 | with open(profile_path, 'r') as f: | 63 | with open(profile_path, 'r') as f: |
64 | profile = f.readlines() | 64 | profile = f.readlines() |
65 | profile = [ | 65 | profile = [ |
66 | arg.strip() for arg in profile | 66 | arg.strip() for arg in profile |
67 | if not arg.startswith('#') and arg.strip() != '' | 67 | if not arg.startswith('#') and arg.strip() != '' |
68 | ] | 68 | ] |
69 | 69 | ||
70 | return profile | 70 | return profile |
71 | 71 | ||
72 | 72 | ||
73 | def arg_converter(arg_list, style): | 73 | def arg_converter(arg_list, style): |
74 | """ | 74 | """ |
75 | Convert between firejail command-line arguments (--example=something) and | 75 | Convert between firejail command-line arguments (--example=something) and |
76 | profile arguments (example something) | 76 | profile arguments (example something) |
77 | 77 | ||
78 | Args: | 78 | Args: |
79 | arg_list: A list of firejail arguments | 79 | arg_list: A list of firejail arguments |
80 | 80 | ||
81 | style: String, one of {'to_profile', 'to_commandline'}. Whether to | 81 | style: String, one of {'to_profile', 'to_commandline'}. Whether to |
82 | convert arguments to command-line form or profile form | 82 | convert arguments to command-line form or profile form |
83 | """ | 83 | """ |
84 | if style == 'to_profile': | 84 | if style == 'to_profile': |
85 | old_sep = '=' | 85 | old_sep = '=' |
86 | new_sep = ' ' | 86 | new_sep = ' ' |
87 | prefix = '' | 87 | prefix = '' |
88 | elif style == 'to_commandline': | 88 | elif style == 'to_commandline': |
89 | old_sep = ' ' | 89 | old_sep = ' ' |
90 | new_sep = '=' | 90 | new_sep = '=' |
91 | prefix = '--' | 91 | prefix = '--' |
92 | new_args = [prefix + word.replace(old_sep, new_sep) for word in arg_list] | 92 | new_args = [prefix + word.replace(old_sep, new_sep) for word in arg_list] |
93 | # Additional strip of '--' if converting to profile form | 93 | # Additional strip of '--' if converting to profile form |
94 | if style == 'to_profile': | 94 | if style == 'to_profile': |
95 | new_args = [word[2:] for word in new_args] | 95 | new_args = [word[2:] for word in new_args] |
96 | 96 | ||
97 | # Remove invalid '--include' args if converting to command-line form | 97 | # Remove invalid '--include' args if converting to command-line form |
98 | elif style == 'to_commandline': | 98 | elif style == 'to_commandline': |
99 | new_args = [word for word in new_args if 'include' not in word] | 99 | new_args = [word for word in new_args if 'include' not in word] |
100 | 100 | ||
101 | return new_args | 101 | return new_args |
102 | 102 | ||
103 | 103 | ||
104 | def run_firejail(program, all_args): | 104 | def run_firejail(program, all_args): |
105 | """ | 105 | """ |
106 | Attempt to run the program in firejail, incrementally adding to the number | 106 | Attempt to run the program in firejail, incrementally adding to the number |
107 | of firejail arguments. Initial run has no additional params besides | 107 | of firejail arguments. Initial run has no additional params besides |
108 | noprofile. | 108 | noprofile. |
109 | 109 | ||
110 | Args: | 110 | Args: |
111 | program: String, the program name. If it doesn't exist in $PATH then | 111 | program: String, the program name. If it doesn't exist in $PATH then |
112 | the full path to the program should be provided | 112 | the full path to the program should be provided |
113 | 113 | ||
114 | all_args: List, all Firejail arguments to try, in command-line format | 114 | all_args: List, all Firejail arguments to try, in command-line format |
115 | (i.e. prefixed by '--') | 115 | (i.e. prefixed by '--') |
116 | 116 | ||
117 | Returns: | 117 | Returns: |
118 | good_args: List, all Firejail arguments that the user has reported to | 118 | good_args: List, all Firejail arguments that the user has reported to |
119 | not adversely affect the program | 119 | not adversely affect the program |
120 | 120 | ||
121 | bad_args: List, all Firejail arguments that the user has reported to | 121 | bad_args: List, all Firejail arguments that the user has reported to |
122 | break the program | 122 | break the program |
123 | """ | 123 | """ |
124 | good_args = ['firejail', '--noprofile', program] | 124 | good_args = ['firejail', '--noprofile', program] |
125 | bad_args = [] | 125 | bad_args = [] |
126 | all_args.insert(0, "") | 126 | all_args.insert(0, "") |
127 | print('Attempting to run %s in Firejail' % program) | 127 | print('Attempting to run %s in Firejail' % program) |
128 | for arg in all_args: | 128 | for arg in all_args: |
129 | if arg: | 129 | if arg: |
130 | print('Running with', arg) | 130 | print('Running with', arg) |
131 | else: | 131 | else: |
132 | print('Running without profile') | 132 | print('Running without profile') |
133 | #We are adding the argument in a copy of the actual list to avoid modify it now. | 133 | #We are adding the argument in a copy of the actual list to avoid modify it now. |
134 | myargs = good_args.copy() | 134 | myargs = good_args.copy() |
135 | if arg: | 135 | if arg: |
136 | myargs.insert(-1, arg) | 136 | myargs.insert(-1, arg) |
137 | subprocess.call(myargs) | 137 | subprocess.call(myargs) |
138 | ans = input('Did %s run correctly? [y]/n ' % program) | 138 | ans = input('Did %s run correctly? [y]/n ' % program) |
139 | if ans in ['n', 'N']: | 139 | if ans in ['n', 'N']: |
140 | bad_args.append(arg) | 140 | bad_args.append(arg) |
141 | elif arg: | 141 | elif arg: |
142 | good_args.insert(-1, arg) | 142 | good_args.insert(-1, arg) |
143 | print('\n') | 143 | print('\n') |
144 | # Don't include 'firejail', '--noprofile', or program name in arguments | 144 | # Don't include 'firejail', '--noprofile', or program name in arguments |
145 | good_args = good_args[2:-1] | 145 | good_args = good_args[2:-1] |
146 | 146 | ||
147 | return good_args, bad_args | 147 | return good_args, bad_args |
148 | 148 | ||
149 | 149 | ||
150 | def main(): | 150 | def main(): |
151 | profile_path = sys.argv[1] | 151 | profile_path = sys.argv[1] |
152 | program = sys.argv[2] | 152 | program = sys.argv[2] |
153 | # Quick error check and extract arguments | 153 | # Quick error check and extract arguments |
154 | check_params(profile_path) | 154 | check_params(profile_path) |
155 | profile = get_args(profile_path) | 155 | profile = get_args(profile_path) |
156 | all_args = arg_converter(profile, 'to_commandline') | 156 | all_args = arg_converter(profile, 'to_commandline') |
157 | # Find out which profile options break the program when running in firejail | 157 | # Find out which profile options break the program when running in firejail |
158 | good_args, bad_args = run_firejail(program, all_args) | 158 | good_args, bad_args = run_firejail(program, all_args) |
159 | 159 | ||
160 | good_args = arg_converter(good_args, 'to_profile') | 160 | good_args = arg_converter(good_args, 'to_profile') |
161 | bad_args = arg_converter(bad_args, 'to_profile') | 161 | bad_args = arg_converter(bad_args, 'to_profile') |
162 | 162 | ||
163 | print('\n###########################') | 163 | print('\n###########################') |
164 | print('Debugging completed.') | 164 | print('Debugging completed.') |
165 | print( | 165 | print( |
166 | 'Please copy the following and report it to the Firejail development', | 166 | 'Please copy the following and report it to the Firejail development', |
167 | 'team on GitHub at %s \n\n' % | 167 | 'team on GitHub at %s \n\n' % |
168 | 'https://github.com/netblue30/firejail/issues') | 168 | 'https://github.com/netblue30/firejail/issues') |
169 | 169 | ||
170 | subprocess.call(['firejail', '--version']) | 170 | subprocess.call(['firejail', '--version']) |
171 | 171 | ||
172 | print('These profile options break the program.') | 172 | print('These profile options break the program.') |
173 | print('```') | 173 | print('```') |
174 | for item in bad_args: | 174 | for item in bad_args: |
175 | print(item) | 175 | print(item) |
176 | print('```\n\n\n') | 176 | print('```\n\n\n') |
177 | 177 | ||
178 | print('This is a minimal working profile:') | 178 | print('This is a minimal working profile:') |
179 | print('```') | 179 | print('```') |
180 | for item in good_args: | 180 | for item in good_args: |
181 | print(item) | 181 | print(item) |
182 | print('```') | 182 | print('```') |
183 | 183 | ||
184 | 184 | ||
185 | if __name__ == '__main__': | 185 | if __name__ == '__main__': |
186 | main() | 186 | main() |