Merge lp:~sbeattie/apparmor-profile-tools/pre-merger-cleanups into lp:apparmor-profile-tools
- pre-merger-cleanups
- Merge into trunk
Proposed by
Steve Beattie
Status: | Merged |
---|---|
Merge reported by: | Steve Beattie |
Merged at revision: | not available |
Proposed branch: | lp:~sbeattie/apparmor-profile-tools/pre-merger-cleanups |
Merge into: | lp:apparmor-profile-tools |
Diff against target: |
2957 lines (+481/-465) 20 files modified
Tools/aa-audit (+4/-3) Tools/aa-autodep (+5/-4) Tools/aa-cleanprof (+5/-4) Tools/aa-complain (+4/-3) Tools/aa-disable (+4/-3) Tools/aa-enforce (+4/-3) Tools/aa-genprof (+4/-3) Tools/aa-logprof (+4/-3) Tools/aa-mergeprof (+4/-3) Tools/aa-unconfined (+4/-3) apparmor/__init__.py (+0/-15) apparmor/aa.py (+310/-284) apparmor/aamode.py (+9/-9) apparmor/common.py (+11/-19) apparmor/config.py (+7/-7) apparmor/logparser.py (+31/-27) apparmor/severity.py (+18/-19) apparmor/tools.py (+26/-21) apparmor/ui.py (+27/-31) apparmor/yasti.py (+0/-1) |
To merge this branch: | bzr merge lp:~sbeattie/apparmor-profile-tools/pre-merger-cleanups |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Kshitij Gupta | Pending | ||
Review via email: mp+205701@code.launchpad.net |
Commit message
Description of the change
Here are some simple cleanups in preparation for merging the new profile tools into trunk.
To post a comment you must log in.
Revision history for this message
Christian Boltz (cboltz) wrote : | # |
- 100. By Steve Beattie
-
Simplify the work tools and modules need to do to get the shared
translations. External utilities can still use their own textdomains
if they have strings that are not part of the apparmor-utils catalog.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'Tools/aa-audit' | |||
2 | --- Tools/aa-audit 2014-02-01 01:34:08 +0000 | |||
3 | +++ Tools/aa-audit 2014-02-12 00:39:55 +0000 | |||
4 | @@ -15,11 +15,12 @@ | |||
5 | 15 | import argparse | 15 | import argparse |
6 | 16 | import traceback | 16 | import traceback |
7 | 17 | 17 | ||
8 | 18 | from apparmor.common import init_translations | ||
9 | 19 | init_translations() | ||
10 | 20 | |||
11 | 21 | import apparmor.tools | 18 | import apparmor.tools |
12 | 22 | 19 | ||
13 | 20 | # setup module translations | ||
14 | 21 | from apparmor.translations import init_translation | ||
15 | 22 | _ = init_translation() | ||
16 | 23 | |||
17 | 23 | parser = argparse.ArgumentParser(description=_('Switch the given programs to audit mode')) | 24 | parser = argparse.ArgumentParser(description=_('Switch the given programs to audit mode')) |
18 | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 25 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
19 | 25 | parser.add_argument('-r', '--remove', action='store_true', help=_('remove audit mode')) | 26 | parser.add_argument('-r', '--remove', action='store_true', help=_('remove audit mode')) |
20 | 26 | 27 | ||
21 | === modified file 'Tools/aa-autodep' | |||
22 | --- Tools/aa-autodep 2013-10-21 21:36:23 +0000 | |||
23 | +++ Tools/aa-autodep 2014-02-12 00:39:55 +0000 | |||
24 | @@ -14,11 +14,12 @@ | |||
25 | 14 | # ---------------------------------------------------------------------- | 14 | # ---------------------------------------------------------------------- |
26 | 15 | import argparse | 15 | import argparse |
27 | 16 | 16 | ||
28 | 17 | from apparmor.common import init_translations | ||
29 | 18 | init_translations() | ||
30 | 19 | |||
31 | 20 | import apparmor.tools | 17 | import apparmor.tools |
32 | 21 | 18 | ||
33 | 19 | # setup module translations | ||
34 | 20 | from apparmor.translations import init_translation | ||
35 | 21 | _ = init_translation() | ||
36 | 22 | |||
37 | 22 | parser = argparse.ArgumentParser(description=_('Generate a basic AppArmor profile by guessing requirements')) | 23 | parser = argparse.ArgumentParser(description=_('Generate a basic AppArmor profile by guessing requirements')) |
38 | 23 | parser.add_argument('--force', type=str, help=_('overwrite existing profile')) | 24 | parser.add_argument('--force', type=str, help=_('overwrite existing profile')) |
39 | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 25 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
40 | @@ -27,4 +28,4 @@ | |||
41 | 27 | 28 | ||
42 | 28 | autodep = apparmor.tools.aa_tools('autodep', args) | 29 | autodep = apparmor.tools.aa_tools('autodep', args) |
43 | 29 | 30 | ||
44 | 30 | autodep.act() | ||
45 | 31 | \ No newline at end of file | 31 | \ No newline at end of file |
46 | 32 | autodep.act() | ||
47 | 32 | 33 | ||
48 | === modified file 'Tools/aa-cleanprof' | |||
49 | --- Tools/aa-cleanprof 2013-10-21 21:36:23 +0000 | |||
50 | +++ Tools/aa-cleanprof 2014-02-12 00:39:55 +0000 | |||
51 | @@ -14,11 +14,12 @@ | |||
52 | 14 | # ---------------------------------------------------------------------- | 14 | # ---------------------------------------------------------------------- |
53 | 15 | import argparse | 15 | import argparse |
54 | 16 | 16 | ||
55 | 17 | from apparmor.common import init_translations | ||
56 | 18 | init_translations() | ||
57 | 19 | |||
58 | 20 | import apparmor.tools | 17 | import apparmor.tools |
59 | 21 | 18 | ||
60 | 19 | # setup module translations | ||
61 | 20 | from apparmor.translations import init_translation | ||
62 | 21 | _ = init_translation() | ||
63 | 22 | |||
64 | 22 | parser = argparse.ArgumentParser(description=_('Cleanup the profiles for the given programs')) | 23 | parser = argparse.ArgumentParser(description=_('Cleanup the profiles for the given programs')) |
65 | 23 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
66 | 24 | parser.add_argument('program', type=str, nargs='+', help=_('name of program')) | 25 | parser.add_argument('program', type=str, nargs='+', help=_('name of program')) |
67 | @@ -27,4 +28,4 @@ | |||
68 | 27 | 28 | ||
69 | 28 | clean = apparmor.tools.aa_tools('cleanprof', args) | 29 | clean = apparmor.tools.aa_tools('cleanprof', args) |
70 | 29 | 30 | ||
71 | 30 | clean.act() | ||
72 | 31 | \ No newline at end of file | 31 | \ No newline at end of file |
73 | 32 | clean.act() | ||
74 | 32 | 33 | ||
75 | === modified file 'Tools/aa-complain' | |||
76 | --- Tools/aa-complain 2013-12-29 09:42:30 +0000 | |||
77 | +++ Tools/aa-complain 2014-02-12 00:39:55 +0000 | |||
78 | @@ -14,11 +14,12 @@ | |||
79 | 14 | # ---------------------------------------------------------------------- | 14 | # ---------------------------------------------------------------------- |
80 | 15 | import argparse | 15 | import argparse |
81 | 16 | 16 | ||
82 | 17 | from apparmor.common import init_translations | ||
83 | 18 | init_translations() | ||
84 | 19 | |||
85 | 20 | import apparmor.tools | 17 | import apparmor.tools |
86 | 21 | 18 | ||
87 | 19 | # setup module translations | ||
88 | 20 | from apparmor.translations import init_translation | ||
89 | 21 | _ = init_translation() | ||
90 | 22 | |||
91 | 22 | parser = argparse.ArgumentParser(description=_('Switch the given program to complain mode')) | 23 | parser = argparse.ArgumentParser(description=_('Switch the given program to complain mode')) |
92 | 23 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
93 | 24 | parser.add_argument('-r', '--remove', action='store_true', help=_('remove complain mode')) | 25 | parser.add_argument('-r', '--remove', action='store_true', help=_('remove complain mode')) |
94 | 25 | 26 | ||
95 | === modified file 'Tools/aa-disable' | |||
96 | --- Tools/aa-disable 2013-10-21 21:36:23 +0000 | |||
97 | +++ Tools/aa-disable 2014-02-12 00:39:55 +0000 | |||
98 | @@ -14,11 +14,12 @@ | |||
99 | 14 | # ---------------------------------------------------------------------- | 14 | # ---------------------------------------------------------------------- |
100 | 15 | import argparse | 15 | import argparse |
101 | 16 | 16 | ||
102 | 17 | from apparmor.common import init_translations | ||
103 | 18 | init_translations() | ||
104 | 19 | |||
105 | 20 | import apparmor.tools | 17 | import apparmor.tools |
106 | 21 | 18 | ||
107 | 19 | # setup module translations | ||
108 | 20 | from apparmor.translations import init_translation | ||
109 | 21 | _ = init_translation() | ||
110 | 22 | |||
111 | 22 | parser = argparse.ArgumentParser(description=_('Disable the profile for the given programs')) | 23 | parser = argparse.ArgumentParser(description=_('Disable the profile for the given programs')) |
112 | 23 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
113 | 24 | parser.add_argument('-r', '--revert', action='store_true', help=_('enable the profile for the given programs')) | 25 | parser.add_argument('-r', '--revert', action='store_true', help=_('enable the profile for the given programs')) |
114 | 25 | 26 | ||
115 | === modified file 'Tools/aa-enforce' | |||
116 | --- Tools/aa-enforce 2013-10-21 21:36:23 +0000 | |||
117 | +++ Tools/aa-enforce 2014-02-12 00:39:55 +0000 | |||
118 | @@ -14,11 +14,12 @@ | |||
119 | 14 | # ---------------------------------------------------------------------- | 14 | # ---------------------------------------------------------------------- |
120 | 15 | import argparse | 15 | import argparse |
121 | 16 | 16 | ||
122 | 17 | from apparmor.common import init_translations | ||
123 | 18 | init_translations() | ||
124 | 19 | |||
125 | 20 | import apparmor.tools | 17 | import apparmor.tools |
126 | 21 | 18 | ||
127 | 19 | # setup module translations | ||
128 | 20 | from apparmor.translations import init_translation | ||
129 | 21 | _ = init_translation() | ||
130 | 22 | |||
131 | 22 | parser = argparse.ArgumentParser(description=_('Switch the given program to enforce mode')) | 23 | parser = argparse.ArgumentParser(description=_('Switch the given program to enforce mode')) |
132 | 23 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
133 | 24 | parser.add_argument('-r', '--remove', action='store_true', help=_('switch to complain mode')) | 25 | parser.add_argument('-r', '--remove', action='store_true', help=_('switch to complain mode')) |
134 | 25 | 26 | ||
135 | === modified file 'Tools/aa-genprof' | |||
136 | --- Tools/aa-genprof 2013-12-29 09:42:30 +0000 | |||
137 | +++ Tools/aa-genprof 2014-02-12 00:39:55 +0000 | |||
138 | @@ -19,11 +19,12 @@ | |||
139 | 19 | import subprocess | 19 | import subprocess |
140 | 20 | import sys | 20 | import sys |
141 | 21 | 21 | ||
142 | 22 | from apparmor.common import init_translations | ||
143 | 23 | init_translations() | ||
144 | 24 | |||
145 | 25 | import apparmor.aa as apparmor | 22 | import apparmor.aa as apparmor |
146 | 26 | 23 | ||
147 | 24 | # setup module translations | ||
148 | 25 | from apparmor.translations import init_translation | ||
149 | 26 | _ = init_translation() | ||
150 | 27 | |||
151 | 27 | def sysctl_read(path): | 28 | def sysctl_read(path): |
152 | 28 | value = None | 29 | value = None |
153 | 29 | with open(path, 'r') as f_in: | 30 | with open(path, 'r') as f_in: |
154 | 30 | 31 | ||
155 | === modified file 'Tools/aa-logprof' | |||
156 | --- Tools/aa-logprof 2013-12-29 09:42:30 +0000 | |||
157 | +++ Tools/aa-logprof 2014-02-12 00:39:55 +0000 | |||
158 | @@ -15,11 +15,12 @@ | |||
159 | 15 | import argparse | 15 | import argparse |
160 | 16 | import os | 16 | import os |
161 | 17 | 17 | ||
162 | 18 | from apparmor.common import init_translations | ||
163 | 19 | init_translations() | ||
164 | 20 | |||
165 | 21 | import apparmor.aa as apparmor | 18 | import apparmor.aa as apparmor |
166 | 22 | 19 | ||
167 | 20 | # setup module translations | ||
168 | 21 | from apparmor.translations import init_translation | ||
169 | 22 | _ = init_translation() | ||
170 | 23 | |||
171 | 23 | parser = argparse.ArgumentParser(description=_('Process log entries to generate profiles')) | 24 | parser = argparse.ArgumentParser(description=_('Process log entries to generate profiles')) |
172 | 24 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) | 25 | parser.add_argument('-d', '--dir', type=str, help=_('path to profiles')) |
173 | 25 | parser.add_argument('-f', '--file', type=str, help=_('path to logfile')) | 26 | parser.add_argument('-f', '--file', type=str, help=_('path to logfile')) |
174 | 26 | 27 | ||
175 | === modified file 'Tools/aa-mergeprof' | |||
176 | --- Tools/aa-mergeprof 2013-10-21 21:36:23 +0000 | |||
177 | +++ Tools/aa-mergeprof 2014-02-12 00:39:55 +0000 | |||
178 | @@ -15,14 +15,15 @@ | |||
179 | 15 | import argparse | 15 | import argparse |
180 | 16 | import sys | 16 | import sys |
181 | 17 | 17 | ||
182 | 18 | from apparmor.common import init_translations | ||
183 | 19 | init_translations() | ||
184 | 20 | |||
185 | 21 | import apparmor.aa | 18 | import apparmor.aa |
186 | 22 | import apparmor.aamode | 19 | import apparmor.aamode |
187 | 23 | import apparmor.severity | 20 | import apparmor.severity |
188 | 24 | import apparmor.cleanprofile as cleanprofile | 21 | import apparmor.cleanprofile as cleanprofile |
189 | 25 | 22 | ||
190 | 23 | # setup module translations | ||
191 | 24 | from apparmor.translations import init_translation | ||
192 | 25 | _ = init_translation() | ||
193 | 26 | |||
194 | 26 | parser = argparse.ArgumentParser(description=_('Perform a 3way merge on the given profiles')) | 27 | parser = argparse.ArgumentParser(description=_('Perform a 3way merge on the given profiles')) |
195 | 27 | parser.add_argument('mine', type=str, help=_('your profile')) | 28 | parser.add_argument('mine', type=str, help=_('your profile')) |
196 | 28 | parser.add_argument('base', type=str, help=_('base profile')) | 29 | parser.add_argument('base', type=str, help=_('base profile')) |
197 | 29 | 30 | ||
198 | === modified file 'Tools/aa-unconfined' | |||
199 | --- Tools/aa-unconfined 2013-12-29 09:42:30 +0000 | |||
200 | +++ Tools/aa-unconfined 2014-02-12 00:39:55 +0000 | |||
201 | @@ -17,11 +17,12 @@ | |||
202 | 17 | import re | 17 | import re |
203 | 18 | import sys | 18 | import sys |
204 | 19 | 19 | ||
205 | 20 | from apparmor.common import init_translations | ||
206 | 21 | init_translations() | ||
207 | 22 | |||
208 | 23 | import apparmor.aa as apparmor | 20 | import apparmor.aa as apparmor |
209 | 24 | 21 | ||
210 | 22 | # setup module translations | ||
211 | 23 | from apparmor.translations import init_translation | ||
212 | 24 | _ = init_translation() | ||
213 | 25 | |||
214 | 25 | parser = argparse.ArgumentParser(description=_("Lists unconfined processes having tcp or udp ports")) | 26 | parser = argparse.ArgumentParser(description=_("Lists unconfined processes having tcp or udp ports")) |
215 | 26 | parser.add_argument("--paranoid", action="store_true", help=_("scan all processes from /proc")) | 27 | parser.add_argument("--paranoid", action="store_true", help=_("scan all processes from /proc")) |
216 | 27 | args = parser.parse_args() | 28 | args = parser.parse_args() |
217 | 28 | 29 | ||
218 | === modified file 'apparmor/__init__.py' | |||
219 | --- apparmor/__init__.py 2013-12-19 21:42:58 +0000 | |||
220 | +++ apparmor/__init__.py 2014-02-12 00:39:55 +0000 | |||
221 | @@ -1,24 +1,9 @@ | |||
222 | 1 | # ------------------------------------------------------------------ | 1 | # ------------------------------------------------------------------ |
223 | 2 | # | 2 | # |
224 | 3 | # Copyright (C) 2011-2012 Canonical Ltd. | 3 | # Copyright (C) 2011-2012 Canonical Ltd. |
225 | 4 | # Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com> | ||
226 | 5 | # | 4 | # |
227 | 6 | # This program is free software; you can redistribute it and/or | 5 | # This program is free software; you can redistribute it and/or |
228 | 7 | # modify it under the terms of version 2 of the GNU General Public | 6 | # modify it under the terms of version 2 of the GNU General Public |
229 | 8 | # License published by the Free Software Foundation. | 7 | # License published by the Free Software Foundation. |
230 | 9 | # | 8 | # |
231 | 10 | # ------------------------------------------------------------------ | 9 | # ------------------------------------------------------------------ |
232 | 11 | import gettext | ||
233 | 12 | import locale | ||
234 | 13 | |||
235 | 14 | def init_localisation(): | ||
236 | 15 | locale.setlocale(locale.LC_ALL, '') | ||
237 | 16 | #If a correct locale has been provided set filename else let an IOError be raised | ||
238 | 17 | filename = '/usr/share/locale/%s/LC_MESSAGES/apparmor-utils.mo' % locale.getlocale()[0] | ||
239 | 18 | try: | ||
240 | 19 | trans = gettext.GNUTranslations(open(filename, 'rb')) | ||
241 | 20 | except IOError: | ||
242 | 21 | trans = gettext.NullTranslations() | ||
243 | 22 | trans.install() | ||
244 | 23 | |||
245 | 24 | init_localisation() | ||
246 | 25 | 10 | ||
247 | === modified file 'apparmor/aa.py' | |||
248 | --- apparmor/aa.py 2014-02-01 00:44:05 +0000 | |||
249 | +++ apparmor/aa.py 2014-02-12 00:39:55 +0000 | |||
250 | @@ -13,11 +13,11 @@ | |||
251 | 13 | # ---------------------------------------------------------------------- | 13 | # ---------------------------------------------------------------------- |
252 | 14 | # No old version logs, only 2.6 + supported | 14 | # No old version logs, only 2.6 + supported |
253 | 15 | from __future__ import with_statement | 15 | from __future__ import with_statement |
254 | 16 | import gettext | ||
255 | 16 | import inspect | 17 | import inspect |
256 | 17 | import os | 18 | import os |
257 | 18 | import re | 19 | import re |
258 | 19 | import shutil | 20 | import shutil |
259 | 20 | import stat | ||
260 | 21 | import subprocess | 21 | import subprocess |
261 | 22 | import sys | 22 | import sys |
262 | 23 | import time | 23 | import time |
263 | @@ -33,12 +33,20 @@ | |||
264 | 33 | from copy import deepcopy | 33 | from copy import deepcopy |
265 | 34 | 34 | ||
266 | 35 | from apparmor.common import (AppArmorException, error, debug, msg, cmd, | 35 | from apparmor.common import (AppArmorException, error, debug, msg, cmd, |
273 | 36 | open_file_read, valid_path, | 36 | open_file_read, valid_path, hasher, |
274 | 37 | hasher, open_file_write, convert_regexp, DebugLogger) | 37 | open_file_write, convert_regexp, DebugLogger) |
275 | 38 | 38 | ||
276 | 39 | from apparmor.ui import * | 39 | import apparmor.ui as aaui |
277 | 40 | 40 | ||
278 | 41 | from apparmor.aamode import * | 41 | from apparmor.aamode import (str_to_mode, mode_to_str, contains, split_mode, |
279 | 42 | mode_to_str_user, mode_contains, AA_OTHER, | ||
280 | 43 | flatten_mode, owner_flatten_mode) | ||
281 | 44 | |||
282 | 45 | from apparmor.yasti import SendDataToYast, GetDataFromYast, shutdown_yast | ||
283 | 46 | |||
284 | 47 | # setup module translations | ||
285 | 48 | from apparmor.translations import init_translation | ||
286 | 49 | _ = init_translation() | ||
287 | 42 | 50 | ||
288 | 43 | # Setup logging incase of debugging is enabled | 51 | # Setup logging incase of debugging is enabled |
289 | 44 | debug_logger = DebugLogger('aa') | 52 | debug_logger = DebugLogger('aa') |
290 | @@ -67,7 +75,7 @@ | |||
291 | 67 | 75 | ||
292 | 68 | existing_profiles = dict() | 76 | existing_profiles = dict() |
293 | 69 | 77 | ||
295 | 70 | seen_events = 0 # was our | 78 | seen_events = 0 # was our |
296 | 71 | # To store the globs entered by users so they can be provided again | 79 | # To store the globs entered by users so they can be provided again |
297 | 72 | user_globs = [] | 80 | user_globs = [] |
298 | 73 | 81 | ||
299 | @@ -76,7 +84,7 @@ | |||
300 | 76 | t = hasher() # dict() | 84 | t = hasher() # dict() |
301 | 77 | transitions = hasher() | 85 | transitions = hasher() |
302 | 78 | aa = hasher() # Profiles originally in sd, replace by aa | 86 | aa = hasher() # Profiles originally in sd, replace by aa |
304 | 79 | original_aa = hasher() | 87 | original_aa = hasher() |
305 | 80 | extras = hasher() # Inactive profiles from extras | 88 | extras = hasher() # Inactive profiles from extras |
306 | 81 | ### end our | 89 | ### end our |
307 | 82 | log = [] | 90 | log = [] |
308 | @@ -85,11 +93,11 @@ | |||
309 | 85 | seen = hasher() # dir() | 93 | seen = hasher() # dir() |
310 | 86 | profile_changes = hasher() | 94 | profile_changes = hasher() |
311 | 87 | prelog = hasher() | 95 | prelog = hasher() |
313 | 88 | log_dict = hasher()#dict() | 96 | log_dict = hasher() # dict() |
314 | 89 | changed = dict() | 97 | changed = dict() |
315 | 90 | created = [] | 98 | created = [] |
316 | 91 | skip = hasher() | 99 | skip = hasher() |
318 | 92 | helpers = dict() # Preserve this between passes # was our | 100 | helpers = dict() # Preserve this between passes # was our |
319 | 93 | ### logprof ends | 101 | ### logprof ends |
320 | 94 | 102 | ||
321 | 95 | filelist = hasher() # File level variables and stuff in config files | 103 | filelist = hasher() # File level variables and stuff in config files |
322 | @@ -110,7 +118,7 @@ | |||
323 | 110 | return False | 118 | return False |
324 | 111 | size = os.stat(file).st_size | 119 | size = os.stat(file).st_size |
325 | 112 | # Limit to checking files under 100k for the sake of speed | 120 | # Limit to checking files under 100k for the sake of speed |
327 | 113 | if size >100000: | 121 | if size > 100000: |
328 | 114 | return False | 122 | return False |
329 | 115 | with open_file_read(file, encoding='ascii') as f_in: | 123 | with open_file_read(file, encoding='ascii') as f_in: |
330 | 116 | for line in f_in: | 124 | for line in f_in: |
331 | @@ -128,11 +136,11 @@ | |||
332 | 128 | caller = inspect.stack()[1][3] | 136 | caller = inspect.stack()[1][3] |
333 | 129 | 137 | ||
334 | 130 | # If caller is SendDataToYast or GetDatFromYast simply exit | 138 | # If caller is SendDataToYast or GetDatFromYast simply exit |
336 | 131 | if caller == 'SendDataToYast' or caller== 'GetDatFromYast': | 139 | if caller == 'SendDataToYast' or caller == 'GetDatFromYast': |
337 | 132 | sys.exit(1) | 140 | sys.exit(1) |
338 | 133 | 141 | ||
339 | 134 | # Else tell user what happened | 142 | # Else tell user what happened |
341 | 135 | UI_Important(message) | 143 | aaui.UI_Important(message) |
342 | 136 | shutdown_yast() | 144 | shutdown_yast() |
343 | 137 | sys.exit(1) | 145 | sys.exit(1) |
344 | 138 | 146 | ||
345 | @@ -164,7 +172,7 @@ | |||
346 | 164 | 172 | ||
347 | 165 | def which(file): | 173 | def which(file): |
348 | 166 | """Returns the executable fullpath for the file, None otherwise""" | 174 | """Returns the executable fullpath for the file, None otherwise""" |
350 | 167 | if sys.version_info >= (3,3): | 175 | if sys.version_info >= (3, 3): |
351 | 168 | return shutil.which(file) | 176 | return shutil.which(file) |
352 | 169 | env_dirs = os.getenv('PATH').split(':') | 177 | env_dirs = os.getenv('PATH').split(':') |
353 | 170 | for env_dir in env_dirs: | 178 | for env_dir in env_dirs: |
354 | @@ -238,33 +246,33 @@ | |||
355 | 238 | def complain(path): | 246 | def complain(path): |
356 | 239 | """Sets the profile to complain mode if it exists""" | 247 | """Sets the profile to complain mode if it exists""" |
357 | 240 | prof_filename, name = name_to_prof_filename(path) | 248 | prof_filename, name = name_to_prof_filename(path) |
359 | 241 | if not prof_filename : | 249 | if not prof_filename: |
360 | 242 | fatal_error(_("Can't find %s") % path) | 250 | fatal_error(_("Can't find %s") % path) |
361 | 243 | set_complain(prof_filename, name) | 251 | set_complain(prof_filename, name) |
362 | 244 | 252 | ||
363 | 245 | def enforce(path): | 253 | def enforce(path): |
364 | 246 | """Sets the profile to enforce mode if it exists""" | 254 | """Sets the profile to enforce mode if it exists""" |
365 | 247 | prof_filename, name = name_to_prof_filename(path) | 255 | prof_filename, name = name_to_prof_filename(path) |
367 | 248 | if not prof_filename : | 256 | if not prof_filename: |
368 | 249 | fatal_error(_("Can't find %s") % path) | 257 | fatal_error(_("Can't find %s") % path) |
369 | 250 | set_enforce(prof_filename, name) | 258 | set_enforce(prof_filename, name) |
370 | 251 | 259 | ||
371 | 252 | def set_complain(filename, program): | 260 | def set_complain(filename, program): |
372 | 253 | """Sets the profile to complain mode""" | 261 | """Sets the profile to complain mode""" |
374 | 254 | UI_Info(_('Setting %s to complain mode.') % program) | 262 | aaui.UI_Info(_('Setting %s to complain mode.') % program) |
375 | 255 | create_symlink('force-complain', filename) | 263 | create_symlink('force-complain', filename) |
376 | 256 | change_profile_flags(filename, program, 'complain', True) | 264 | change_profile_flags(filename, program, 'complain', True) |
377 | 257 | 265 | ||
378 | 258 | def set_enforce(filename, program): | 266 | def set_enforce(filename, program): |
379 | 259 | """Sets the profile to enforce mode""" | 267 | """Sets the profile to enforce mode""" |
381 | 260 | UI_Info(_('Setting %s to enforce mode.') % program) | 268 | aaui.UI_Info(_('Setting %s to enforce mode.') % program) |
382 | 261 | delete_symlink('force-complain', filename) | 269 | delete_symlink('force-complain', filename) |
383 | 262 | delete_symlink('disable', filename) | 270 | delete_symlink('disable', filename) |
384 | 263 | change_profile_flags(filename, program, 'complain', False) | 271 | change_profile_flags(filename, program, 'complain', False) |
385 | 264 | 272 | ||
386 | 265 | def delete_symlink(subdir, filename): | 273 | def delete_symlink(subdir, filename): |
387 | 266 | path = filename | 274 | path = filename |
389 | 267 | link = re.sub('^%s'%profile_dir, '%s/%s'%(profile_dir, subdir), path) | 275 | link = re.sub('^%s' % profile_dir, '%s/%s' % (profile_dir, subdir), path) |
390 | 268 | if link != path and os.path.islink(link): | 276 | if link != path and os.path.islink(link): |
391 | 269 | os.remove(link) | 277 | os.remove(link) |
392 | 270 | 278 | ||
393 | @@ -272,13 +280,13 @@ | |||
394 | 272 | path = filename | 280 | path = filename |
395 | 273 | bname = os.path.basename(filename) | 281 | bname = os.path.basename(filename) |
396 | 274 | if not bname: | 282 | if not bname: |
398 | 275 | raise AppArmorException(_('Unable to find basename for %s.')%filename) | 283 | raise AppArmorException(_('Unable to find basename for %s.') % filename) |
399 | 276 | #print(filename) | 284 | #print(filename) |
401 | 277 | link = re.sub('^%s'%profile_dir, '%s/%s'%(profile_dir, subdir), path) | 285 | link = re.sub('^%s' % profile_dir, '%s/%s' % (profile_dir, subdir), path) |
402 | 278 | #print(link) | 286 | #print(link) |
403 | 279 | #link = link + '/%s'%bname | 287 | #link = link + '/%s'%bname |
404 | 280 | #print(link) | 288 | #print(link) |
406 | 281 | symlink_dir=os.path.dirname(link) | 289 | symlink_dir = os.path.dirname(link) |
407 | 282 | if not os.path.exists(symlink_dir): | 290 | if not os.path.exists(symlink_dir): |
408 | 283 | # If the symlink directory does not exist create it | 291 | # If the symlink directory does not exist create it |
409 | 284 | os.makedirs(symlink_dir) | 292 | os.makedirs(symlink_dir) |
410 | @@ -287,7 +295,7 @@ | |||
411 | 287 | try: | 295 | try: |
412 | 288 | os.symlink(filename, link) | 296 | os.symlink(filename, link) |
413 | 289 | except: | 297 | except: |
415 | 290 | raise AppArmorException(_('Could not create %s symlink to %s.')%(link, filename)) | 298 | raise AppArmorException(_('Could not create %s symlink to %s.') % (link, filename)) |
416 | 291 | 299 | ||
417 | 292 | def head(file): | 300 | def head(file): |
418 | 293 | """Returns the first/head line of the file""" | 301 | """Returns the first/head line of the file""" |
419 | @@ -300,7 +308,7 @@ | |||
420 | 300 | pass | 308 | pass |
421 | 301 | return first | 309 | return first |
422 | 302 | else: | 310 | else: |
424 | 303 | raise AppArmorException(_('Unable to read first line from %s: File Not Found') %file) | 311 | raise AppArmorException(_('Unable to read first line from %s: File Not Found') % file) |
425 | 304 | 312 | ||
426 | 305 | def get_output(params): | 313 | def get_output(params): |
427 | 306 | """Returns the return code output by running the program with the args given in the list""" | 314 | """Returns the return code output by running the program with the args given in the list""" |
428 | @@ -314,7 +322,7 @@ | |||
429 | 314 | # Get the output of the program | 322 | # Get the output of the program |
430 | 315 | output = subprocess.check_output(params) | 323 | output = subprocess.check_output(params) |
431 | 316 | except OSError as e: | 324 | except OSError as e: |
433 | 317 | raise AppArmorException(_("Unable to fork: %s\n\t%s") %(program, str(e))) | 325 | raise AppArmorException(_("Unable to fork: %s\n\t%s") % (program, str(e))) |
434 | 318 | # If exit-codes besides 0 | 326 | # If exit-codes besides 0 |
435 | 319 | except subprocess.CalledProcessError as e: | 327 | except subprocess.CalledProcessError as e: |
436 | 320 | output = e.output | 328 | output = e.output |
437 | @@ -419,7 +427,7 @@ | |||
438 | 419 | 427 | ||
439 | 420 | created.append(localfile) | 428 | created.append(localfile) |
440 | 421 | changed.append(localfile) | 429 | changed.append(localfile) |
442 | 422 | 430 | ||
443 | 423 | debug_logger.debug("Profile for %s:\n\t%s" % (localfile, local_profile.__str__())) | 431 | debug_logger.debug("Profile for %s:\n\t%s" % (localfile, local_profile.__str__())) |
444 | 424 | return {localfile: local_profile} | 432 | return {localfile: local_profile} |
445 | 425 | 433 | ||
446 | @@ -434,9 +442,9 @@ | |||
447 | 434 | #prof_unload(local_prof) | 442 | #prof_unload(local_prof) |
448 | 435 | 443 | ||
449 | 436 | def confirm_and_abort(): | 444 | def confirm_and_abort(): |
451 | 437 | ans = UI_YesNo(_('Are you sure you want to abandon this set of profile changes and exit?'), 'n') | 445 | ans = aaui.UI_YesNo(_('Are you sure you want to abandon this set of profile changes and exit?'), 'n') |
452 | 438 | if ans == 'y': | 446 | if ans == 'y': |
454 | 439 | UI_Info(_('Abandoning all changes.')) | 447 | aaui.UI_Info(_('Abandoning all changes.')) |
455 | 440 | shutdown_yast() | 448 | shutdown_yast() |
456 | 441 | for prof in created: | 449 | for prof in created: |
457 | 442 | delete_profile(prof) | 450 | delete_profile(prof) |
458 | @@ -449,13 +457,13 @@ | |||
459 | 449 | local_profiles = [] | 457 | local_profiles = [] |
460 | 450 | profile_hash = hasher() | 458 | profile_hash = hasher() |
461 | 451 | if repo_is_enabled(): | 459 | if repo_is_enabled(): |
463 | 452 | UI_BusyStart(_('Connecting to repository...')) | 460 | aaui.UI_BusyStart(_('Connecting to repository...')) |
464 | 453 | status_ok, ret = fetch_profiles_by_name(repo_url, distro, prof_name) | 461 | status_ok, ret = fetch_profiles_by_name(repo_url, distro, prof_name) |
466 | 454 | UI_BusyStop() | 462 | aaui.UI_BusyStop() |
467 | 455 | if status_ok: | 463 | if status_ok: |
468 | 456 | profile_hash = ret | 464 | profile_hash = ret |
469 | 457 | else: | 465 | else: |
471 | 458 | UI_Important(_('WARNING: Error fetching profiles from the repository')) | 466 | aaui.UI_Important(_('WARNING: Error fetching profiles from the repository')) |
472 | 459 | inactive_profile = get_inactive_profile(prof_name) | 467 | inactive_profile = get_inactive_profile(prof_name) |
473 | 460 | if inactive_profile: | 468 | if inactive_profile: |
474 | 461 | uname = 'Inactive local profile for %s' % prof_name | 469 | uname = 'Inactive local profile for %s' % prof_name |
475 | @@ -493,13 +501,12 @@ | |||
476 | 493 | 501 | ||
477 | 494 | ans = '' | 502 | ans = '' |
478 | 495 | while 'CMD_USE_PROFILE' not in ans and 'CMD_CREATE_PROFILE' not in ans: | 503 | while 'CMD_USE_PROFILE' not in ans and 'CMD_CREATE_PROFILE' not in ans: |
480 | 496 | ans, arg = UI_PromptUser(q) | 504 | ans, arg = aaui.UI_PromptUser(q) |
481 | 497 | p = profile_hash[options[arg]] | 505 | p = profile_hash[options[arg]] |
482 | 498 | q['selected'] = options.index(options[arg]) | 506 | q['selected'] = options.index(options[arg]) |
483 | 499 | if ans == 'CMD_VIEW_PROFILE': | 507 | if ans == 'CMD_VIEW_PROFILE': |
487 | 500 | if UI_mode == 'yast': | 508 | if aaui.UI_mode == 'yast': |
488 | 501 | SendDataToYast({ | 509 | SendDataToYast({'type': 'dialogue-view-profile', |
486 | 502 | 'type': 'dialogue-view-profile', | ||
489 | 503 | 'user': options[arg], | 510 | 'user': options[arg], |
490 | 504 | 'profile': p['profile'], | 511 | 'profile': p['profile'], |
491 | 505 | 'profile_type': p['profile_type'] | 512 | 'profile_type': p['profile_type'] |
492 | @@ -530,7 +537,7 @@ | |||
493 | 530 | if complain: | 537 | if complain: |
494 | 531 | fname = get_profile_filename(pname) | 538 | fname = get_profile_filename(pname) |
495 | 532 | set_profile_flags(profile_dir + fname, 'complain') | 539 | set_profile_flags(profile_dir + fname, 'complain') |
497 | 533 | UI_Info(_('Setting %s to complain mode.') % pname) | 540 | aaui.UI_Info(_('Setting %s to complain mode.') % pname) |
498 | 534 | except Exception as e: | 541 | except Exception as e: |
499 | 535 | sys.stderr.write(_("Error activating profiles: %s") % e) | 542 | sys.stderr.write(_("Error activating profiles: %s") % e) |
500 | 536 | 543 | ||
501 | @@ -585,7 +592,7 @@ | |||
502 | 585 | if profile == program: | 592 | if profile == program: |
503 | 586 | return flags | 593 | return flags |
504 | 587 | 594 | ||
506 | 588 | raise AppArmorException(_('%s contains no profile')%filename) | 595 | raise AppArmorException(_('%s contains no profile') % filename) |
507 | 589 | 596 | ||
508 | 590 | def change_profile_flags(filename, program, flag, set_flag): | 597 | def change_profile_flags(filename, program, flag, set_flag): |
509 | 591 | old_flags = get_profile_flags(filename, program) | 598 | old_flags = get_profile_flags(filename, program) |
510 | @@ -595,7 +602,7 @@ | |||
511 | 595 | # Flags maybe white-space and/or , separated | 602 | # Flags maybe white-space and/or , separated |
512 | 596 | old_flags = old_flags.split(',') | 603 | old_flags = old_flags.split(',') |
513 | 597 | 604 | ||
515 | 598 | if type(old_flags) == type([]): | 605 | if not isinstance(old_flags, str): |
516 | 599 | for i in old_flags: | 606 | for i in old_flags: |
517 | 600 | newflags += i.split() | 607 | newflags += i.split() |
518 | 601 | else: | 608 | else: |
519 | @@ -619,7 +626,7 @@ | |||
520 | 619 | regex_hat_flag = re.compile('^([a-z]*)\s+([A-Z]*)\s*(#.*)?$') | 626 | regex_hat_flag = re.compile('^([a-z]*)\s+([A-Z]*)\s*(#.*)?$') |
521 | 620 | if os.path.isfile(prof_filename): | 627 | if os.path.isfile(prof_filename): |
522 | 621 | with open_file_read(prof_filename) as f_in: | 628 | with open_file_read(prof_filename) as f_in: |
524 | 622 | temp_file = tempfile.NamedTemporaryFile('w', prefix=prof_filename , suffix='~', delete=False, dir=profile_dir) | 629 | temp_file = tempfile.NamedTemporaryFile('w', prefix=prof_filename, suffix='~', delete=False, dir=profile_dir) |
525 | 623 | shutil.copymode(prof_filename, temp_file.name) | 630 | shutil.copymode(prof_filename, temp_file.name) |
526 | 624 | with open_file_write(temp_file.name) as f_out: | 631 | with open_file_write(temp_file.name) as f_out: |
527 | 625 | for line in f_in: | 632 | for line in f_in: |
528 | @@ -679,7 +686,7 @@ | |||
529 | 679 | if not status_ok: | 686 | if not status_ok: |
530 | 680 | if not ret: | 687 | if not ret: |
531 | 681 | ret = 'UNKNOWN ERROR' | 688 | ret = 'UNKNOWN ERROR' |
533 | 682 | UI_Important(_('WARNING: Error synchronizing profiles with the repository:\n%s\n') % ret) | 689 | aaui.UI_Important(_('WARNING: Error synchronizing profiles with the repository:\n%s\n') % ret) |
534 | 683 | else: | 690 | else: |
535 | 684 | users_repo_profiles = ret | 691 | users_repo_profiles = ret |
536 | 685 | serialize_opts['NO_FLAGS'] = True | 692 | serialize_opts['NO_FLAGS'] = True |
537 | @@ -717,7 +724,7 @@ | |||
538 | 717 | else: | 724 | else: |
539 | 718 | if not ret: | 725 | if not ret: |
540 | 719 | ret = 'UNKNOWN ERROR' | 726 | ret = 'UNKNOWN ERROR' |
542 | 720 | UI_Important(_('WARNING: Error synchronizing profiles with the repository\n%s') % ret) | 727 | aaui.UI_Important(_('WARNING: Error synchronizing profiles with the repository\n%s') % ret) |
543 | 721 | continue | 728 | continue |
544 | 722 | if p_repo != p_local: | 729 | if p_repo != p_local: |
545 | 723 | changed_profiles.append(prof) | 730 | changed_profiles.append(prof) |
546 | @@ -743,7 +750,7 @@ | |||
547 | 743 | def submit_created_profiles(new_profiles): | 750 | def submit_created_profiles(new_profiles): |
548 | 744 | #url = cfg['repository']['url'] | 751 | #url = cfg['repository']['url'] |
549 | 745 | if new_profiles: | 752 | if new_profiles: |
551 | 746 | if UI_mode == 'yast': | 753 | if aaui.UI_mode == 'yast': |
552 | 747 | title = 'New Profiles' | 754 | title = 'New Profiles' |
553 | 748 | message = 'Please select the newly created profiles that you would like to store in the repository' | 755 | message = 'Please select the newly created profiles that you would like to store in the repository' |
554 | 749 | yast_select_and_upload_profiles(title, message, new_profiles) | 756 | yast_select_and_upload_profiles(title, message, new_profiles) |
555 | @@ -755,7 +762,7 @@ | |||
556 | 755 | def submit_changed_profiles(changed_profiles): | 762 | def submit_changed_profiles(changed_profiles): |
557 | 756 | #url = cfg['repository']['url'] | 763 | #url = cfg['repository']['url'] |
558 | 757 | if changed_profiles: | 764 | if changed_profiles: |
560 | 758 | if UI_mode == 'yast': | 765 | if aaui.UI_mode == 'yast': |
561 | 759 | title = 'Changed Profiles' | 766 | title = 'Changed Profiles' |
562 | 760 | message = 'Please select which of the changed profiles would you like to upload to the repository' | 767 | message = 'Please select which of the changed profiles would you like to upload to the repository' |
563 | 761 | yast_select_and_upload_profiles(title, message, changed_profiles) | 768 | yast_select_and_upload_profiles(title, message, changed_profiles) |
564 | @@ -770,8 +777,7 @@ | |||
565 | 770 | profs = profiles_up[:] | 777 | profs = profiles_up[:] |
566 | 771 | for p in profs: | 778 | for p in profs: |
567 | 772 | profile_changes[p[0]] = get_profile_diff(p[2], p[1]) | 779 | profile_changes[p[0]] = get_profile_diff(p[2], p[1]) |
570 | 773 | SendDataToYast({ | 780 | SendDataToYast({'type': 'dialog-select-profiles', |
569 | 774 | 'type': 'dialog-select-profiles', | ||
571 | 775 | 'title': title, | 781 | 'title': title, |
572 | 776 | 'explanation': message, | 782 | 'explanation': message, |
573 | 777 | 'default_select': 'false', | 783 | 'default_select': 'false', |
574 | @@ -806,8 +812,8 @@ | |||
575 | 806 | else: | 812 | else: |
576 | 807 | if not ret: | 813 | if not ret: |
577 | 808 | ret = 'UNKNOWN ERROR' | 814 | ret = 'UNKNOWN ERROR' |
580 | 809 | UI_Important(_('WARNING: An error occurred while uploading the profile %s\n%s') % (p, ret)) | 815 | aaui.UI_Important(_('WARNING: An error occurred while uploading the profile %s\n%s') % (p, ret)) |
581 | 810 | UI_Info(_('Uploaded changes to repository.')) | 816 | aaui.UI_Info(_('Uploaded changes to repository.')) |
582 | 811 | if yarg.get('NEVER_ASK_AGAIN'): | 817 | if yarg.get('NEVER_ASK_AGAIN'): |
583 | 812 | unselected_profiles = [] | 818 | unselected_profiles = [] |
584 | 813 | for p in profs: | 819 | for p in profs: |
585 | @@ -833,13 +839,13 @@ | |||
586 | 833 | q['selected'] = 0 | 839 | q['selected'] = 0 |
587 | 834 | ans = '' | 840 | ans = '' |
588 | 835 | while 'CMD_UPLOAD_CHANGES' not in ans and 'CMD_ASK_NEVER' not in ans and 'CMD_ASK_LATER' not in ans: | 841 | while 'CMD_UPLOAD_CHANGES' not in ans and 'CMD_ASK_NEVER' not in ans and 'CMD_ASK_LATER' not in ans: |
590 | 836 | ans, arg = UI_PromptUser(q) | 842 | ans, arg = aaui.UI_PromptUser(q) |
591 | 837 | if ans == 'CMD_VIEW_CHANGES': | 843 | if ans == 'CMD_VIEW_CHANGES': |
592 | 838 | display_changes(profs[arg][2], profs[arg][1]) | 844 | display_changes(profs[arg][2], profs[arg][1]) |
593 | 839 | if ans == 'CMD_NEVER_ASK': | 845 | if ans == 'CMD_NEVER_ASK': |
594 | 840 | set_profiles_local_only([i[0] for i in profs]) | 846 | set_profiles_local_only([i[0] for i in profs]) |
595 | 841 | elif ans == 'CMD_UPLOAD_CHANGES': | 847 | elif ans == 'CMD_UPLOAD_CHANGES': |
597 | 842 | changelog = UI_GetString(_('Changelog Entry: '), '') | 848 | changelog = aaui.UI_GetString(_('Changelog Entry: '), '') |
598 | 843 | user, passw = get_repo_user_pass() | 849 | user, passw = get_repo_user_pass() |
599 | 844 | if user and passw: | 850 | if user and passw: |
600 | 845 | for p_data in profs: | 851 | for p_data in profs: |
601 | @@ -847,19 +853,19 @@ | |||
602 | 847 | prof_string = p_data[1] | 853 | prof_string = p_data[1] |
603 | 848 | status_ok, ret = upload_profile(url, user, passw, | 854 | status_ok, ret = upload_profile(url, user, passw, |
604 | 849 | cfg['repository']['distro'], | 855 | cfg['repository']['distro'], |
606 | 850 | prof, prof_string, changelog ) | 856 | prof, prof_string, changelog) |
607 | 851 | if status_ok: | 857 | if status_ok: |
608 | 852 | newprof = ret | 858 | newprof = ret |
609 | 853 | newid = newprof['id'] | 859 | newid = newprof['id'] |
610 | 854 | set_repo_info(aa[prof][prof], url, user, newid) | 860 | set_repo_info(aa[prof][prof], url, user, newid) |
611 | 855 | write_profile_ui_feedback(prof) | 861 | write_profile_ui_feedback(prof) |
613 | 856 | UI_Info('Uploaded %s to repository' % prof) | 862 | aaui.UI_Info('Uploaded %s to repository' % prof) |
614 | 857 | else: | 863 | else: |
615 | 858 | if not ret: | 864 | if not ret: |
616 | 859 | ret = 'UNKNOWN ERROR' | 865 | ret = 'UNKNOWN ERROR' |
618 | 860 | UI_Important(_('WARNING: An error occurred while uploading the profile %s\n%s') % (prof, ret)) | 866 | aaui.UI_Important(_('WARNING: An error occurred while uploading the profile %s\n%s') % (prof, ret)) |
619 | 861 | else: | 867 | else: |
621 | 862 | UI_Important(_('Repository Error\nRegistration or Signin was unsuccessful. User login\ninformation is required to upload profiles to the repository.\nThese changes could not be sent.')) | 868 | aaui.UI_Important(_('Repository Error\nRegistration or Signin was unsuccessful. User login\ninformation is required to upload profiles to the repository.\nThese changes could not be sent.')) |
622 | 863 | 869 | ||
623 | 864 | def set_profiles_local_only(profs): | 870 | def set_profiles_local_only(profs): |
624 | 865 | for p in profs: | 871 | for p in profs: |
625 | @@ -886,7 +892,7 @@ | |||
626 | 886 | ret_list.append('CMD_EXEC_IX_OFF') | 892 | ret_list.append('CMD_EXEC_IX_OFF') |
627 | 887 | if 'u' in options: | 893 | if 'u' in options: |
628 | 888 | ret_list.append('CMD_ux') | 894 | ret_list.append('CMD_ux') |
630 | 889 | 895 | ||
631 | 890 | else: | 896 | else: |
632 | 891 | if 'i' in options: | 897 | if 'i' in options: |
633 | 892 | ret_list.append('CMD_ix') | 898 | ret_list.append('CMD_ix') |
634 | @@ -985,7 +991,7 @@ | |||
635 | 985 | 991 | ||
636 | 986 | seen_events += 1 | 992 | seen_events += 1 |
637 | 987 | 993 | ||
639 | 988 | ans = UI_PromptUser(q) | 994 | ans = aaui.UI_PromptUser(q) |
640 | 989 | 995 | ||
641 | 990 | transitions[context] = ans | 996 | transitions[context] = ans |
642 | 991 | 997 | ||
643 | @@ -1043,7 +1049,7 @@ | |||
644 | 1043 | else: | 1049 | else: |
645 | 1044 | do_execute = True | 1050 | do_execute = True |
646 | 1045 | 1051 | ||
648 | 1046 | if mode & AA_MAY_LINK: | 1052 | if mode & apparmor.aamode.AA_MAY_LINK: |
649 | 1047 | regex_link = re.compile('^from (.+) to (.+)$') | 1053 | regex_link = re.compile('^from (.+) to (.+)$') |
650 | 1048 | match = regex_link.search(detail) | 1054 | match = regex_link.search(detail) |
651 | 1049 | if match: | 1055 | if match: |
652 | @@ -1090,7 +1096,7 @@ | |||
653 | 1090 | combinedaudit = set() | 1096 | combinedaudit = set() |
654 | 1091 | ## Check return Value Consistency | 1097 | ## Check return Value Consistency |
655 | 1092 | # Check if path matches any existing regexps in profile | 1098 | # Check if path matches any existing regexps in profile |
657 | 1093 | cm, am , m = rematchfrag(aa[profile][hat], 'allow', exec_target) | 1099 | cm, am, m = rematchfrag(aa[profile][hat], 'allow', exec_target) |
658 | 1094 | if cm: | 1100 | if cm: |
659 | 1095 | combinedmode |= cm | 1101 | combinedmode |= cm |
660 | 1096 | if am: | 1102 | if am: |
661 | @@ -1202,7 +1208,7 @@ | |||
662 | 1202 | default = None | 1208 | default = None |
663 | 1203 | if 'p' in options and os.path.exists(get_profile_filename(exec_target)): | 1209 | if 'p' in options and os.path.exists(get_profile_filename(exec_target)): |
664 | 1204 | default = 'CMD_px' | 1210 | default = 'CMD_px' |
666 | 1205 | sys.stdout.write(_('Target profile exists: %s\n') %get_profile_filename(exec_target)) | 1211 | sys.stdout.write(_('Target profile exists: %s\n') % get_profile_filename(exec_target)) |
667 | 1206 | elif 'i' in options: | 1212 | elif 'i' in options: |
668 | 1207 | default = 'CMD_ix' | 1213 | default = 'CMD_ix' |
669 | 1208 | elif 'c' in options: | 1214 | elif 'c' in options: |
670 | @@ -1241,7 +1247,7 @@ | |||
671 | 1241 | 1247 | ||
672 | 1242 | ans = '' | 1248 | ans = '' |
673 | 1243 | while not regex_options.search(ans): | 1249 | while not regex_options.search(ans): |
675 | 1244 | ans = UI_PromptUser(q)[0].strip() | 1250 | ans = aaui.UI_PromptUser(q)[0].strip() |
676 | 1245 | if ans.startswith('CMD_EXEC_IX_'): | 1251 | if ans.startswith('CMD_EXEC_IX_'): |
677 | 1246 | exec_toggle = not exec_toggle | 1252 | exec_toggle = not exec_toggle |
678 | 1247 | q['functions'] = [] | 1253 | q['functions'] = [] |
679 | @@ -1252,7 +1258,7 @@ | |||
680 | 1252 | arg = exec_target | 1258 | arg = exec_target |
681 | 1253 | ynans = 'n' | 1259 | ynans = 'n' |
682 | 1254 | if profile == hat: | 1260 | if profile == hat: |
684 | 1255 | ynans = UI_YesNo(_('Are you specifying a transition to a local profile?'), 'n') | 1261 | ynans = aaui.UI_YesNo(_('Are you specifying a transition to a local profile?'), 'n') |
685 | 1256 | if ynans == 'y': | 1262 | if ynans == 'y': |
686 | 1257 | if ans == 'CMD_nx': | 1263 | if ans == 'CMD_nx': |
687 | 1258 | ans = 'CMD_cx' | 1264 | ans = 'CMD_cx' |
688 | @@ -1264,7 +1270,7 @@ | |||
689 | 1264 | else: | 1270 | else: |
690 | 1265 | ans = 'CMD_pix' | 1271 | ans = 'CMD_pix' |
691 | 1266 | 1272 | ||
693 | 1267 | to_name = UI_GetString(_('Enter profile name to transition to: '), arg) | 1273 | to_name = aaui.UI_GetString(_('Enter profile name to transition to: '), arg) |
694 | 1268 | 1274 | ||
695 | 1269 | regex_optmode = re.compile('CMD_(px|cx|nx|pix|cix|nix)') | 1275 | regex_optmode = re.compile('CMD_(px|cx|nx|pix|cix|nix)') |
696 | 1270 | if ans == 'CMD_ix': | 1276 | if ans == 'CMD_ix': |
697 | @@ -1277,18 +1283,18 @@ | |||
698 | 1277 | if parent_uses_ld_xxx: | 1283 | if parent_uses_ld_xxx: |
699 | 1278 | px_msg = _("Should AppArmor sanitise the environment when\nswitching profiles?\n\nSanitising environment is more secure,\nbut this application appears to be using LD_PRELOAD\nor LD_LIBRARY_PATH and sanitising the environment\ncould cause functionality problems.") | 1284 | px_msg = _("Should AppArmor sanitise the environment when\nswitching profiles?\n\nSanitising environment is more secure,\nbut this application appears to be using LD_PRELOAD\nor LD_LIBRARY_PATH and sanitising the environment\ncould cause functionality problems.") |
700 | 1279 | 1285 | ||
702 | 1280 | ynans = UI_YesNo(px_msg, px_default) | 1286 | ynans = aaui.UI_YesNo(px_msg, px_default) |
703 | 1281 | if ynans == 'y': | 1287 | if ynans == 'y': |
704 | 1282 | # Disable the unsafe mode | 1288 | # Disable the unsafe mode |
706 | 1283 | exec_mode = exec_mode - (AA_EXEC_UNSAFE | AA_OTHER(AA_EXEC_UNSAFE)) | 1289 | exec_mode = exec_mode - (apparmor.aamode.AA_EXEC_UNSAFE | AA_OTHER(apparmor.aamode.AA_EXEC_UNSAFE)) |
707 | 1284 | elif ans == 'CMD_ux': | 1290 | elif ans == 'CMD_ux': |
708 | 1285 | exec_mode = str_to_mode('ux') | 1291 | exec_mode = str_to_mode('ux') |
710 | 1286 | ynans = UI_YesNo(_("Launching processes in an unconfined state is a very\ndangerous operation and can cause serious security holes.\n\nAre you absolutely certain you wish to remove all\nAppArmor protection when executing %s ?") % exec_target, 'n') | 1292 | ynans = aaui.UI_YesNo(_("Launching processes in an unconfined state is a very\ndangerous operation and can cause serious security holes.\n\nAre you absolutely certain you wish to remove all\nAppArmor protection when executing %s ?") % exec_target, 'n') |
711 | 1287 | if ynans == 'y': | 1293 | if ynans == 'y': |
713 | 1288 | ynans = UI_YesNo(_("Should AppArmor sanitise the environment when\nrunning this program unconfined?\n\nNot sanitising the environment when unconfining\na program opens up significant security holes\nand should be avoided if at all possible."), 'y') | 1294 | ynans = aaui.UI_YesNo(_("Should AppArmor sanitise the environment when\nrunning this program unconfined?\n\nNot sanitising the environment when unconfining\na program opens up significant security holes\nand should be avoided if at all possible."), 'y') |
714 | 1289 | if ynans == 'y': | 1295 | if ynans == 'y': |
715 | 1290 | # Disable the unsafe mode | 1296 | # Disable the unsafe mode |
717 | 1291 | exec_mode = exec_mode - (AA_EXEC_UNSAFE | AA_OTHER(AA_EXEC_UNSAFE)) | 1297 | exec_mode = exec_mode - (apparmor.aamode.AA_EXEC_UNSAFE | AA_OTHER(apparmor.aamode.AA_EXEC_UNSAFE)) |
718 | 1292 | else: | 1298 | else: |
719 | 1293 | ans = 'INVALID' | 1299 | ans = 'INVALID' |
720 | 1294 | transitions[context_new] = ans | 1300 | transitions[context_new] = ans |
721 | @@ -1345,7 +1351,7 @@ | |||
722 | 1345 | 1351 | ||
723 | 1346 | if ans == 'CMD_ix': | 1352 | if ans == 'CMD_ix': |
724 | 1347 | if hat: | 1353 | if hat: |
726 | 1348 | profile_changes[pid] = '%s//%s' %(profile, hat) | 1354 | profile_changes[pid] = '%s//%s' % (profile, hat) |
727 | 1349 | else: | 1355 | else: |
728 | 1350 | profile_changes[pid] = '%s//' % profile | 1356 | profile_changes[pid] = '%s//' % profile |
729 | 1351 | elif re.search('^CMD_(px|nx|pix|nix)', ans): | 1357 | elif re.search('^CMD_(px|nx|pix|nix)', ans): |
730 | @@ -1361,7 +1367,7 @@ | |||
731 | 1361 | if not os.path.exists(get_profile_filename(exec_target)): | 1367 | if not os.path.exists(get_profile_filename(exec_target)): |
732 | 1362 | ynans = 'y' | 1368 | ynans = 'y' |
733 | 1363 | if exec_mode & str_to_mode('i'): | 1369 | if exec_mode & str_to_mode('i'): |
735 | 1364 | ynans = UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') %exec_target, 'n') | 1370 | ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n') |
736 | 1365 | if ynans == 'y': | 1371 | if ynans == 'y': |
737 | 1366 | helpers[exec_target] = 'enforce' | 1372 | helpers[exec_target] = 'enforce' |
738 | 1367 | if to_name: | 1373 | if to_name: |
739 | @@ -1379,7 +1385,7 @@ | |||
740 | 1379 | if not aa[profile].get(exec_target, False): | 1385 | if not aa[profile].get(exec_target, False): |
741 | 1380 | ynans = 'y' | 1386 | ynans = 'y' |
742 | 1381 | if exec_mode & str_to_mode('i'): | 1387 | if exec_mode & str_to_mode('i'): |
744 | 1382 | ynans = UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n') | 1388 | ynans = aaui.UI_YesNo(_('A profile for %s does not exist.\nDo you want to create one?') % exec_target, 'n') |
745 | 1383 | if ynans == 'y': | 1389 | if ynans == 'y': |
746 | 1384 | hat = exec_target | 1390 | hat = exec_target |
747 | 1385 | aa[profile][hat]['declared'] = False | 1391 | aa[profile][hat]['declared'] = False |
748 | @@ -1488,9 +1494,9 @@ | |||
749 | 1488 | for aamode in sorted(log_dict.keys()): | 1494 | for aamode in sorted(log_dict.keys()): |
750 | 1489 | # Describe the type of changes | 1495 | # Describe the type of changes |
751 | 1490 | if aamode == 'PERMITTING': | 1496 | if aamode == 'PERMITTING': |
753 | 1491 | UI_Info(_('Complain-mode changes:')) | 1497 | aaui.UI_Info(_('Complain-mode changes:')) |
754 | 1492 | elif aamode == 'REJECTING': | 1498 | elif aamode == 'REJECTING': |
756 | 1493 | UI_Info(_('Enforce-mode changes:')) | 1499 | aaui.UI_Info(_('Enforce-mode changes:')) |
757 | 1494 | else: | 1500 | else: |
758 | 1495 | # This is so wrong! | 1501 | # This is so wrong! |
759 | 1496 | fatal_error(_('Invalid mode found: %s') % aamode) | 1502 | fatal_error(_('Invalid mode found: %s') % aamode) |
760 | @@ -1520,7 +1526,7 @@ | |||
761 | 1520 | q = hasher() | 1526 | q = hasher() |
762 | 1521 | 1527 | ||
763 | 1522 | if newincludes: | 1528 | if newincludes: |
765 | 1523 | options += list(map(lambda inc: '#include <%s>' %inc, sorted(set(newincludes)))) | 1529 | options += list(map(lambda inc: '#include <%s>' % inc, sorted(set(newincludes)))) |
766 | 1524 | 1530 | ||
767 | 1525 | if options: | 1531 | if options: |
768 | 1526 | options.append('capability %s' % capability) | 1532 | options.append('capability %s' % capability) |
769 | @@ -1546,7 +1552,7 @@ | |||
770 | 1546 | 1552 | ||
771 | 1547 | done = False | 1553 | done = False |
772 | 1548 | while not done: | 1554 | while not done: |
774 | 1549 | ans, selected = UI_PromptUser(q) | 1555 | ans, selected = aaui.UI_PromptUser(q) |
775 | 1550 | # Ignore the log entry | 1556 | # Ignore the log entry |
776 | 1551 | if ans == 'CMD_IGNORE_ENTRY': | 1557 | if ans == 'CMD_IGNORE_ENTRY': |
777 | 1552 | done = True | 1558 | done = True |
778 | @@ -1574,27 +1580,27 @@ | |||
779 | 1574 | match = re_match_include(selection) | 1580 | match = re_match_include(selection) |
780 | 1575 | if match: | 1581 | if match: |
781 | 1576 | deleted = False | 1582 | deleted = False |
783 | 1577 | inc = match #.groups()[0] | 1583 | inc = match # .groups()[0] |
784 | 1578 | deleted = delete_duplicates(aa[profile][hat], inc) | 1584 | deleted = delete_duplicates(aa[profile][hat], inc) |
785 | 1579 | aa[profile][hat]['include'][inc] = True | 1585 | aa[profile][hat]['include'][inc] = True |
786 | 1580 | 1586 | ||
788 | 1581 | UI_Info(_('Adding %s to profile.') % selection) | 1587 | aaui.UI_Info(_('Adding %s to profile.') % selection) |
789 | 1582 | if deleted: | 1588 | if deleted: |
791 | 1583 | UI_Info(_('Deleted %s previous matching profile entries.') % deleted) | 1589 | aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) |
792 | 1584 | 1590 | ||
793 | 1585 | aa[profile][hat]['allow']['capability'][capability]['set'] = True | 1591 | aa[profile][hat]['allow']['capability'][capability]['set'] = True |
794 | 1586 | aa[profile][hat]['allow']['capability'][capability]['audit'] = audit_toggle | 1592 | aa[profile][hat]['allow']['capability'][capability]['audit'] = audit_toggle |
795 | 1587 | 1593 | ||
796 | 1588 | changed[profile] = True | 1594 | changed[profile] = True |
797 | 1589 | 1595 | ||
799 | 1590 | UI_Info(_('Adding capability %s to profile.') % capability) | 1596 | aaui.UI_Info(_('Adding capability %s to profile.') % capability) |
800 | 1591 | done = True | 1597 | done = True |
801 | 1592 | 1598 | ||
802 | 1593 | elif ans == 'CMD_DENY': | 1599 | elif ans == 'CMD_DENY': |
803 | 1594 | aa[profile][hat]['deny']['capability'][capability]['set'] = True | 1600 | aa[profile][hat]['deny']['capability'][capability]['set'] = True |
804 | 1595 | changed[profile] = True | 1601 | changed[profile] = True |
805 | 1596 | 1602 | ||
807 | 1597 | UI_Info(_('Denying capability %s to profile.') % capability) | 1603 | aaui.UI_Info(_('Denying capability %s to profile.') % capability) |
808 | 1598 | done = True | 1604 | done = True |
809 | 1599 | else: | 1605 | else: |
810 | 1600 | done = False | 1606 | done = False |
811 | @@ -1632,7 +1638,7 @@ | |||
812 | 1632 | if cam: | 1638 | if cam: |
813 | 1633 | deny_audit |= cam | 1639 | deny_audit |= cam |
814 | 1634 | 1640 | ||
816 | 1635 | if deny_mode & AA_MAY_EXEC: | 1641 | if deny_mode & apparmor.aamode.AA_MAY_EXEC: |
817 | 1636 | deny_mode |= apparmor.aamode.ALL_AA_EXEC_TYPE | 1642 | deny_mode |= apparmor.aamode.ALL_AA_EXEC_TYPE |
818 | 1637 | 1643 | ||
819 | 1638 | # Mask off the denied modes | 1644 | # Mask off the denied modes |
820 | @@ -1641,10 +1647,10 @@ | |||
821 | 1641 | # If we get an exec request from some kindof event that generates 'PERMITTING X' | 1647 | # If we get an exec request from some kindof event that generates 'PERMITTING X' |
822 | 1642 | # check if its already in allow_mode | 1648 | # check if its already in allow_mode |
823 | 1643 | # if not add ix permission | 1649 | # if not add ix permission |
825 | 1644 | if mode & AA_MAY_EXEC: | 1650 | if mode & apparmor.aamode.AA_MAY_EXEC: |
826 | 1645 | # Remove all type access permission | 1651 | # Remove all type access permission |
827 | 1646 | mode = mode - apparmor.aamode.ALL_AA_EXEC_TYPE | 1652 | mode = mode - apparmor.aamode.ALL_AA_EXEC_TYPE |
829 | 1647 | if not allow_mode & AA_MAY_EXEC: | 1653 | if not allow_mode & apparmor.aamode.AA_MAY_EXEC: |
830 | 1648 | mode |= str_to_mode('ix') | 1654 | mode |= str_to_mode('ix') |
831 | 1649 | 1655 | ||
832 | 1650 | # m is not implied by ix | 1656 | # m is not implied by ix |
833 | @@ -1678,7 +1684,7 @@ | |||
834 | 1678 | if aa[profile][hat][incname]: | 1684 | if aa[profile][hat][incname]: |
835 | 1679 | continue | 1685 | continue |
836 | 1680 | if incname.startswith(profile_dir): | 1686 | if incname.startswith(profile_dir): |
838 | 1681 | incname = incname.replace(profile_dir+'/', '', 1) | 1687 | incname = incname.replace(profile_dir + '/', '', 1) |
839 | 1682 | 1688 | ||
840 | 1683 | include_valid = valid_include('', incname) | 1689 | include_valid = valid_include('', incname) |
841 | 1684 | 1690 | ||
842 | @@ -1725,7 +1731,7 @@ | |||
843 | 1725 | owner_toggle = cfg['settings']['default_owner_prompt'] | 1731 | owner_toggle = cfg['settings']['default_owner_prompt'] |
844 | 1726 | done = False | 1732 | done = False |
845 | 1727 | while not done: | 1733 | while not done: |
847 | 1728 | q = hasher() | 1734 | q = hasher() |
848 | 1729 | q['headers'] = [_('Profile'), combine_name(profile, hat), | 1735 | q['headers'] = [_('Profile'), combine_name(profile, hat), |
849 | 1730 | _('Path'), path] | 1736 | _('Path'), path] |
850 | 1731 | 1737 | ||
851 | @@ -1789,7 +1795,7 @@ | |||
852 | 1789 | 1795 | ||
853 | 1790 | seen_events += 1 | 1796 | seen_events += 1 |
854 | 1791 | 1797 | ||
856 | 1792 | ans, selected = UI_PromptUser(q) | 1798 | ans, selected = aaui.UI_PromptUser(q) |
857 | 1793 | 1799 | ||
858 | 1794 | if ans == 'CMD_IGNORE_ENTRY': | 1800 | if ans == 'CMD_IGNORE_ENTRY': |
859 | 1795 | done = True | 1801 | done = True |
860 | @@ -1806,16 +1812,16 @@ | |||
861 | 1806 | elif ans == 'CMD_ALLOW': | 1812 | elif ans == 'CMD_ALLOW': |
862 | 1807 | path = options[selected] | 1813 | path = options[selected] |
863 | 1808 | done = True | 1814 | done = True |
865 | 1809 | match = re_match_include(path) #.search('^#include\s+<(.+)>$', path) | 1815 | match = re_match_include(path) # .search('^#include\s+<(.+)>$', path) |
866 | 1810 | if match: | 1816 | if match: |
868 | 1811 | inc = match #.groups()[0] | 1817 | inc = match # .groups()[0] |
869 | 1812 | deleted = 0 | 1818 | deleted = 0 |
870 | 1813 | deleted = delete_duplicates(aa[profile][hat], inc) | 1819 | deleted = delete_duplicates(aa[profile][hat], inc) |
874 | 1814 | aa[profile][hat]['include'][inc] = True | 1820 | aa[profile][hat]['include'][inc] = True |
875 | 1815 | changed[profile] = True | 1821 | changed[profile] = True |
876 | 1816 | UI_Info(_('Adding %s to profile.') % path) | 1822 | aaui.UI_Info(_('Adding %s to profile.') % path) |
877 | 1817 | if deleted: | 1823 | if deleted: |
879 | 1818 | UI_Info(_('Deleted %s previous matching profile entries.') % deleted) | 1824 | aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) |
880 | 1819 | 1825 | ||
881 | 1820 | else: | 1826 | else: |
882 | 1821 | if aa[profile][hat]['allow']['path'][path].get('mode', False): | 1827 | if aa[profile][hat]['allow']['path'][path].get('mode', False): |
883 | @@ -1845,7 +1851,7 @@ | |||
884 | 1845 | 1851 | ||
885 | 1846 | tmpmode = set() | 1852 | tmpmode = set() |
886 | 1847 | if audit_toggle == 1: | 1853 | if audit_toggle == 1: |
888 | 1848 | tmpmode = mode- allow_mode | 1854 | tmpmode = mode - allow_mode |
889 | 1849 | elif audit_toggle == 2: | 1855 | elif audit_toggle == 2: |
890 | 1850 | tmpmode = mode | 1856 | tmpmode = mode |
891 | 1851 | 1857 | ||
892 | @@ -1853,9 +1859,9 @@ | |||
893 | 1853 | 1859 | ||
894 | 1854 | changed[profile] = True | 1860 | changed[profile] = True |
895 | 1855 | 1861 | ||
897 | 1856 | UI_Info(_('Adding %s %s to profile') % (path, mode_to_str_user(mode))) | 1862 | aaui.UI_Info(_('Adding %s %s to profile') % (path, mode_to_str_user(mode))) |
898 | 1857 | if deleted: | 1863 | if deleted: |
900 | 1858 | UI_Info(_('Deleted %s previous matching profile entries.') % deleted) | 1864 | aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) |
901 | 1859 | 1865 | ||
902 | 1860 | elif ans == 'CMD_DENY': | 1866 | elif ans == 'CMD_DENY': |
903 | 1861 | path = options[selected].strip() | 1867 | path = options[selected].strip() |
904 | @@ -1871,11 +1877,11 @@ | |||
905 | 1871 | elif ans == 'CMD_NEW': | 1877 | elif ans == 'CMD_NEW': |
906 | 1872 | arg = options[selected] | 1878 | arg = options[selected] |
907 | 1873 | if not re_match_include(arg): | 1879 | if not re_match_include(arg): |
909 | 1874 | ans = UI_GetString(_('Enter new path: '), arg) | 1880 | ans = aaui.UI_GetString(_('Enter new path: '), arg) |
910 | 1875 | if ans: | 1881 | if ans: |
911 | 1876 | if not matchliteral(ans, path): | 1882 | if not matchliteral(ans, path): |
914 | 1877 | ynprompt = _('The specified path does not match this log entry:\n\n Log Entry: %s\n Entered Path: %s\nDo you really want to use this path?') % (path,ans) | 1883 | ynprompt = _('The specified path does not match this log entry:\n\n Log Entry: %s\n Entered Path: %s\nDo you really want to use this path?') % (path, ans) |
915 | 1878 | key = UI_YesNo(ynprompt, 'n') | 1884 | key = aaui.UI_YesNo(ynprompt, 'n') |
916 | 1879 | if key == 'n': | 1885 | if key == 'n': |
917 | 1880 | continue | 1886 | continue |
918 | 1881 | 1887 | ||
919 | @@ -1919,7 +1925,7 @@ | |||
920 | 1919 | newincludes = match_net_includes(aa[profile][hat], family, sock_type) | 1925 | newincludes = match_net_includes(aa[profile][hat], family, sock_type) |
921 | 1920 | q = hasher() | 1926 | q = hasher() |
922 | 1921 | if newincludes: | 1927 | if newincludes: |
924 | 1922 | options += list(map(lambda s: '#include <%s>'%s, sorted(set(newincludes)))) | 1928 | options += list(map(lambda s: '#include <%s>' % s, sorted(set(newincludes)))) |
925 | 1923 | if options: | 1929 | if options: |
926 | 1924 | options.append('network %s %s' % (family, sock_type)) | 1930 | options.append('network %s %s' % (family, sock_type)) |
927 | 1925 | q['options'] = options | 1931 | q['options'] = options |
928 | @@ -1941,7 +1947,7 @@ | |||
929 | 1941 | 1947 | ||
930 | 1942 | done = False | 1948 | done = False |
931 | 1943 | while not done: | 1949 | while not done: |
933 | 1944 | ans, selected = UI_PromptUser(q) | 1950 | ans, selected = aaui.UI_PromptUser(q) |
934 | 1945 | if ans == 'CMD_IGNORE_ENTRY': | 1951 | if ans == 'CMD_IGNORE_ENTRY': |
935 | 1946 | done = True | 1952 | done = True |
936 | 1947 | break | 1953 | break |
937 | @@ -1963,18 +1969,18 @@ | |||
938 | 1963 | elif ans == 'CMD_ALLOW': | 1969 | elif ans == 'CMD_ALLOW': |
939 | 1964 | selection = options[selected] | 1970 | selection = options[selected] |
940 | 1965 | done = True | 1971 | done = True |
944 | 1966 | if re_match_include(selection): #re.search('#include\s+<.+>$', selection): | 1972 | if re_match_include(selection): # re.search('#include\s+<.+>$', selection): |
945 | 1967 | inc = re_match_include(selection) #re.search('#include\s+<(.+)>$', selection).groups()[0] | 1973 | inc = re_match_include(selection) # re.search('#include\s+<(.+)>$', selection).groups()[0] |
946 | 1968 | deleted = 0 | 1974 | deleted = 0 |
947 | 1969 | deleted = delete_duplicates(aa[profile][hat], inc) | 1975 | deleted = delete_duplicates(aa[profile][hat], inc) |
948 | 1970 | 1976 | ||
949 | 1971 | aa[profile][hat]['include'][inc] = True | 1977 | aa[profile][hat]['include'][inc] = True |
950 | 1972 | 1978 | ||
951 | 1973 | changed[profile] = True | 1979 | changed[profile] = True |
952 | 1974 | 1980 | ||
954 | 1975 | UI_Info(_('Adding %s to profile') % selection) | 1981 | aaui.UI_Info(_('Adding %s to profile') % selection) |
955 | 1976 | if deleted: | 1982 | if deleted: |
957 | 1977 | UI_Info(_('Deleted %s previous matching profile entries.') % deleted) | 1983 | aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted) |
958 | 1978 | 1984 | ||
959 | 1979 | else: | 1985 | else: |
960 | 1980 | aa[profile][hat]['allow']['netdomain']['audit'][family][sock_type] = audit_toggle | 1986 | aa[profile][hat]['allow']['netdomain']['audit'][family][sock_type] = audit_toggle |
961 | @@ -1982,13 +1988,13 @@ | |||
962 | 1982 | 1988 | ||
963 | 1983 | changed[profile] = True | 1989 | changed[profile] = True |
964 | 1984 | 1990 | ||
966 | 1985 | UI_Info(_('Adding network access %s %s to profile.') % (family, sock_type)) | 1991 | aaui.UI_Info(_('Adding network access %s %s to profile.') % (family, sock_type)) |
967 | 1986 | 1992 | ||
968 | 1987 | elif ans == 'CMD_DENY': | 1993 | elif ans == 'CMD_DENY': |
969 | 1988 | done = True | 1994 | done = True |
970 | 1989 | aa[profile][hat]['deny']['netdomain']['rule'][family][sock_type] = True | 1995 | aa[profile][hat]['deny']['netdomain']['rule'][family][sock_type] = True |
971 | 1990 | changed[profile] = True | 1996 | changed[profile] = True |
973 | 1991 | UI_Info(_('Denying network access %s %s to profile') % (family, sock_type)) | 1997 | aaui.UI_Info(_('Denying network access %s %s to profile') % (family, sock_type)) |
974 | 1992 | 1998 | ||
975 | 1993 | else: | 1999 | else: |
976 | 1994 | done = False | 2000 | done = False |
977 | @@ -1998,13 +2004,13 @@ | |||
978 | 1998 | if newpath[-1] == '/': | 2004 | if newpath[-1] == '/': |
979 | 1999 | if newpath[-4:] == '/**/' or newpath[-3:] == '/*/': | 2005 | if newpath[-4:] == '/**/' or newpath[-3:] == '/*/': |
980 | 2000 | # /foo/**/ and /foo/*/ => /**/ | 2006 | # /foo/**/ and /foo/*/ => /**/ |
982 | 2001 | newpath = re.sub('/[^/]+/\*{1,2}/$', '/**/', newpath) #re.sub('/[^/]+/\*{1,2}$/', '/\*\*/', newpath) | 2007 | newpath = re.sub('/[^/]+/\*{1,2}/$', '/**/', newpath) # re.sub('/[^/]+/\*{1,2}$/', '/\*\*/', newpath) |
983 | 2002 | elif re.search('/[^/]+\*\*[^/]*/$', newpath): | 2008 | elif re.search('/[^/]+\*\*[^/]*/$', newpath): |
984 | 2003 | # /foo**/ and /foo**bar/ => /**/ | 2009 | # /foo**/ and /foo**bar/ => /**/ |
986 | 2004 | newpath = re.sub('/[^/]+\*\*[^/]*/$', '/**/', newpath) | 2010 | newpath = re.sub('/[^/]+\*\*[^/]*/$', '/**/', newpath) |
987 | 2005 | elif re.search('/\*\*[^/]+/$', newpath): | 2011 | elif re.search('/\*\*[^/]+/$', newpath): |
988 | 2006 | # /**bar/ => /**/ | 2012 | # /**bar/ => /**/ |
990 | 2007 | newpath = re.sub('/\*\*[^/]+/$', '/**/', newpath) | 2013 | newpath = re.sub('/\*\*[^/]+/$', '/**/', newpath) |
991 | 2008 | else: | 2014 | else: |
992 | 2009 | newpath = re.sub('/[^/]+/$', '/*/', newpath) | 2015 | newpath = re.sub('/[^/]+/$', '/*/', newpath) |
993 | 2010 | else: | 2016 | else: |
994 | @@ -2016,7 +2022,7 @@ | |||
995 | 2016 | newpath = re.sub('/[^/]*\*\*[^/]+$', '/**', newpath) | 2022 | newpath = re.sub('/[^/]*\*\*[^/]+$', '/**', newpath) |
996 | 2017 | elif re.search('/[^/]+\*\*$', newpath): | 2023 | elif re.search('/[^/]+\*\*$', newpath): |
997 | 2018 | # /foo** => /** | 2024 | # /foo** => /** |
999 | 2019 | newpath = re.sub('/[^/]+\*\*$', '/**', newpath) | 2025 | newpath = re.sub('/[^/]+\*\*$', '/**', newpath) |
1000 | 2020 | else: | 2026 | else: |
1001 | 2021 | newpath = re.sub('/[^/]+$', '/*', newpath) | 2027 | newpath = re.sub('/[^/]+$', '/*', newpath) |
1002 | 2022 | return newpath | 2028 | return newpath |
1003 | @@ -2027,19 +2033,19 @@ | |||
1004 | 2027 | match = re.search('/\*{1,2}(\.[^/]+)$', newpath) | 2033 | match = re.search('/\*{1,2}(\.[^/]+)$', newpath) |
1005 | 2028 | if match: | 2034 | if match: |
1006 | 2029 | # /foo/**.ext and /foo/*.ext => /**.ext | 2035 | # /foo/**.ext and /foo/*.ext => /**.ext |
1008 | 2030 | newpath = re.sub('/[^/]+/\*{1,2}\.[^/]+$', '/**'+match.groups()[0], newpath) | 2036 | newpath = re.sub('/[^/]+/\*{1,2}\.[^/]+$', '/**' + match.groups()[0], newpath) |
1009 | 2031 | elif re.search('/[^/]+\*\*[^/]*\.[^/]+$', newpath): | 2037 | elif re.search('/[^/]+\*\*[^/]*\.[^/]+$', newpath): |
1010 | 2032 | # /foo**.ext and /foo**bar.ext => /**.ext | 2038 | # /foo**.ext and /foo**bar.ext => /**.ext |
1011 | 2033 | match = re.search('/[^/]+\*\*[^/]*(\.[^/]+)$', newpath) | 2039 | match = re.search('/[^/]+\*\*[^/]*(\.[^/]+)$', newpath) |
1013 | 2034 | newpath = re.sub('/[^/]+\*\*[^/]*\.[^/]+$', '/**'+match.groups()[0], newpath) | 2040 | newpath = re.sub('/[^/]+\*\*[^/]*\.[^/]+$', '/**' + match.groups()[0], newpath) |
1014 | 2035 | elif re.search('/\*\*[^/]+\.[^/]+$', newpath): | 2041 | elif re.search('/\*\*[^/]+\.[^/]+$', newpath): |
1015 | 2036 | # /**foo.ext => /**.ext | 2042 | # /**foo.ext => /**.ext |
1016 | 2037 | match = re.search('/\*\*[^/]+(\.[^/]+)$', newpath) | 2043 | match = re.search('/\*\*[^/]+(\.[^/]+)$', newpath) |
1018 | 2038 | newpath = re.sub('/\*\*[^/]+\.[^/]+$', '/**'+match.groups()[0], newpath) | 2044 | newpath = re.sub('/\*\*[^/]+\.[^/]+$', '/**' + match.groups()[0], newpath) |
1019 | 2039 | else: | 2045 | else: |
1020 | 2040 | match = re.search('(\.[^/]+)$', newpath) | 2046 | match = re.search('(\.[^/]+)$', newpath) |
1021 | 2041 | if match: | 2047 | if match: |
1023 | 2042 | newpath = re.sub('/[^/]+(\.[^/]+)$', '/*'+match.groups()[0], newpath) | 2048 | newpath = re.sub('/[^/]+(\.[^/]+)$', '/*' + match.groups()[0], newpath) |
1024 | 2043 | return newpath | 2049 | return newpath |
1025 | 2044 | 2050 | ||
1026 | 2045 | def delete_net_duplicates(netrules, incnetrules): | 2051 | def delete_net_duplicates(netrules, incnetrules): |
1027 | @@ -2081,7 +2087,7 @@ | |||
1028 | 2081 | def delete_path_duplicates(profile, incname, allow): | 2087 | def delete_path_duplicates(profile, incname, allow): |
1029 | 2082 | deleted = [] | 2088 | deleted = [] |
1030 | 2083 | for entry in profile[allow]['path'].keys(): | 2089 | for entry in profile[allow]['path'].keys(): |
1032 | 2084 | if entry == '#include <%s>'%incname: | 2090 | if entry == '#include <%s>' % incname: |
1033 | 2085 | continue | 2091 | continue |
1034 | 2086 | cm, am, m = match_include_to_path(incname, allow, entry) | 2092 | cm, am, m = match_include_to_path(incname, allow, entry) |
1035 | 2087 | if cm and mode_contains(cm, profile[allow]['path'][entry]['mode']) and mode_contains(am, profile[allow]['path'][entry]['audit']): | 2093 | if cm and mode_contains(cm, profile[allow]['path'][entry]['mode']) and mode_contains(am, profile[allow]['path'][entry]['audit']): |
1036 | @@ -2201,10 +2207,10 @@ | |||
1037 | 2201 | skip = hasher() | 2207 | skip = hasher() |
1038 | 2202 | # filelist = hasher() | 2208 | # filelist = hasher() |
1039 | 2203 | 2209 | ||
1041 | 2204 | UI_Info(_('Reading log entries from %s.') %filename) | 2210 | aaui.UI_Info(_('Reading log entries from %s.') % filename) |
1042 | 2205 | 2211 | ||
1043 | 2206 | if not passno: | 2212 | if not passno: |
1045 | 2207 | UI_Info(_('Updating AppArmor profiles in %s.') %profile_dir) | 2213 | aaui.UI_Info(_('Updating AppArmor profiles in %s.') % profile_dir) |
1046 | 2208 | read_profiles() | 2214 | read_profiles() |
1047 | 2209 | 2215 | ||
1048 | 2210 | if not sev_db: | 2216 | if not sev_db: |
1049 | @@ -2231,7 +2237,7 @@ | |||
1050 | 2231 | 2237 | ||
1051 | 2232 | ask_the_questions() | 2238 | ask_the_questions() |
1052 | 2233 | 2239 | ||
1054 | 2234 | if UI_mode == 'yast': | 2240 | if aaui.UI_mode == 'yast': |
1055 | 2235 | # To-Do | 2241 | # To-Do |
1056 | 2236 | pass | 2242 | pass |
1057 | 2237 | 2243 | ||
1058 | @@ -2263,7 +2269,7 @@ | |||
1059 | 2263 | 2269 | ||
1060 | 2264 | if changed_list: | 2270 | if changed_list: |
1061 | 2265 | 2271 | ||
1063 | 2266 | if UI_mode == 'yast': | 2272 | if aaui.UI_mode == 'yast': |
1064 | 2267 | # To-Do | 2273 | # To-Do |
1065 | 2268 | selected_profiles = [] | 2274 | selected_profiles = [] |
1066 | 2269 | profile_changes = dict() | 2275 | profile_changes = dict() |
1067 | @@ -2273,8 +2279,7 @@ | |||
1068 | 2273 | profile_changes[prof] = get_profile_diff(oldprofile, newprofile) | 2279 | profile_changes[prof] = get_profile_diff(oldprofile, newprofile) |
1069 | 2274 | explanation = _('Select which profile changes you would like to save to the\nlocal profile set.') | 2280 | explanation = _('Select which profile changes you would like to save to the\nlocal profile set.') |
1070 | 2275 | title = _('Local profile changes') | 2281 | title = _('Local profile changes') |
1073 | 2276 | SendDataToYast({ | 2282 | SendDataToYast({'type': 'dialog-select-profiles', |
1072 | 2277 | 'type': 'dialog-select-profiles', | ||
1074 | 2278 | 'title': title, | 2283 | 'title': title, |
1075 | 2279 | 'explanation': explanation, | 2284 | 'explanation': explanation, |
1076 | 2280 | 'dialog_select': 'true', | 2285 | 'dialog_select': 'true', |
1077 | @@ -2299,13 +2304,13 @@ | |||
1078 | 2299 | q['default'] = 'CMD_VIEW_CHANGES' | 2304 | q['default'] = 'CMD_VIEW_CHANGES' |
1079 | 2300 | q['options'] = changed | 2305 | q['options'] = changed |
1080 | 2301 | q['selected'] = 0 | 2306 | q['selected'] = 0 |
1082 | 2302 | p =None | 2307 | p = None |
1083 | 2303 | ans = '' | 2308 | ans = '' |
1084 | 2304 | arg = None | 2309 | arg = None |
1085 | 2305 | while ans != 'CMD_SAVE_CHANGES': | 2310 | while ans != 'CMD_SAVE_CHANGES': |
1086 | 2306 | if not changed: | 2311 | if not changed: |
1087 | 2307 | return | 2312 | return |
1089 | 2308 | ans, arg = UI_PromptUser(q) | 2313 | ans, arg = aaui.UI_PromptUser(q) |
1090 | 2309 | if ans == 'CMD_SAVE_SELECTED': | 2314 | if ans == 'CMD_SAVE_SELECTED': |
1091 | 2310 | profile_name = list(changed.keys())[arg] | 2315 | profile_name = list(changed.keys())[arg] |
1092 | 2311 | write_profile_ui_feedback(profile_name) | 2316 | write_profile_ui_feedback(profile_name) |
1093 | @@ -2350,7 +2355,7 @@ | |||
1094 | 2350 | 2355 | ||
1095 | 2351 | difftemp = tempfile.NamedTemporaryFile('w', delete=False) | 2356 | difftemp = tempfile.NamedTemporaryFile('w', delete=False) |
1096 | 2352 | 2357 | ||
1098 | 2353 | subprocess.call('diff -u -p %s %s > %s' %(oldtemp.name, newtemp.name, difftemp.name), shell=True) | 2358 | subprocess.call('diff -u -p %s %s > %s' % (oldtemp.name, newtemp.name, difftemp.name), shell=True) |
1099 | 2354 | 2359 | ||
1100 | 2355 | oldtemp.close() | 2360 | oldtemp.close() |
1101 | 2356 | newtemp.close() | 2361 | newtemp.close() |
1102 | @@ -2369,19 +2374,19 @@ | |||
1103 | 2369 | return ''.join(diff) | 2374 | return ''.join(diff) |
1104 | 2370 | 2375 | ||
1105 | 2371 | def display_changes(oldprofile, newprofile): | 2376 | def display_changes(oldprofile, newprofile): |
1108 | 2372 | if UI_mode == 'yast': | 2377 | if aaui.UI_mode == 'yast': |
1109 | 2373 | UI_LongMessage(_('Profile Changes'), get_profile_diff(oldprofile, newprofile)) | 2378 | aaui.UI_LongMessage(_('Profile Changes'), get_profile_diff(oldprofile, newprofile)) |
1110 | 2374 | else: | 2379 | else: |
1111 | 2375 | difftemp = generate_diff(oldprofile, newprofile) | 2380 | difftemp = generate_diff(oldprofile, newprofile) |
1113 | 2376 | subprocess.call('less %s' %difftemp.name, shell=True) | 2381 | subprocess.call('less %s' % difftemp.name, shell=True) |
1114 | 2377 | difftemp.delete = True | 2382 | difftemp.delete = True |
1115 | 2378 | difftemp.close() | 2383 | difftemp.close() |
1116 | 2379 | 2384 | ||
1117 | 2380 | def display_changes_with_comments(oldprofile, newprofile): | 2385 | def display_changes_with_comments(oldprofile, newprofile): |
1118 | 2381 | """Compare the new profile with the existing profile inclusive of all the comments""" | 2386 | """Compare the new profile with the existing profile inclusive of all the comments""" |
1119 | 2382 | if not os.path.exists(oldprofile): | 2387 | if not os.path.exists(oldprofile): |
1122 | 2383 | raise AppArmorException(_("Can't find existing profile %s to compare changes.") %oldprofile) | 2388 | raise AppArmorException(_("Can't find existing profile %s to compare changes.") % oldprofile) |
1123 | 2384 | if UI_mode == 'yast': | 2389 | if aaui.UI_mode == 'yast': |
1124 | 2385 | #To-Do | 2390 | #To-Do |
1125 | 2386 | pass | 2391 | pass |
1126 | 2387 | else: | 2392 | else: |
1127 | @@ -2391,10 +2396,10 @@ | |||
1128 | 2391 | 2396 | ||
1129 | 2392 | difftemp = tempfile.NamedTemporaryFile('w') | 2397 | difftemp = tempfile.NamedTemporaryFile('w') |
1130 | 2393 | 2398 | ||
1132 | 2394 | subprocess.call('diff -u -p %s %s > %s' %(oldprofile, newtemp.name, difftemp.name), shell=True) | 2399 | subprocess.call('diff -u -p %s %s > %s' % (oldprofile, newtemp.name, difftemp.name), shell=True) |
1133 | 2395 | 2400 | ||
1134 | 2396 | newtemp.close() | 2401 | newtemp.close() |
1136 | 2397 | subprocess.call('less %s' %difftemp.name, shell=True) | 2402 | subprocess.call('less %s' % difftemp.name, shell=True) |
1137 | 2398 | difftemp.close() | 2403 | difftemp.close() |
1138 | 2399 | 2404 | ||
1139 | 2400 | def set_process(pid, profile): | 2405 | def set_process(pid, profile): |
1140 | @@ -2497,8 +2502,8 @@ | |||
1141 | 2497 | def is_skippable_file(path): | 2502 | def is_skippable_file(path): |
1142 | 2498 | """Returns True if filename matches something to be skipped""" | 2503 | """Returns True if filename matches something to be skipped""" |
1143 | 2499 | if (re.search('(^|/)\.[^/]*$', path) or re.search('\.rpm(save|new)$', path) | 2504 | if (re.search('(^|/)\.[^/]*$', path) or re.search('\.rpm(save|new)$', path) |
1146 | 2500 | or re.search('\.dpkg-(old|new)$', path) or re.search('\.swp$', path) | 2505 | or re.search('\.dpkg-(old|new)$', path) or re.search('\.swp$', path) |
1147 | 2501 | or path[-1] == '~' or path == 'README'): | 2506 | or path[-1] == '~' or path == 'README'): |
1148 | 2502 | return True | 2507 | return True |
1149 | 2503 | 2508 | ||
1150 | 2504 | def is_skippable_dir(path): | 2509 | def is_skippable_dir(path): |
1151 | @@ -2517,7 +2522,7 @@ | |||
1152 | 2517 | def read_profiles(): | 2522 | def read_profiles(): |
1153 | 2518 | try: | 2523 | try: |
1154 | 2519 | os.listdir(profile_dir) | 2524 | os.listdir(profile_dir) |
1156 | 2520 | except : | 2525 | except: |
1157 | 2521 | fatal_error(_("Can't read AppArmor profiles in %s") % profile_dir) | 2526 | fatal_error(_("Can't read AppArmor profiles in %s") % profile_dir) |
1158 | 2522 | 2527 | ||
1159 | 2523 | for file in os.listdir(profile_dir): | 2528 | for file in os.listdir(profile_dir): |
1160 | @@ -2532,7 +2537,7 @@ | |||
1161 | 2532 | return None | 2537 | return None |
1162 | 2533 | try: | 2538 | try: |
1163 | 2534 | os.listdir(profile_dir) | 2539 | os.listdir(profile_dir) |
1165 | 2535 | except : | 2540 | except: |
1166 | 2536 | fatal_error(_("Can't read AppArmor profiles in %s") % extra_profile_dir) | 2541 | fatal_error(_("Can't read AppArmor profiles in %s") % extra_profile_dir) |
1167 | 2537 | 2542 | ||
1168 | 2538 | for file in os.listdir(profile_dir): | 2543 | for file in os.listdir(profile_dir): |
1169 | @@ -2548,7 +2553,7 @@ | |||
1170 | 2548 | with open_file_read(file) as f_in: | 2553 | with open_file_read(file) as f_in: |
1171 | 2549 | data = f_in.readlines() | 2554 | data = f_in.readlines() |
1172 | 2550 | except IOError: | 2555 | except IOError: |
1174 | 2551 | debug_logger.debug("read_profile: can't read %s - skipping" %file) | 2556 | debug_logger.debug("read_profile: can't read %s - skipping" % file) |
1175 | 2552 | return None | 2557 | return None |
1176 | 2553 | 2558 | ||
1177 | 2554 | profile_data = parse_profile_data(data, file, 0) | 2559 | profile_data = parse_profile_data(data, file, 0) |
1178 | @@ -2609,13 +2614,13 @@ | |||
1179 | 2609 | if profile: | 2614 | if profile: |
1180 | 2610 | #print(profile, hat) | 2615 | #print(profile, hat) |
1181 | 2611 | if profile != hat or not matches[3]: | 2616 | if profile != hat or not matches[3]: |
1183 | 2612 | raise AppArmorException(_('%s profile in %s contains syntax errors in line: %s.') % (profile, file, lineno+1)) | 2617 | raise AppArmorException(_('%s profile in %s contains syntax errors in line: %s.') % (profile, file, lineno + 1)) |
1184 | 2613 | # Keep track of the start of a profile | 2618 | # Keep track of the start of a profile |
1185 | 2614 | if profile and profile == hat and matches[3]: | 2619 | if profile and profile == hat and matches[3]: |
1186 | 2615 | # local profile | 2620 | # local profile |
1187 | 2616 | hat = matches[3] | 2621 | hat = matches[3] |
1188 | 2617 | in_contained_hat = True | 2622 | in_contained_hat = True |
1190 | 2618 | profile_data[profile][hat]['profile'] = True | 2623 | profile_data[profile][hat]['profile'] = True |
1191 | 2619 | else: | 2624 | else: |
1192 | 2620 | if matches[1]: | 2625 | if matches[1]: |
1193 | 2621 | profile = matches[1] | 2626 | profile = matches[1] |
1194 | @@ -2661,7 +2666,7 @@ | |||
1195 | 2661 | elif RE_PROFILE_END.search(line): | 2666 | elif RE_PROFILE_END.search(line): |
1196 | 2662 | # If profile ends and we're not in one | 2667 | # If profile ends and we're not in one |
1197 | 2663 | if not profile: | 2668 | if not profile: |
1199 | 2664 | raise AppArmorException(_('Syntax Error: Unexpected End of Profile reached in file: %s line: %s') % (file, lineno+1)) | 2669 | raise AppArmorException(_('Syntax Error: Unexpected End of Profile reached in file: %s line: %s') % (file, lineno + 1)) |
1200 | 2665 | 2670 | ||
1201 | 2666 | if in_contained_hat: | 2671 | if in_contained_hat: |
1202 | 2667 | hat = profile | 2672 | hat = profile |
1203 | @@ -2676,7 +2681,7 @@ | |||
1204 | 2676 | matches = RE_PROFILE_CAP.search(line).groups() | 2681 | matches = RE_PROFILE_CAP.search(line).groups() |
1205 | 2677 | 2682 | ||
1206 | 2678 | if not profile: | 2683 | if not profile: |
1208 | 2679 | raise AppArmorException(_('Syntax Error: Unexpected capability entry found in file: %s line: %s') % (file, lineno+1)) | 2684 | raise AppArmorException(_('Syntax Error: Unexpected capability entry found in file: %s line: %s') % (file, lineno + 1)) |
1209 | 2680 | 2685 | ||
1210 | 2681 | audit = False | 2686 | audit = False |
1211 | 2682 | if matches[0]: | 2687 | if matches[0]: |
1212 | @@ -2695,7 +2700,7 @@ | |||
1213 | 2695 | matches = RE_PROFILE_LINK.search(line).groups() | 2700 | matches = RE_PROFILE_LINK.search(line).groups() |
1214 | 2696 | 2701 | ||
1215 | 2697 | if not profile: | 2702 | if not profile: |
1217 | 2698 | raise AppArmorException(_('Syntax Error: Unexpected link entry found in file: %s line: %s') % (file, lineno+1)) | 2703 | raise AppArmorException(_('Syntax Error: Unexpected link entry found in file: %s line: %s') % (file, lineno + 1)) |
1218 | 2699 | 2704 | ||
1219 | 2700 | audit = False | 2705 | audit = False |
1220 | 2701 | if matches[0]: | 2706 | if matches[0]: |
1221 | @@ -2709,13 +2714,13 @@ | |||
1222 | 2709 | link = strip_quotes(matches[6]) | 2714 | link = strip_quotes(matches[6]) |
1223 | 2710 | value = strip_quotes(matches[7]) | 2715 | value = strip_quotes(matches[7]) |
1224 | 2711 | profile_data[profile][hat][allow]['link'][link]['to'] = value | 2716 | profile_data[profile][hat][allow]['link'][link]['to'] = value |
1226 | 2712 | profile_data[profile][hat][allow]['link'][link]['mode'] = profile_data[profile][hat][allow]['link'][link].get('mode', set()) | AA_MAY_LINK | 2717 | profile_data[profile][hat][allow]['link'][link]['mode'] = profile_data[profile][hat][allow]['link'][link].get('mode', set()) | apparmor.aamode.AA_MAY_LINK |
1227 | 2713 | 2718 | ||
1228 | 2714 | if subset: | 2719 | if subset: |
1230 | 2715 | profile_data[profile][hat][allow]['link'][link]['mode'] |= AA_LINK_SUBSET | 2720 | profile_data[profile][hat][allow]['link'][link]['mode'] |= apparmor.aamode.AA_LINK_SUBSET |
1231 | 2716 | 2721 | ||
1232 | 2717 | if audit: | 2722 | if audit: |
1234 | 2718 | profile_data[profile][hat][allow]['link'][link]['audit'] = profile_data[profile][hat][allow]['link'][link].get('audit', set()) | AA_LINK_SUBSET | 2723 | profile_data[profile][hat][allow]['link'][link]['audit'] = profile_data[profile][hat][allow]['link'][link].get('audit', set()) | apparmor.aamode.AA_LINK_SUBSET |
1235 | 2719 | else: | 2724 | else: |
1236 | 2720 | profile_data[profile][hat][allow]['link'][link]['audit'] = set() | 2725 | profile_data[profile][hat][allow]['link'][link]['audit'] = set() |
1237 | 2721 | 2726 | ||
1238 | @@ -2723,7 +2728,7 @@ | |||
1239 | 2723 | matches = RE_PROFILE_CHANGE_PROFILE.search(line).groups() | 2728 | matches = RE_PROFILE_CHANGE_PROFILE.search(line).groups() |
1240 | 2724 | 2729 | ||
1241 | 2725 | if not profile: | 2730 | if not profile: |
1243 | 2726 | raise AppArmorException(_('Syntax Error: Unexpected change profile entry found in file: %s line: %s') % (file, lineno+1)) | 2731 | raise AppArmorException(_('Syntax Error: Unexpected change profile entry found in file: %s line: %s') % (file, lineno + 1)) |
1244 | 2727 | 2732 | ||
1245 | 2728 | cp = strip_quotes(matches[0]) | 2733 | cp = strip_quotes(matches[0]) |
1246 | 2729 | profile_data[profile][hat]['changes_profile'][cp] = True | 2734 | profile_data[profile][hat]['changes_profile'][cp] = True |
1247 | @@ -2745,7 +2750,7 @@ | |||
1248 | 2745 | matches = RE_PROFILE_RLIMIT.search(line).groups() | 2750 | matches = RE_PROFILE_RLIMIT.search(line).groups() |
1249 | 2746 | 2751 | ||
1250 | 2747 | if not profile: | 2752 | if not profile: |
1252 | 2748 | raise AppArmorException(_('Syntax Error: Unexpected rlimit entry found in file: %s line: %s') % (file, lineno+1)) | 2753 | raise AppArmorException(_('Syntax Error: Unexpected rlimit entry found in file: %s line: %s') % (file, lineno + 1)) |
1253 | 2749 | 2754 | ||
1254 | 2750 | from_name = matches[0] | 2755 | from_name = matches[0] |
1255 | 2751 | to_name = matches[2] | 2756 | to_name = matches[2] |
1256 | @@ -2756,7 +2761,7 @@ | |||
1257 | 2756 | matches = RE_PROFILE_BOOLEAN.search(line) | 2761 | matches = RE_PROFILE_BOOLEAN.search(line) |
1258 | 2757 | 2762 | ||
1259 | 2758 | if not profile: | 2763 | if not profile: |
1261 | 2759 | raise AppArmorException(_('Syntax Error: Unexpected boolean definition found in file: %s line: %s') % (file, lineno+1)) | 2764 | raise AppArmorException(_('Syntax Error: Unexpected boolean definition found in file: %s line: %s') % (file, lineno + 1)) |
1262 | 2760 | 2765 | ||
1263 | 2761 | bool_var = matches[0] | 2766 | bool_var = matches[0] |
1264 | 2762 | value = matches[1] | 2767 | value = matches[1] |
1265 | @@ -2796,7 +2801,7 @@ | |||
1266 | 2796 | matches = RE_PROFILE_PATH_ENTRY.search(line).groups() | 2801 | matches = RE_PROFILE_PATH_ENTRY.search(line).groups() |
1267 | 2797 | 2802 | ||
1268 | 2798 | if not profile: | 2803 | if not profile: |
1270 | 2799 | raise AppArmorException(_('Syntax Error: Unexpected path entry found in file: %s line: %s') % (file, lineno+1)) | 2804 | raise AppArmorException(_('Syntax Error: Unexpected path entry found in file: %s line: %s') % (file, lineno + 1)) |
1271 | 2800 | 2805 | ||
1272 | 2801 | audit = False | 2806 | audit = False |
1273 | 2802 | if matches[0]: | 2807 | if matches[0]: |
1274 | @@ -2820,10 +2825,10 @@ | |||
1275 | 2820 | try: | 2825 | try: |
1276 | 2821 | re.compile(p_re) | 2826 | re.compile(p_re) |
1277 | 2822 | except: | 2827 | except: |
1279 | 2823 | raise AppArmorException(_('Syntax Error: Invalid Regex %s in file: %s line: %s') % (path, file, lineno+1)) | 2828 | raise AppArmorException(_('Syntax Error: Invalid Regex %s in file: %s line: %s') % (path, file, lineno + 1)) |
1280 | 2824 | 2829 | ||
1281 | 2825 | if not validate_profile_mode(mode, allow, nt_name): | 2830 | if not validate_profile_mode(mode, allow, nt_name): |
1283 | 2826 | raise AppArmorException(_('Invalid mode %s in file: %s line: %s') % (mode, file, lineno+1)) | 2831 | raise AppArmorException(_('Invalid mode %s in file: %s line: %s') % (mode, file, lineno + 1)) |
1284 | 2827 | 2832 | ||
1285 | 2828 | tmpmode = set() | 2833 | tmpmode = set() |
1286 | 2829 | if user: | 2834 | if user: |
1287 | @@ -2847,7 +2852,6 @@ | |||
1288 | 2847 | if include_name.startswith('local/'): | 2852 | if include_name.startswith('local/'): |
1289 | 2848 | profile_data[profile][hat]['localinclude'][include_name] = True | 2853 | profile_data[profile][hat]['localinclude'][include_name] = True |
1290 | 2849 | 2854 | ||
1291 | 2850 | |||
1292 | 2851 | if profile: | 2855 | if profile: |
1293 | 2852 | profile_data[profile][hat]['include'][include_name] = True | 2856 | profile_data[profile][hat]['include'][include_name] = True |
1294 | 2853 | else: | 2857 | else: |
1295 | @@ -2862,7 +2866,7 @@ | |||
1296 | 2862 | continue | 2866 | continue |
1297 | 2863 | if os.path.isfile(profile_dir + '/' + include_name + '/' + path): | 2867 | if os.path.isfile(profile_dir + '/' + include_name + '/' + path): |
1298 | 2864 | file_name = include_name + '/' + path | 2868 | file_name = include_name + '/' + path |
1300 | 2865 | file_name = file_name.replace(profile_dir+'/', '') | 2869 | file_name = file_name.replace(profile_dir + '/', '') |
1301 | 2866 | if not include.get(file_name, False): | 2870 | if not include.get(file_name, False): |
1302 | 2867 | load_include(file_name) | 2871 | load_include(file_name) |
1303 | 2868 | else: | 2872 | else: |
1304 | @@ -2873,7 +2877,7 @@ | |||
1305 | 2873 | matches = RE_PROFILE_NETWORK.search(line).groups() | 2877 | matches = RE_PROFILE_NETWORK.search(line).groups() |
1306 | 2874 | 2878 | ||
1307 | 2875 | if not profile: | 2879 | if not profile: |
1309 | 2876 | raise AppArmorException(_('Syntax Error: Unexpected network entry found in file: %s line: %s') % (file, lineno+1)) | 2880 | raise AppArmorException(_('Syntax Error: Unexpected network entry found in file: %s line: %s') % (file, lineno + 1)) |
1310 | 2877 | 2881 | ||
1311 | 2878 | audit = False | 2882 | audit = False |
1312 | 2879 | if matches[0]: | 2883 | if matches[0]: |
1313 | @@ -2889,7 +2893,7 @@ | |||
1314 | 2889 | ##Simply ignore any type subrules if family has True (seperately for allow and deny) | 2893 | ##Simply ignore any type subrules if family has True (seperately for allow and deny) |
1315 | 2890 | ##This will lead to those type specific rules being lost when written | 2894 | ##This will lead to those type specific rules being lost when written |
1316 | 2891 | #if type(profile_data[profile][hat][allow]['netdomain']['rule'].get(fam, False)) == dict: | 2895 | #if type(profile_data[profile][hat][allow]['netdomain']['rule'].get(fam, False)) == dict: |
1318 | 2892 | profile_data[profile][hat][allow]['netdomain']['rule'][fam][typ] = 1 | 2896 | profile_data[profile][hat][allow]['netdomain']['rule'][fam][typ] = 1 |
1319 | 2893 | profile_data[profile][hat][allow]['netdomain']['audit'][fam][typ] = audit | 2897 | profile_data[profile][hat][allow]['netdomain']['audit'][fam][typ] = audit |
1320 | 2894 | elif RE_NETWORK_FAMILY.search(network): | 2898 | elif RE_NETWORK_FAMILY.search(network): |
1321 | 2895 | fam = RE_NETWORK_FAMILY.search(network).groups()[0] | 2899 | fam = RE_NETWORK_FAMILY.search(network).groups()[0] |
1322 | @@ -2897,13 +2901,13 @@ | |||
1323 | 2897 | profile_data[profile][hat][allow]['netdomain']['audit'][fam] = audit | 2901 | profile_data[profile][hat][allow]['netdomain']['audit'][fam] = audit |
1324 | 2898 | else: | 2902 | else: |
1325 | 2899 | profile_data[profile][hat][allow]['netdomain']['rule']['all'] = True | 2903 | profile_data[profile][hat][allow]['netdomain']['rule']['all'] = True |
1327 | 2900 | profile_data[profile][hat][allow]['netdomain']['audit']['all'] = audit # True | 2904 | profile_data[profile][hat][allow]['netdomain']['audit']['all'] = audit # True |
1328 | 2901 | 2905 | ||
1329 | 2902 | elif RE_PROFILE_CHANGE_HAT.search(line): | 2906 | elif RE_PROFILE_CHANGE_HAT.search(line): |
1330 | 2903 | matches = RE_PROFILE_CHANGE_HAT.search(line).groups() | 2907 | matches = RE_PROFILE_CHANGE_HAT.search(line).groups() |
1331 | 2904 | 2908 | ||
1332 | 2905 | if not profile: | 2909 | if not profile: |
1334 | 2906 | raise AppArmorException(_('Syntax Error: Unexpected change hat declaration found in file: %s line: %s') % (file, lineno+1)) | 2910 | raise AppArmorException(_('Syntax Error: Unexpected change hat declaration found in file: %s line: %s') % (file, lineno + 1)) |
1335 | 2907 | 2911 | ||
1336 | 2908 | hat = matches[0] | 2912 | hat = matches[0] |
1337 | 2909 | hat = strip_quotes(hat) | 2913 | hat = strip_quotes(hat) |
1338 | @@ -2915,7 +2919,7 @@ | |||
1339 | 2915 | # An embedded hat syntax definition starts | 2919 | # An embedded hat syntax definition starts |
1340 | 2916 | matches = RE_PROFILE_HAT_DEF.search(line).groups() | 2920 | matches = RE_PROFILE_HAT_DEF.search(line).groups() |
1341 | 2917 | if not profile: | 2921 | if not profile: |
1343 | 2918 | raise AppArmorException(_('Syntax Error: Unexpected hat definition found in file: %s line: %s') % (file, lineno+1)) | 2922 | raise AppArmorException(_('Syntax Error: Unexpected hat definition found in file: %s line: %s') % (file, lineno + 1)) |
1344 | 2919 | 2923 | ||
1345 | 2920 | in_contained_hat = True | 2924 | in_contained_hat = True |
1346 | 2921 | hat = matches[0] | 2925 | hat = matches[0] |
1347 | @@ -2931,7 +2935,7 @@ | |||
1348 | 2931 | profile_data[profile][hat]['initial_comment'] = initial_comment | 2935 | profile_data[profile][hat]['initial_comment'] = initial_comment |
1349 | 2932 | initial_comment = '' | 2936 | initial_comment = '' |
1350 | 2933 | if filelist[file]['profiles'][profile].get(hat, False): | 2937 | if filelist[file]['profiles'][profile].get(hat, False): |
1352 | 2934 | raise AppArmorException(_('Error: Multiple definitions for hat %s in profile %s.') %(hat, profile)) | 2938 | raise AppArmorException(_('Error: Multiple definitions for hat %s in profile %s.') % (hat, profile)) |
1353 | 2935 | filelist[file]['profiles'][profile][hat] = True | 2939 | filelist[file]['profiles'][profile][hat] = True |
1354 | 2936 | 2940 | ||
1355 | 2937 | elif line[0] == '#': | 2941 | elif line[0] == '#': |
1356 | @@ -2951,7 +2955,7 @@ | |||
1357 | 2951 | initial_comment = ' '.join(line) + '\n' | 2955 | initial_comment = ' '.join(line) + '\n' |
1358 | 2952 | 2956 | ||
1359 | 2953 | else: | 2957 | else: |
1361 | 2954 | raise AppArmorException(_('Syntax Error: Unknown line found in file: %s line: %s') % (file, lineno+1)) | 2958 | raise AppArmorException(_('Syntax Error: Unknown line found in file: %s line: %s') % (file, lineno + 1)) |
1362 | 2955 | 2959 | ||
1363 | 2956 | # Below is not required I'd say | 2960 | # Below is not required I'd say |
1364 | 2957 | if not do_include: | 2961 | if not do_include: |
1365 | @@ -2995,18 +2999,18 @@ | |||
1366 | 2995 | var[list_var] = set(vlist) | 2999 | var[list_var] = set(vlist) |
1367 | 2996 | else: | 3000 | else: |
1368 | 2997 | #print('Ignored: New definition for variable for:',list_var,'=', value, 'operation was:',var_operation,'old value=', var[list_var]) | 3001 | #print('Ignored: New definition for variable for:',list_var,'=', value, 'operation was:',var_operation,'old value=', var[list_var]) |
1370 | 2998 | raise AppArmorException(_('An existing variable redefined: %s') %list_var) | 3002 | raise AppArmorException(_('An existing variable redefined: %s') % list_var) |
1371 | 2999 | elif var_operation == '+=': | 3003 | elif var_operation == '+=': |
1372 | 3000 | if var.get(list_var, False): | 3004 | if var.get(list_var, False): |
1373 | 3001 | var[list_var] = set(var[list_var] + vlist) | 3005 | var[list_var] = set(var[list_var] + vlist) |
1374 | 3002 | else: | 3006 | else: |
1376 | 3003 | raise AppArmorException(_('Values added to a non-existing variable: %s') %list_var) | 3007 | raise AppArmorException(_('Values added to a non-existing variable: %s') % list_var) |
1377 | 3004 | else: | 3008 | else: |
1379 | 3005 | raise AppArmorException(_('Unknown variable operation: %s') %var_operation) | 3009 | raise AppArmorException(_('Unknown variable operation: %s') % var_operation) |
1380 | 3006 | 3010 | ||
1381 | 3007 | 3011 | ||
1382 | 3008 | def strip_quotes(data): | 3012 | def strip_quotes(data): |
1384 | 3009 | if data[0]+data[-1] == '""': | 3013 | if data[0] + data[-1] == '""': |
1385 | 3010 | return data[1:-1] | 3014 | return data[1:-1] |
1386 | 3011 | else: | 3015 | else: |
1387 | 3012 | return data | 3016 | return data |
1388 | @@ -3029,7 +3033,7 @@ | |||
1389 | 3029 | data = [] | 3033 | data = [] |
1390 | 3030 | name = quote_if_needed(name) | 3034 | name = quote_if_needed(name) |
1391 | 3031 | 3035 | ||
1393 | 3032 | if (not embedded_hat and re.search('^[^/]|^"[^/]', name)) or (embedded_hat and re.search('^[^^]' ,name)): | 3036 | if (not embedded_hat and re.search('^[^/]|^"[^/]', name)) or (embedded_hat and re.search('^[^^]', name)): |
1394 | 3033 | name = 'profile %s' % name | 3037 | name = 'profile %s' % name |
1395 | 3034 | 3038 | ||
1396 | 3035 | if write_flags and prof_data['flags']: | 3039 | if write_flags and prof_data['flags']: |
1397 | @@ -3047,7 +3051,7 @@ | |||
1398 | 3047 | if ref.get(name, False): | 3051 | if ref.get(name, False): |
1399 | 3048 | for key in sorted(ref[name].keys()): | 3052 | for key in sorted(ref[name].keys()): |
1400 | 3049 | qkey = quote_if_needed(key) | 3053 | qkey = quote_if_needed(key) |
1402 | 3050 | data.append('%s%s%s%s%s' %(pre, allow, prefix, qkey, tail)) | 3054 | data.append('%s%s%s%s%s' % (pre, allow, prefix, qkey, tail)) |
1403 | 3051 | if ref[name].keys(): | 3055 | if ref[name].keys(): |
1404 | 3052 | data.append('') | 3056 | data.append('') |
1405 | 3053 | 3057 | ||
1406 | @@ -3077,8 +3081,8 @@ | |||
1407 | 3077 | 3081 | ||
1408 | 3078 | if ref.get(name, False): | 3082 | if ref.get(name, False): |
1409 | 3079 | for key in sorted(ref[name].keys()): | 3083 | for key in sorted(ref[name].keys()): |
1412 | 3080 | value = fn(ref[name][key])#eval('%s(%s)' % (fn, ref[name][key])) | 3084 | value = fn(ref[name][key]) # eval('%s(%s)' % (fn, ref[name][key])) |
1413 | 3081 | data.append('%s%s%s%s%s%s' %(pre, allow, prefix, key, sep, value)) | 3085 | data.append('%s%s%s%s%s%s' % (pre, allow, prefix, key, sep, value)) |
1414 | 3082 | if ref[name].keys(): | 3086 | if ref[name].keys(): |
1415 | 3083 | data.append('') | 3087 | data.append('') |
1416 | 3084 | 3088 | ||
1417 | @@ -3116,7 +3120,7 @@ | |||
1418 | 3116 | if prof_data[allow]['capability'][cap].get('audit', False): | 3120 | if prof_data[allow]['capability'][cap].get('audit', False): |
1419 | 3117 | audit = 'audit ' | 3121 | audit = 'audit ' |
1420 | 3118 | if prof_data[allow]['capability'][cap].get('set', False): | 3122 | if prof_data[allow]['capability'][cap].get('set', False): |
1422 | 3119 | data.append('%s%s%scapability %s,' %(pre, audit, allowstr, cap)) | 3123 | data.append('%s%s%scapability %s,' % (pre, audit, allowstr, cap)) |
1423 | 3120 | data.append('') | 3124 | data.append('') |
1424 | 3121 | 3125 | ||
1425 | 3122 | return data | 3126 | return data |
1426 | @@ -3136,10 +3140,10 @@ | |||
1427 | 3136 | if prof_data[allow]['netdomain'].get('rule', False) == 'all': | 3140 | if prof_data[allow]['netdomain'].get('rule', False) == 'all': |
1428 | 3137 | if prof_data[allow]['netdomain']['audit'].get('all', False): | 3141 | if prof_data[allow]['netdomain']['audit'].get('all', False): |
1429 | 3138 | audit = 'audit ' | 3142 | audit = 'audit ' |
1431 | 3139 | data.append('%s%snetwork,' %(pre, audit)) | 3143 | data.append('%s%snetwork,' % (pre, audit)) |
1432 | 3140 | else: | 3144 | else: |
1433 | 3141 | for fam in sorted(prof_data[allow]['netdomain']['rule'].keys()): | 3145 | for fam in sorted(prof_data[allow]['netdomain']['rule'].keys()): |
1435 | 3142 | if prof_data[allow]['netdomain']['rule'][fam] == True: | 3146 | if prof_data[allow]['netdomain']['rule'][fam] is True: |
1436 | 3143 | if prof_data[allow]['netdomain']['audit'][fam]: | 3147 | if prof_data[allow]['netdomain']['audit'][fam]: |
1437 | 3144 | audit = 'audit' | 3148 | audit = 'audit' |
1438 | 3145 | data.append('%s%s%snetwork %s' % (pre, audit, allowstr, fam)) | 3149 | data.append('%s%s%snetwork %s' % (pre, audit, allowstr, fam)) |
1439 | @@ -3147,7 +3151,7 @@ | |||
1440 | 3147 | for typ in sorted(prof_data[allow]['netdomain']['rule'][fam].keys()): | 3151 | for typ in sorted(prof_data[allow]['netdomain']['rule'][fam].keys()): |
1441 | 3148 | if prof_data[allow]['netdomain']['audit'][fam].get(typ, False): | 3152 | if prof_data[allow]['netdomain']['audit'][fam].get(typ, False): |
1442 | 3149 | audit = 'audit' | 3153 | audit = 'audit' |
1444 | 3150 | data.append('%s%s%snetwork %s %s,' % (pre, audit, allowstr,fam, typ)) | 3154 | data.append('%s%s%snetwork %s %s,' % (pre, audit, allowstr, fam, typ)) |
1445 | 3151 | if prof_data[allow].get('netdomain', False): | 3155 | if prof_data[allow].get('netdomain', False): |
1446 | 3152 | data.append('') | 3156 | data.append('') |
1447 | 3153 | 3157 | ||
1448 | @@ -3167,14 +3171,14 @@ | |||
1449 | 3167 | for path in sorted(prof_data[allow]['link'].keys()): | 3171 | for path in sorted(prof_data[allow]['link'].keys()): |
1450 | 3168 | to_name = prof_data[allow]['link'][path]['to'] | 3172 | to_name = prof_data[allow]['link'][path]['to'] |
1451 | 3169 | subset = '' | 3173 | subset = '' |
1453 | 3170 | if prof_data[allow]['link'][path]['mode'] & AA_LINK_SUBSET: | 3174 | if prof_data[allow]['link'][path]['mode'] & apparmor.aamode.AA_LINK_SUBSET: |
1454 | 3171 | subset = 'subset' | 3175 | subset = 'subset' |
1455 | 3172 | audit = '' | 3176 | audit = '' |
1456 | 3173 | if prof_data[allow]['link'][path].get('audit', False): | 3177 | if prof_data[allow]['link'][path].get('audit', False): |
1457 | 3174 | audit = 'audit ' | 3178 | audit = 'audit ' |
1458 | 3175 | path = quote_if_needed(path) | 3179 | path = quote_if_needed(path) |
1459 | 3176 | to_name = quote_if_needed(to_name) | 3180 | to_name = quote_if_needed(to_name) |
1461 | 3177 | data.append('%s%s%slink %s%s -> %s,' %(pre, audit, allowstr, subset, path, to_name)) | 3181 | data.append('%s%s%slink %s%s -> %s,' % (pre, audit, allowstr, subset, path, to_name)) |
1462 | 3178 | data.append('') | 3182 | data.append('') |
1463 | 3179 | 3183 | ||
1464 | 3180 | return data | 3184 | return data |
1465 | @@ -3226,13 +3230,13 @@ | |||
1466 | 3226 | if tmpmode & tmpaudit: | 3230 | if tmpmode & tmpaudit: |
1467 | 3227 | modestr = mode_to_str(tmpmode & tmpaudit) | 3231 | modestr = mode_to_str(tmpmode & tmpaudit) |
1468 | 3228 | path = quote_if_needed(path) | 3232 | path = quote_if_needed(path) |
1470 | 3229 | data.append('%saudit %s%s%s %s%s,' %(pre, allowstr, ownerstr, path, modestr, tail)) | 3233 | data.append('%saudit %s%s%s %s%s,' % (pre, allowstr, ownerstr, path, modestr, tail)) |
1471 | 3230 | tmpmode = tmpmode - tmpaudit | 3234 | tmpmode = tmpmode - tmpaudit |
1472 | 3231 | 3235 | ||
1473 | 3232 | if tmpmode: | 3236 | if tmpmode: |
1474 | 3233 | modestr = mode_to_str(tmpmode) | 3237 | modestr = mode_to_str(tmpmode) |
1475 | 3234 | path = quote_if_needed(path) | 3238 | path = quote_if_needed(path) |
1477 | 3235 | data.append('%s%s%s%s %s%s,' %(pre, allowstr, ownerstr, path, modestr, tail)) | 3239 | data.append('%s%s%s%s %s%s,' % (pre, allowstr, ownerstr, path, modestr, tail)) |
1478 | 3236 | 3240 | ||
1479 | 3237 | data.append('') | 3241 | data.append('') |
1480 | 3238 | return data | 3242 | return data |
1481 | @@ -3268,13 +3272,13 @@ | |||
1482 | 3268 | name = nhat | 3272 | name = nhat |
1483 | 3269 | inhat = True | 3273 | inhat = True |
1484 | 3270 | data += write_header(profile_data[name], depth, wname, False, write_flags) | 3274 | data += write_header(profile_data[name], depth, wname, False, write_flags) |
1486 | 3271 | data += write_rules(profile_data[name], depth+1) | 3275 | data += write_rules(profile_data[name], depth + 1) |
1487 | 3272 | 3276 | ||
1489 | 3273 | pre2 = ' ' * (depth+1) | 3277 | pre2 = ' ' * (depth + 1) |
1490 | 3274 | # External hat declarations | 3278 | # External hat declarations |
1491 | 3275 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): | 3279 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): |
1492 | 3276 | if profile_data[hat].get('declared', False): | 3280 | if profile_data[hat].get('declared', False): |
1494 | 3277 | data.append('%s^%s,' %(pre2, hat)) | 3281 | data.append('%s^%s,' % (pre2, hat)) |
1495 | 3278 | 3282 | ||
1496 | 3279 | if not inhat: | 3283 | if not inhat: |
1497 | 3280 | # Embedded hats | 3284 | # Embedded hats |
1498 | @@ -3282,21 +3286,21 @@ | |||
1499 | 3282 | if not profile_data[hat]['external'] and not profile_data[hat]['declared']: | 3286 | if not profile_data[hat]['external'] and not profile_data[hat]['declared']: |
1500 | 3283 | data.append('') | 3287 | data.append('') |
1501 | 3284 | if profile_data[hat]['profile']: | 3288 | if profile_data[hat]['profile']: |
1503 | 3285 | data += list(map(str, write_header(profile_data[hat], depth+1, hat, True, write_flags))) | 3289 | data += list(map(str, write_header(profile_data[hat], depth + 1, hat, True, write_flags))) |
1504 | 3286 | else: | 3290 | else: |
1512 | 3287 | data += list(map(str, write_header(profile_data[hat], depth+1, '^'+hat, True, write_flags))) | 3291 | data += list(map(str, write_header(profile_data[hat], depth + 1, '^' + hat, True, write_flags))) |
1513 | 3288 | 3292 | ||
1514 | 3289 | data += list(map(str, write_rules(profile_data[hat], depth+2))) | 3293 | data += list(map(str, write_rules(profile_data[hat], depth + 2))) |
1515 | 3290 | 3294 | ||
1516 | 3291 | data.append('%s}' %pre2) | 3295 | data.append('%s}' % pre2) |
1517 | 3292 | 3296 | ||
1518 | 3293 | data.append('%s}' %pre) | 3297 | data.append('%s}' % pre) |
1519 | 3294 | 3298 | ||
1520 | 3295 | # External hats | 3299 | # External hats |
1521 | 3296 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): | 3300 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): |
1522 | 3297 | if name == nhat and profile_data[hat].get('external', False): | 3301 | if name == nhat and profile_data[hat].get('external', False): |
1523 | 3298 | data.append('') | 3302 | data.append('') |
1525 | 3299 | data += list(map(lambda x: ' %s' %x, write_piece(profile_data, depth-1, name, nhat, write_flags))) | 3303 | data += list(map(lambda x: ' %s' % x, write_piece(profile_data, depth - 1, name, nhat, write_flags))) |
1526 | 3300 | data.append(' }') | 3304 | data.append(' }') |
1527 | 3301 | 3305 | ||
1528 | 3302 | return data | 3306 | return data |
1529 | @@ -3305,21 +3309,23 @@ | |||
1530 | 3305 | string = '' | 3309 | string = '' |
1531 | 3306 | include_metadata = False | 3310 | include_metadata = False |
1532 | 3307 | include_flags = True | 3311 | include_flags = True |
1534 | 3308 | data= [] | 3312 | data = [] |
1535 | 3309 | 3313 | ||
1537 | 3310 | if options:# and type(options) == dict: | 3314 | if options: # and type(options) == dict: |
1538 | 3311 | if options.get('METADATA', False): | 3315 | if options.get('METADATA', False): |
1539 | 3312 | include_metadata = True | 3316 | include_metadata = True |
1540 | 3313 | if options.get('NO_FLAGS', False): | 3317 | if options.get('NO_FLAGS', False): |
1541 | 3314 | include_flags = False | 3318 | include_flags = False |
1542 | 3315 | 3319 | ||
1543 | 3316 | if include_metadata: | 3320 | if include_metadata: |
1545 | 3317 | string = '# Last Modified: %s\n' %time.asctime() | 3321 | string = '# Last Modified: %s\n' % time.asctime() |
1546 | 3318 | 3322 | ||
1549 | 3319 | if (profile_data[name].get('repo', False) and profile_data[name]['repo']['url'] | 3323 | if (profile_data[name].get('repo', False) and |
1550 | 3320 | and profile_data[name]['repo']['user'] and profile_data[name]['repo']['id']): | 3324 | profile_data[name]['repo']['url'] and |
1551 | 3325 | profile_data[name]['repo']['user'] and | ||
1552 | 3326 | profile_data[name]['repo']['id']): | ||
1553 | 3321 | repo = profile_data[name]['repo'] | 3327 | repo = profile_data[name]['repo'] |
1555 | 3322 | string += '# REPOSITORY: %s %s %s\n' %(repo['url'], repo['user'], repo['id']) | 3328 | string += '# REPOSITORY: %s %s %s\n' % (repo['url'], repo['user'], repo['id']) |
1556 | 3323 | elif profile_data[name]['repo']['neversubmit']: | 3329 | elif profile_data[name]['repo']['neversubmit']: |
1557 | 3324 | string += '# REPOSITORY: NEVERSUBMIT\n' | 3330 | string += '# REPOSITORY: NEVERSUBMIT\n' |
1558 | 3325 | 3331 | ||
1559 | @@ -3351,7 +3357,7 @@ | |||
1560 | 3351 | 3357 | ||
1561 | 3352 | string += '\n'.join(data) | 3358 | string += '\n'.join(data) |
1562 | 3353 | 3359 | ||
1564 | 3354 | return string+'\n' | 3360 | return string + '\n' |
1565 | 3355 | 3361 | ||
1566 | 3356 | def serialize_profile_from_old_profile(profile_data, name, options): | 3362 | def serialize_profile_from_old_profile(profile_data, name, options): |
1567 | 3357 | data = [] | 3363 | data = [] |
1568 | @@ -3363,28 +3369,29 @@ | |||
1569 | 3363 | write_filelist = deepcopy(filelist[prof_filename]) | 3369 | write_filelist = deepcopy(filelist[prof_filename]) |
1570 | 3364 | write_prof_data = deepcopy(profile_data) | 3370 | write_prof_data = deepcopy(profile_data) |
1571 | 3365 | 3371 | ||
1573 | 3366 | if options:# and type(options) == dict: | 3372 | if options: # and type(options) == dict: |
1574 | 3367 | if options.get('METADATA', False): | 3373 | if options.get('METADATA', False): |
1575 | 3368 | include_metadata = True | 3374 | include_metadata = True |
1576 | 3369 | if options.get('NO_FLAGS', False): | 3375 | if options.get('NO_FLAGS', False): |
1577 | 3370 | include_flags = False | 3376 | include_flags = False |
1578 | 3371 | 3377 | ||
1579 | 3372 | if include_metadata: | 3378 | if include_metadata: |
1581 | 3373 | string = '# Last Modified: %s\n' %time.asctime() | 3379 | string = '# Last Modified: %s\n' % time.asctime() |
1582 | 3374 | 3380 | ||
1585 | 3375 | if (profile_data[name].get('repo', False) and profile_data[name]['repo']['url'] | 3381 | if (profile_data[name].get('repo', False) and |
1586 | 3376 | and profile_data[name]['repo']['user'] and profile_data[name]['repo']['id']): | 3382 | profile_data[name]['repo']['url'] and |
1587 | 3383 | profile_data[name]['repo']['user'] and | ||
1588 | 3384 | profile_data[name]['repo']['id']): | ||
1589 | 3377 | repo = profile_data[name]['repo'] | 3385 | repo = profile_data[name]['repo'] |
1591 | 3378 | string += '# REPOSITORY: %s %s %s\n' %(repo['url'], repo['user'], repo['id']) | 3386 | string += '# REPOSITORY: %s %s %s\n' % (repo['url'], repo['user'], repo['id']) |
1592 | 3379 | elif profile_data[name]['repo']['neversubmit']: | 3387 | elif profile_data[name]['repo']['neversubmit']: |
1593 | 3380 | string += '# REPOSITORY: NEVERSUBMIT\n' | 3388 | string += '# REPOSITORY: NEVERSUBMIT\n' |
1594 | 3381 | 3389 | ||
1595 | 3382 | |||
1596 | 3383 | if not os.path.isfile(prof_filename): | 3390 | if not os.path.isfile(prof_filename): |
1597 | 3384 | raise AppArmorException(_("Can't find existing profile to modify")) | 3391 | raise AppArmorException(_("Can't find existing profile to modify")) |
1599 | 3385 | 3392 | ||
1600 | 3386 | profiles_list = filelist[prof_filename].keys() | 3393 | profiles_list = filelist[prof_filename].keys() |
1602 | 3387 | 3394 | ||
1603 | 3388 | with open_file_read(prof_filename) as f_in: | 3395 | with open_file_read(prof_filename) as f_in: |
1604 | 3389 | profile = None | 3396 | profile = None |
1605 | 3390 | hat = None | 3397 | hat = None |
1606 | @@ -3399,8 +3406,7 @@ | |||
1607 | 3399 | 'change_profile': write_change_profile, | 3406 | 'change_profile': write_change_profile, |
1608 | 3400 | } | 3407 | } |
1609 | 3401 | prof_correct = True | 3408 | prof_correct = True |
1612 | 3402 | segments = { | 3409 | segments = {'alias': False, |
1611 | 3403 | 'alias': False, | ||
1613 | 3404 | 'lvar': False, | 3410 | 'lvar': False, |
1614 | 3405 | 'include': False, | 3411 | 'include': False, |
1615 | 3406 | 'rlimit': False, | 3412 | 'rlimit': False, |
1616 | @@ -3410,7 +3416,7 @@ | |||
1617 | 3410 | 'path': False, | 3416 | 'path': False, |
1618 | 3411 | 'change_profile': False, | 3417 | 'change_profile': False, |
1619 | 3412 | 'include_local_started': False, | 3418 | 'include_local_started': False, |
1621 | 3413 | } | 3419 | } |
1622 | 3414 | #data.append('reading prof') | 3420 | #data.append('reading prof') |
1623 | 3415 | for line in f_in: | 3421 | for line in f_in: |
1624 | 3416 | correct = True | 3422 | correct = True |
1625 | @@ -3446,7 +3452,7 @@ | |||
1626 | 3446 | if not write_prof_data[hat]['name'] == profile: | 3452 | if not write_prof_data[hat]['name'] == profile: |
1627 | 3447 | correct = False | 3453 | correct = False |
1628 | 3448 | 3454 | ||
1630 | 3449 | if not write_filelist['profiles'][profile][hat] == True: | 3455 | if not write_filelist['profiles'][profile][hat] is True: |
1631 | 3450 | correct = False | 3456 | correct = False |
1632 | 3451 | 3457 | ||
1633 | 3452 | if not write_prof_data[hat]['flags'] == flags: | 3458 | if not write_prof_data[hat]['flags'] == flags: |
1634 | @@ -3462,7 +3468,7 @@ | |||
1635 | 3462 | else: | 3468 | else: |
1636 | 3463 | if write_prof_data[hat]['name'] == profile: | 3469 | if write_prof_data[hat]['name'] == profile: |
1637 | 3464 | depth = len(line) - len(line.lstrip()) | 3470 | depth = len(line) - len(line.lstrip()) |
1639 | 3465 | data += write_header(write_prof_data[name], int(depth/2), name, False, include_flags) | 3471 | data += write_header(write_prof_data[name], int(depth / 2), name, False, include_flags) |
1640 | 3466 | 3472 | ||
1641 | 3467 | elif RE_PROFILE_END.search(line): | 3473 | elif RE_PROFILE_END.search(line): |
1642 | 3468 | # DUMP REMAINDER OF PROFILE | 3474 | # DUMP REMAINDER OF PROFILE |
1643 | @@ -3471,11 +3477,12 @@ | |||
1644 | 3471 | if True in segments.values(): | 3477 | if True in segments.values(): |
1645 | 3472 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3478 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1646 | 3473 | 3479 | ||
1648 | 3474 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3480 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1649 | 3475 | segments[segs] = False | 3481 | segments[segs] = False |
1653 | 3476 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3482 | if write_prof_data[name]['allow'].get(segs, False): |
1654 | 3477 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3483 | write_prof_data[name]['allow'].pop(segs) |
1655 | 3478 | 3484 | if write_prof_data[name]['deny'].get(segs, False): | |
1656 | 3485 | write_prof_data[name]['deny'].pop(segs) | ||
1657 | 3479 | 3486 | ||
1658 | 3480 | data += write_alias(write_prof_data[name], depth) | 3487 | data += write_alias(write_prof_data[name], depth) |
1659 | 3481 | data += write_list_vars(write_prof_data[name], depth) | 3488 | data += write_list_vars(write_prof_data[name], depth) |
1660 | @@ -3494,25 +3501,25 @@ | |||
1661 | 3494 | 3501 | ||
1662 | 3495 | if not in_contained_hat: | 3502 | if not in_contained_hat: |
1663 | 3496 | # Embedded hats | 3503 | # Embedded hats |
1666 | 3497 | depth = int((len(line) - len(line.lstrip()))/2) | 3504 | depth = int((len(line) - len(line.lstrip())) / 2) |
1667 | 3498 | pre2 = ' ' * (depth+1) | 3505 | pre2 = ' ' * (depth + 1) |
1668 | 3499 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): | 3506 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): |
1669 | 3500 | if not profile_data[hat]['external'] and not profile_data[hat]['declared']: | 3507 | if not profile_data[hat]['external'] and not profile_data[hat]['declared']: |
1670 | 3501 | data.append('') | 3508 | data.append('') |
1671 | 3502 | if profile_data[hat]['profile']: | 3509 | if profile_data[hat]['profile']: |
1673 | 3503 | data += list(map(str, write_header(profile_data[hat], depth+1, hat, True, include_flags))) | 3510 | data += list(map(str, write_header(profile_data[hat], depth + 1, hat, True, include_flags))) |
1674 | 3504 | else: | 3511 | else: |
1680 | 3505 | data += list(map(str, write_header(profile_data[hat], depth+1, '^'+hat, True, include_flags))) | 3512 | data += list(map(str, write_header(profile_data[hat], depth + 1, '^' + hat, True, include_flags))) |
1681 | 3506 | 3513 | ||
1682 | 3507 | data += list(map(str, write_rules(profile_data[hat], depth+2))) | 3514 | data += list(map(str, write_rules(profile_data[hat], depth + 2))) |
1683 | 3508 | 3515 | ||
1684 | 3509 | data.append('%s}' %pre2) | 3516 | data.append('%s}' % pre2) |
1685 | 3510 | 3517 | ||
1686 | 3511 | # External hats | 3518 | # External hats |
1687 | 3512 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): | 3519 | for hat in list(filter(lambda x: x != name, sorted(profile_data.keys()))): |
1688 | 3513 | if profile_data[hat].get('external', False): | 3520 | if profile_data[hat].get('external', False): |
1689 | 3514 | data.append('') | 3521 | data.append('') |
1691 | 3515 | data += list(map(lambda x: ' %s' %x, write_piece(profile_data, depth-1, name, name, include_flags))) | 3522 | data += list(map(lambda x: ' %s' % x, write_piece(profile_data, depth - 1, name, name, include_flags))) |
1692 | 3516 | data.append(' }') | 3523 | data.append(' }') |
1693 | 3517 | 3524 | ||
1694 | 3518 | if in_contained_hat: | 3525 | if in_contained_hat: |
1695 | @@ -3522,7 +3529,6 @@ | |||
1696 | 3522 | else: | 3529 | else: |
1697 | 3523 | profile = None | 3530 | profile = None |
1698 | 3524 | 3531 | ||
1699 | 3525 | |||
1700 | 3526 | elif RE_PROFILE_CAP.search(line): | 3532 | elif RE_PROFILE_CAP.search(line): |
1701 | 3527 | matches = RE_PROFILE_CAP.search(line).groups() | 3533 | matches = RE_PROFILE_CAP.search(line).groups() |
1702 | 3528 | audit = False | 3534 | audit = False |
1703 | @@ -3544,10 +3550,12 @@ | |||
1704 | 3544 | if not segments['capability'] and True in segments.values(): | 3550 | if not segments['capability'] and True in segments.values(): |
1705 | 3545 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3551 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1706 | 3546 | depth = len(line) - len(line.lstrip()) | 3552 | depth = len(line) - len(line.lstrip()) |
1708 | 3547 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3553 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1709 | 3548 | segments[segs] = False | 3554 | segments[segs] = False |
1712 | 3549 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3555 | if write_prof_data[name]['allow'].get(segs, False): |
1713 | 3550 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3556 | write_prof_data[name]['allow'].pop(segs) |
1714 | 3557 | if write_prof_data[name]['deny'].get(segs, False): | ||
1715 | 3558 | write_prof_data[name]['deny'].pop(segs) | ||
1716 | 3551 | segments['capability'] = True | 3559 | segments['capability'] = True |
1717 | 3552 | write_prof_data[hat][allow]['capability'].pop(capability) | 3560 | write_prof_data[hat][allow]['capability'].pop(capability) |
1718 | 3553 | data.append(line) | 3561 | data.append(line) |
1719 | @@ -3572,21 +3580,23 @@ | |||
1720 | 3572 | value = strip_quotes(matches[7]) | 3580 | value = strip_quotes(matches[7]) |
1721 | 3573 | if not write_prof_data[hat][allow]['link'][link]['to'] == value: | 3581 | if not write_prof_data[hat][allow]['link'][link]['to'] == value: |
1722 | 3574 | correct = False | 3582 | correct = False |
1728 | 3575 | if not write_prof_data[hat][allow]['link'][link]['mode'] & AA_MAY_LINK: | 3583 | if not write_prof_data[hat][allow]['link'][link]['mode'] & apparmor.aamode.AA_MAY_LINK: |
1729 | 3576 | correct = False | 3584 | correct = False |
1730 | 3577 | if subset and not write_prof_data[hat][allow]['link'][link]['mode'] & AA_LINK_SUBSET: | 3585 | if subset and not write_prof_data[hat][allow]['link'][link]['mode'] & apparmor.aamode.AA_LINK_SUBSET: |
1731 | 3578 | correct = False | 3586 | correct = False |
1732 | 3579 | if audit and not write_prof_data[hat][allow]['link'][link]['audit'] & AA_LINK_SUBSET: | 3587 | if audit and not write_prof_data[hat][allow]['link'][link]['audit'] & apparmor.aamode.AA_LINK_SUBSET: |
1733 | 3580 | correct = False | 3588 | correct = False |
1734 | 3581 | 3589 | ||
1735 | 3582 | if correct: | 3590 | if correct: |
1736 | 3583 | if not segments['link'] and True in segments.values(): | 3591 | if not segments['link'] and True in segments.values(): |
1737 | 3584 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3592 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1738 | 3585 | depth = len(line) - len(line.lstrip()) | 3593 | depth = len(line) - len(line.lstrip()) |
1740 | 3586 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3594 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1741 | 3587 | segments[segs] = False | 3595 | segments[segs] = False |
1744 | 3588 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3596 | if write_prof_data[name]['allow'].get(segs, False): |
1745 | 3589 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3597 | write_prof_data[name]['allow'].pop(segs) |
1746 | 3598 | if write_prof_data[name]['deny'].get(segs, False): | ||
1747 | 3599 | write_prof_data[name]['deny'].pop(segs) | ||
1748 | 3590 | segments['link'] = True | 3600 | segments['link'] = True |
1749 | 3591 | write_prof_data[hat][allow]['link'].pop(link) | 3601 | write_prof_data[hat][allow]['link'].pop(link) |
1750 | 3592 | data.append(line) | 3602 | data.append(line) |
1751 | @@ -3598,17 +3608,19 @@ | |||
1752 | 3598 | matches = RE_PROFILE_CHANGE_PROFILE.search(line).groups() | 3608 | matches = RE_PROFILE_CHANGE_PROFILE.search(line).groups() |
1753 | 3599 | cp = strip_quotes(matches[0]) | 3609 | cp = strip_quotes(matches[0]) |
1754 | 3600 | 3610 | ||
1756 | 3601 | if not write_prof_data[hat]['changes_profile'][cp] == True: | 3611 | if not write_prof_data[hat]['changes_profile'][cp] is True: |
1757 | 3602 | correct = False | 3612 | correct = False |
1758 | 3603 | 3613 | ||
1759 | 3604 | if correct: | 3614 | if correct: |
1760 | 3605 | if not segments['change_profile'] and True in segments.values(): | 3615 | if not segments['change_profile'] and True in segments.values(): |
1761 | 3606 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3616 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1762 | 3607 | depth = len(line) - len(line.lstrip()) | 3617 | depth = len(line) - len(line.lstrip()) |
1764 | 3608 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3618 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1765 | 3609 | segments[segs] = False | 3619 | segments[segs] = False |
1768 | 3610 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3620 | if write_prof_data[name]['allow'].get(segs, False): |
1769 | 3611 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3621 | write_prof_data[name]['allow'].pop(segs) |
1770 | 3622 | if write_prof_data[name]['deny'].get(segs, False): | ||
1771 | 3623 | write_prof_data[name]['deny'].pop(segs) | ||
1772 | 3612 | segments['change_profile'] = True | 3624 | segments['change_profile'] = True |
1773 | 3613 | write_prof_data[hat]['change_profile'].pop(cp) | 3625 | write_prof_data[hat]['change_profile'].pop(cp) |
1774 | 3614 | data.append(line) | 3626 | data.append(line) |
1775 | @@ -3633,10 +3645,12 @@ | |||
1776 | 3633 | if not segments['alias'] and True in segments.values(): | 3645 | if not segments['alias'] and True in segments.values(): |
1777 | 3634 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3646 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1778 | 3635 | depth = len(line) - len(line.lstrip()) | 3647 | depth = len(line) - len(line.lstrip()) |
1780 | 3636 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3648 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1781 | 3637 | segments[segs] = False | 3649 | segments[segs] = False |
1784 | 3638 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3650 | if write_prof_data[name]['allow'].get(segs, False): |
1785 | 3639 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3651 | write_prof_data[name]['allow'].pop(segs) |
1786 | 3652 | if write_prof_data[name]['deny'].get(segs, False): | ||
1787 | 3653 | write_prof_data[name]['deny'].pop(segs) | ||
1788 | 3640 | segments['alias'] = True | 3654 | segments['alias'] = True |
1789 | 3641 | if profile: | 3655 | if profile: |
1790 | 3642 | write_prof_data[hat]['alias'].pop(from_name) | 3656 | write_prof_data[hat]['alias'].pop(from_name) |
1791 | @@ -3660,10 +3674,12 @@ | |||
1792 | 3660 | if not segments['rlimit'] and True in segments.values(): | 3674 | if not segments['rlimit'] and True in segments.values(): |
1793 | 3661 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3675 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1794 | 3662 | depth = len(line) - len(line.lstrip()) | 3676 | depth = len(line) - len(line.lstrip()) |
1796 | 3663 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3677 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1797 | 3664 | segments[segs] = False | 3678 | segments[segs] = False |
1800 | 3665 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3679 | if write_prof_data[name]['allow'].get(segs, False): |
1801 | 3666 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3680 | write_prof_data[name]['allow'].pop(segs) |
1802 | 3681 | if write_prof_data[name]['deny'].get(segs, False): | ||
1803 | 3682 | write_prof_data[name]['deny'].pop(segs) | ||
1804 | 3667 | segments['rlimit'] = True | 3683 | segments['rlimit'] = True |
1805 | 3668 | write_prof_data[hat]['rlimit'].pop(from_name) | 3684 | write_prof_data[hat]['rlimit'].pop(from_name) |
1806 | 3669 | data.append(line) | 3685 | data.append(line) |
1807 | @@ -3683,10 +3699,12 @@ | |||
1808 | 3683 | if not segments['lvar'] and True in segments.values(): | 3699 | if not segments['lvar'] and True in segments.values(): |
1809 | 3684 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3700 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1810 | 3685 | depth = len(line) - len(line.lstrip()) | 3701 | depth = len(line) - len(line.lstrip()) |
1812 | 3686 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3702 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1813 | 3687 | segments[segs] = False | 3703 | segments[segs] = False |
1816 | 3688 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3704 | if write_prof_data[name]['allow'].get(segs, False): |
1817 | 3689 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3705 | write_prof_data[name]['allow'].pop(segs) |
1818 | 3706 | if write_prof_data[name]['deny'].get(segs, False): | ||
1819 | 3707 | write_prof_data[name]['deny'].pop(segs) | ||
1820 | 3690 | segments['lvar'] = True | 3708 | segments['lvar'] = True |
1821 | 3691 | write_prof_data[hat]['lvar'].pop(bool_var) | 3709 | write_prof_data[hat]['lvar'].pop(bool_var) |
1822 | 3692 | data.append(line) | 3710 | data.append(line) |
1823 | @@ -3712,10 +3730,12 @@ | |||
1824 | 3712 | if not segments['lvar'] and True in segments.values(): | 3730 | if not segments['lvar'] and True in segments.values(): |
1825 | 3713 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3731 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1826 | 3714 | depth = len(line) - len(line.lstrip()) | 3732 | depth = len(line) - len(line.lstrip()) |
1828 | 3715 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3733 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1829 | 3716 | segments[segs] = False | 3734 | segments[segs] = False |
1832 | 3717 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3735 | if write_prof_data[name]['allow'].get(segs, False): |
1833 | 3718 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3736 | write_prof_data[name]['allow'].pop(segs) |
1834 | 3737 | if write_prof_data[name]['deny'].get(segs, False): | ||
1835 | 3738 | write_prof_data[name]['deny'].pop(segs) | ||
1836 | 3719 | segments['lvar'] = True | 3739 | segments['lvar'] = True |
1837 | 3720 | if profile: | 3740 | if profile: |
1838 | 3721 | write_prof_data[hat]['lvar'].pop(list_var) | 3741 | write_prof_data[hat]['lvar'].pop(list_var) |
1839 | @@ -3747,7 +3767,7 @@ | |||
1840 | 3747 | 3767 | ||
1841 | 3748 | tmpmode = set() | 3768 | tmpmode = set() |
1842 | 3749 | if user: | 3769 | if user: |
1844 | 3750 | tmpmode = str_to_mode('%s::' %mode) | 3770 | tmpmode = str_to_mode('%s::' % mode) |
1845 | 3751 | else: | 3771 | else: |
1846 | 3752 | tmpmode = str_to_mode(mode) | 3772 | tmpmode = str_to_mode(mode) |
1847 | 3753 | 3773 | ||
1848 | @@ -3764,10 +3784,12 @@ | |||
1849 | 3764 | if not segments['path'] and True in segments.values(): | 3784 | if not segments['path'] and True in segments.values(): |
1850 | 3765 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3785 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1851 | 3766 | depth = len(line) - len(line.lstrip()) | 3786 | depth = len(line) - len(line.lstrip()) |
1853 | 3767 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3787 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1854 | 3768 | segments[segs] = False | 3788 | segments[segs] = False |
1857 | 3769 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3789 | if write_prof_data[name]['allow'].get(segs, False): |
1858 | 3770 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3790 | write_prof_data[name]['allow'].pop(segs) |
1859 | 3791 | if write_prof_data[name]['deny'].get(segs, False): | ||
1860 | 3792 | write_prof_data[name]['deny'].pop(segs) | ||
1861 | 3771 | segments['path'] = True | 3793 | segments['path'] = True |
1862 | 3772 | write_prof_data[hat][allow]['path'].pop(path) | 3794 | write_prof_data[hat][allow]['path'].pop(path) |
1863 | 3773 | data.append(line) | 3795 | data.append(line) |
1864 | @@ -3782,10 +3804,12 @@ | |||
1865 | 3782 | if not segments['include'] and True in segments.values(): | 3804 | if not segments['include'] and True in segments.values(): |
1866 | 3783 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3805 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1867 | 3784 | depth = len(line) - len(line.lstrip()) | 3806 | depth = len(line) - len(line.lstrip()) |
1869 | 3785 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3807 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1870 | 3786 | segments[segs] = False | 3808 | segments[segs] = False |
1873 | 3787 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3809 | if write_prof_data[name]['allow'].get(segs, False): |
1874 | 3788 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3810 | write_prof_data[name]['allow'].pop(segs) |
1875 | 3811 | if write_prof_data[name]['deny'].get(segs, False): | ||
1876 | 3812 | write_prof_data[name]['deny'].pop(segs) | ||
1877 | 3789 | segments['include'] = True | 3813 | segments['include'] = True |
1878 | 3790 | write_prof_data[hat]['include'].pop(include_name) | 3814 | write_prof_data[hat]['include'].pop(include_name) |
1879 | 3791 | data.append(line) | 3815 | data.append(line) |
1880 | @@ -3833,16 +3857,18 @@ | |||
1881 | 3833 | if not segments['netdomain'] and True in segments.values(): | 3857 | if not segments['netdomain'] and True in segments.values(): |
1882 | 3834 | for segs in list(filter(lambda x: segments[x], segments.keys())): | 3858 | for segs in list(filter(lambda x: segments[x], segments.keys())): |
1883 | 3835 | depth = len(line) - len(line.lstrip()) | 3859 | depth = len(line) - len(line.lstrip()) |
1885 | 3836 | data += write_methods[segs](write_prof_data[name], int(depth/2)) | 3860 | data += write_methods[segs](write_prof_data[name], int(depth / 2)) |
1886 | 3837 | segments[segs] = False | 3861 | segments[segs] = False |
1889 | 3838 | if write_prof_data[name]['allow'].get(segs, False): write_prof_data[name]['allow'].pop(segs) | 3862 | if write_prof_data[name]['allow'].get(segs, False): |
1890 | 3839 | if write_prof_data[name]['deny'].get(segs, False): write_prof_data[name]['deny'].pop(segs) | 3863 | write_prof_data[name]['allow'].pop(segs) |
1891 | 3864 | if write_prof_data[name]['deny'].get(segs, False): | ||
1892 | 3865 | write_prof_data[name]['deny'].pop(segs) | ||
1893 | 3840 | segments['netdomain'] = True | 3866 | segments['netdomain'] = True |
1894 | 3841 | 3867 | ||
1895 | 3842 | elif RE_PROFILE_CHANGE_HAT.search(line): | 3868 | elif RE_PROFILE_CHANGE_HAT.search(line): |
1896 | 3843 | matches = RE_PROFILE_CHANGE_HAT.search(line).groups() | 3869 | matches = RE_PROFILE_CHANGE_HAT.search(line).groups() |
1897 | 3844 | hat = matches[0] | 3870 | hat = matches[0] |
1899 | 3845 | hat = strip_quotes(hat) | 3871 | hat = strip_quotes(hat) |
1900 | 3846 | if not write_prof_data[hat]['declared']: | 3872 | if not write_prof_data[hat]['declared']: |
1901 | 3847 | correct = False | 3873 | correct = False |
1902 | 3848 | if correct: | 3874 | if correct: |
1903 | @@ -3858,7 +3884,7 @@ | |||
1904 | 3858 | flags = matches[3] | 3884 | flags = matches[3] |
1905 | 3859 | if not write_prof_data[hat]['flags'] == flags: | 3885 | if not write_prof_data[hat]['flags'] == flags: |
1906 | 3860 | correct = False | 3886 | correct = False |
1908 | 3861 | if not write_prof_data[hat]['declared'] == False: | 3887 | if not write_prof_data[hat]['declared'] is False: |
1909 | 3862 | correct = False | 3888 | correct = False |
1910 | 3863 | if not write_filelist['profile'][profile][hat]: | 3889 | if not write_filelist['profile'][profile][hat]: |
1911 | 3864 | correct = False | 3890 | correct = False |
1912 | @@ -3883,10 +3909,10 @@ | |||
1913 | 3883 | 3909 | ||
1914 | 3884 | string += '\n'.join(data) | 3910 | string += '\n'.join(data) |
1915 | 3885 | 3911 | ||
1917 | 3886 | return string+'\n' | 3912 | return string + '\n' |
1918 | 3887 | 3913 | ||
1919 | 3888 | def write_profile_ui_feedback(profile): | 3914 | def write_profile_ui_feedback(profile): |
1921 | 3889 | UI_Info(_('Writing updated profile for %s.') %profile) | 3915 | aaui.UI_Info(_('Writing updated profile for %s.') % profile) |
1922 | 3890 | write_profile(profile) | 3916 | write_profile(profile) |
1923 | 3891 | 3917 | ||
1924 | 3892 | def write_profile(profile): | 3918 | def write_profile(profile): |
1925 | @@ -3896,7 +3922,7 @@ | |||
1926 | 3896 | else: | 3922 | else: |
1927 | 3897 | prof_filename = get_profile_filename(profile) | 3923 | prof_filename = get_profile_filename(profile) |
1928 | 3898 | 3924 | ||
1930 | 3899 | newprof = tempfile.NamedTemporaryFile('w', suffix='~' ,delete=False, dir=profile_dir) | 3925 | newprof = tempfile.NamedTemporaryFile('w', suffix='~', delete=False, dir=profile_dir) |
1931 | 3900 | if os.path.exists(prof_filename): | 3926 | if os.path.exists(prof_filename): |
1932 | 3901 | shutil.copymode(prof_filename, newprof.name) | 3927 | shutil.copymode(prof_filename, newprof.name) |
1933 | 3902 | else: | 3928 | else: |
1934 | @@ -3917,7 +3943,7 @@ | |||
1935 | 3917 | original_aa[profile] = deepcopy(aa[profile]) | 3943 | original_aa[profile] = deepcopy(aa[profile]) |
1936 | 3918 | 3944 | ||
1937 | 3919 | def matchliteral(aa_regexp, literal): | 3945 | def matchliteral(aa_regexp, literal): |
1939 | 3920 | p_regexp = '^'+convert_regexp(aa_regexp)+'$' | 3946 | p_regexp = '^' + convert_regexp(aa_regexp) + '$' |
1940 | 3921 | match = False | 3947 | match = False |
1941 | 3922 | try: | 3948 | try: |
1942 | 3923 | match = re.search(p_regexp, literal) | 3949 | match = re.search(p_regexp, literal) |
1943 | @@ -3932,19 +3958,19 @@ | |||
1944 | 3932 | m = [] | 3958 | m = [] |
1945 | 3933 | 3959 | ||
1946 | 3934 | cm, am, m = rematchfrag(profile, 'deny', exec_target) | 3960 | cm, am, m = rematchfrag(profile, 'deny', exec_target) |
1948 | 3935 | if cm & AA_MAY_EXEC: | 3961 | if cm & apparmor.aamode.AA_MAY_EXEC: |
1949 | 3936 | return -1 | 3962 | return -1 |
1950 | 3937 | 3963 | ||
1951 | 3938 | cm, am, m = match_prof_incs_to_path(profile, 'deny', exec_target) | 3964 | cm, am, m = match_prof_incs_to_path(profile, 'deny', exec_target) |
1953 | 3939 | if cm & AA_MAY_EXEC: | 3965 | if cm & apparmor.aamode.AA_MAY_EXEC: |
1954 | 3940 | return -1 | 3966 | return -1 |
1955 | 3941 | 3967 | ||
1956 | 3942 | cm, am, m = rematchfrag(profile, 'allow', exec_target) | 3968 | cm, am, m = rematchfrag(profile, 'allow', exec_target) |
1958 | 3943 | if cm & AA_MAY_EXEC: | 3969 | if cm & apparmor.aamode.AA_MAY_EXEC: |
1959 | 3944 | return 1 | 3970 | return 1 |
1960 | 3945 | 3971 | ||
1961 | 3946 | cm, am, m = match_prof_incs_to_path(profile, 'allow', exec_target) | 3972 | cm, am, m = match_prof_incs_to_path(profile, 'allow', exec_target) |
1963 | 3947 | if cm & AA_MAY_EXEC: | 3973 | if cm & apparmor.aamode.AA_MAY_EXEC: |
1964 | 3948 | return 1 | 3974 | return 1 |
1965 | 3949 | 3975 | ||
1966 | 3950 | return 0 | 3976 | return 0 |
1967 | @@ -3986,11 +4012,11 @@ | |||
1968 | 3986 | net_family_sock = False | 4012 | net_family_sock = False |
1969 | 3987 | if netrules['rule'].get('all', False): | 4013 | if netrules['rule'].get('all', False): |
1970 | 3988 | all_net = True | 4014 | all_net = True |
1972 | 3989 | if netrules['rule'].get(family, False) == True: | 4015 | if netrules['rule'].get(family, False) is True: |
1973 | 3990 | all_net_family = True | 4016 | all_net_family = True |
1974 | 3991 | if (netrules['rule'].get(family, False) and | 4017 | if (netrules['rule'].get(family, False) and |
1977 | 3992 | type(netrules['rule'][family]) == dict and | 4018 | type(netrules['rule'][family]) == dict and |
1978 | 3993 | netrules['rule'][family][sock_type]): | 4019 | netrules['rule'][family][sock_type]): |
1979 | 3994 | net_family_sock = True | 4020 | net_family_sock = True |
1980 | 3995 | 4021 | ||
1981 | 3996 | if all_net or all_net_family or net_family_sock: | 4022 | if all_net or all_net_family or net_family_sock: |
1982 | @@ -4004,7 +4030,7 @@ | |||
1983 | 4004 | 4030 | ||
1984 | 4005 | prof_filename = get_profile_filename(bin_path) | 4031 | prof_filename = get_profile_filename(bin_path) |
1985 | 4006 | 4032 | ||
1987 | 4007 | subprocess.call("cat '%s' | %s -I%s -r >/dev/null 2>&1" %(prof_filename, parser ,profile_dir), shell=True) | 4033 | subprocess.call("cat '%s' | %s -I%s -r >/dev/null 2>&1" % (prof_filename, parser, profile_dir), shell=True) |
1988 | 4008 | 4034 | ||
1989 | 4009 | def reload(bin_path): | 4035 | def reload(bin_path): |
1990 | 4010 | bin_path = find_executable(bin_path) | 4036 | bin_path = find_executable(bin_path) |
1991 | @@ -4020,7 +4046,7 @@ | |||
1992 | 4020 | with open_file_read(filename) as f_in: | 4046 | with open_file_read(filename) as f_in: |
1993 | 4021 | data = f_in.readlines() | 4047 | data = f_in.readlines() |
1994 | 4022 | else: | 4048 | else: |
1996 | 4023 | raise AppArmorException(_('File Not Found: %s') %filename) | 4049 | raise AppArmorException(_('File Not Found: %s') % filename) |
1997 | 4024 | return data | 4050 | return data |
1998 | 4025 | 4051 | ||
1999 | 4026 | def load_include(incname): | 4052 | def load_include(incname): |
2000 | @@ -4029,7 +4055,7 @@ | |||
2001 | 4029 | return 0 | 4055 | return 0 |
2002 | 4030 | while load_includeslist: | 4056 | while load_includeslist: |
2003 | 4031 | incfile = load_includeslist.pop(0) | 4057 | incfile = load_includeslist.pop(0) |
2005 | 4032 | if os.path.isfile(profile_dir+'/'+incfile): | 4058 | if os.path.isfile(profile_dir + '/' + incfile): |
2006 | 4033 | data = get_include_data(incfile) | 4059 | data = get_include_data(incfile) |
2007 | 4034 | incdata = parse_profile_data(data, incfile, True) | 4060 | incdata = parse_profile_data(data, incfile, True) |
2008 | 4035 | #print(incdata) | 4061 | #print(incdata) |
2009 | @@ -4040,8 +4066,8 @@ | |||
2010 | 4040 | incdata[incname] = hasher() | 4066 | incdata[incname] = hasher() |
2011 | 4041 | attach_profile_data(include, incdata) | 4067 | attach_profile_data(include, incdata) |
2012 | 4042 | #If the include is a directory means include all subfiles | 4068 | #If the include is a directory means include all subfiles |
2015 | 4043 | elif os.path.isdir(profile_dir+'/'+incfile): | 4069 | elif os.path.isdir(profile_dir + '/' + incfile): |
2016 | 4044 | load_includeslist += list(map(lambda x: incfile+'/'+x, os.listdir(profile_dir+'/'+incfile))) | 4070 | load_includeslist += list(map(lambda x: incfile + '/' + x, os.listdir(profile_dir + '/' + incfile))) |
2017 | 4045 | 4071 | ||
2018 | 4046 | return 0 | 4072 | return 0 |
2019 | 4047 | 4073 | ||
2020 | @@ -4069,7 +4095,7 @@ | |||
2021 | 4069 | while includelist: | 4095 | while includelist: |
2022 | 4070 | incfile = str(includelist.pop(0)) | 4096 | incfile = str(includelist.pop(0)) |
2023 | 4071 | ret = load_include(incfile) | 4097 | ret = load_include(incfile) |
2025 | 4072 | if not include.get(incfile,{}): | 4098 | if not include.get(incfile, {}): |
2026 | 4073 | continue | 4099 | continue |
2027 | 4074 | cm, am, m = rematchfrag(include[incfile].get(incfile, {}), allow, path) | 4100 | cm, am, m = rematchfrag(include[incfile].get(incfile, {}), allow, path) |
2028 | 4075 | #print(incfile, cm, am, m) | 4101 | #print(incfile, cm, am, m) |
2029 | @@ -4111,7 +4137,7 @@ | |||
2030 | 4111 | includelist = [incname] | 4137 | includelist = [incname] |
2031 | 4112 | while includelist: | 4138 | while includelist: |
2032 | 4113 | inc = includelist.pop(0) | 4139 | inc = includelist.pop(0) |
2034 | 4114 | cm, am , m = rematchfrag(include[inc][inc], 'allow', path) | 4140 | cm, am, m = rematchfrag(include[inc][inc], 'allow', path) |
2035 | 4115 | if cm: | 4141 | if cm: |
2036 | 4116 | combinedmode |= cm | 4142 | combinedmode |= cm |
2037 | 4117 | combinedaudit |= am | 4143 | combinedaudit |= am |
2038 | @@ -4129,12 +4155,12 @@ | |||
2039 | 4129 | def check_qualifiers(program): | 4155 | def check_qualifiers(program): |
2040 | 4130 | if cfg['qualifiers'].get(program, False): | 4156 | if cfg['qualifiers'].get(program, False): |
2041 | 4131 | if cfg['qualifiers'][program] != 'p': | 4157 | if cfg['qualifiers'][program] != 'p': |
2043 | 4132 | fatal_error(_("%s is currently marked as a program that should not have its own\nprofile. Usually, programs are marked this way if creating a profile for \nthem is likely to break the rest of the system. If you know what you\'re\ndoing and are certain you want to create a profile for this program, edit\nthe corresponding entry in the [qualifiers] section in /etc/apparmor/logprof.conf.") %program) | 4158 | fatal_error(_("%s is currently marked as a program that should not have its own\nprofile. Usually, programs are marked this way if creating a profile for \nthem is likely to break the rest of the system. If you know what you\'re\ndoing and are certain you want to create a profile for this program, edit\nthe corresponding entry in the [qualifiers] section in /etc/apparmor/logprof.conf.") % program) |
2044 | 4133 | return False | 4159 | return False |
2045 | 4134 | 4160 | ||
2046 | 4135 | def get_subdirectories(current_dir): | 4161 | def get_subdirectories(current_dir): |
2047 | 4136 | """Returns a list of all directories directly inside given directory""" | 4162 | """Returns a list of all directories directly inside given directory""" |
2049 | 4137 | if sys.version_info < (3,0): | 4163 | if sys.version_info < (3, 0): |
2050 | 4138 | return os.walk(current_dir).next()[1] | 4164 | return os.walk(current_dir).next()[1] |
2051 | 4139 | else: | 4165 | else: |
2052 | 4140 | return os.walk(current_dir).__next__()[1] | 4166 | return os.walk(current_dir).__next__()[1] |
2053 | @@ -4152,7 +4178,7 @@ | |||
2054 | 4152 | continue | 4178 | continue |
2055 | 4153 | else: | 4179 | else: |
2056 | 4154 | fi = dirpath + '/' + fi | 4180 | fi = dirpath + '/' + fi |
2058 | 4155 | fi = fi.replace(profile_dir+'/', '', 1) | 4181 | fi = fi.replace(profile_dir + '/', '', 1) |
2059 | 4156 | load_include(fi) | 4182 | load_include(fi) |
2060 | 4157 | 4183 | ||
2061 | 4158 | def glob_common(path): | 4184 | def glob_common(path): |
2062 | @@ -4178,7 +4204,7 @@ | |||
2063 | 4178 | if name1 == name2: | 4204 | if name1 == name2: |
2064 | 4179 | return name1 | 4205 | return name1 |
2065 | 4180 | else: | 4206 | else: |
2067 | 4181 | return '%s^%s' %(name1, name2) | 4207 | return '%s^%s' % (name1, name2) |
2068 | 4182 | 4208 | ||
2069 | 4183 | def split_name(name): | 4209 | def split_name(name): |
2070 | 4184 | names = name.split('^') | 4210 | names = name.split('^') |
2071 | @@ -4187,7 +4213,7 @@ | |||
2072 | 4187 | else: | 4213 | else: |
2073 | 4188 | return names[0], names[1] | 4214 | return names[0], names[1] |
2074 | 4189 | def commonprefix(new, old): | 4215 | def commonprefix(new, old): |
2076 | 4190 | match=re.search(r'^([^\0]*)[^\0]*(\0\1[^\0]*)*$', '\0'.join([new, old])) | 4216 | match = re.search(r'^([^\0]*)[^\0]*(\0\1[^\0]*)*$', '\0'.join([new, old])) |
2077 | 4191 | if match: | 4217 | if match: |
2078 | 4192 | return match.groups()[0] | 4218 | return match.groups()[0] |
2079 | 4193 | return match | 4219 | return match |
2080 | @@ -4234,7 +4260,7 @@ | |||
2081 | 4234 | 4260 | ||
2082 | 4235 | profile_dir = conf.find_first_dir(cfg['settings']['profiledir']) or '/etc/apparmor.d' | 4261 | profile_dir = conf.find_first_dir(cfg['settings']['profiledir']) or '/etc/apparmor.d' |
2083 | 4236 | if not os.path.isdir(profile_dir): | 4262 | if not os.path.isdir(profile_dir): |
2085 | 4237 | raise AppArmorException('Can\'t find AppArmor profiles' ) | 4263 | raise AppArmorException('Can\'t find AppArmor profiles') |
2086 | 4238 | 4264 | ||
2087 | 4239 | extra_profile_dir = conf.find_first_dir(cfg['settings']['inactive_profiledir']) or '/etc/apparmor/profiles/extras/' | 4265 | extra_profile_dir = conf.find_first_dir(cfg['settings']['inactive_profiledir']) or '/etc/apparmor/profiles/extras/' |
2088 | 4240 | 4266 | ||
2089 | 4241 | 4267 | ||
2090 | === modified file 'apparmor/aamode.py' | |||
2091 | --- apparmor/aamode.py 2013-12-29 09:42:30 +0000 | |||
2092 | +++ apparmor/aamode.py 2014-02-12 00:39:55 +0000 | |||
2093 | @@ -16,7 +16,7 @@ | |||
2094 | 16 | def AA_OTHER(mode): | 16 | def AA_OTHER(mode): |
2095 | 17 | other = set() | 17 | other = set() |
2096 | 18 | for i in mode: | 18 | for i in mode: |
2098 | 19 | other.add('::%s'%i) | 19 | other.add('::%s' % i) |
2099 | 20 | return other | 20 | return other |
2100 | 21 | 21 | ||
2101 | 22 | def AA_OTHER_REMOVE(mode): | 22 | def AA_OTHER_REMOVE(mode): |
2102 | @@ -57,14 +57,14 @@ | |||
2103 | 57 | 'm': AA_EXEC_MMAP, 'M': AA_EXEC_MMAP, | 57 | 'm': AA_EXEC_MMAP, 'M': AA_EXEC_MMAP, |
2104 | 58 | 'i': AA_EXEC_INHERIT, 'I': AA_EXEC_INHERIT, | 58 | 'i': AA_EXEC_INHERIT, 'I': AA_EXEC_INHERIT, |
2105 | 59 | 'u': AA_EXEC_UNCONFINED | AA_EXEC_UNSAFE, # Unconfined + Unsafe | 59 | 'u': AA_EXEC_UNCONFINED | AA_EXEC_UNSAFE, # Unconfined + Unsafe |
2114 | 60 | 'U': AA_EXEC_UNCONFINED, | 60 | 'U': AA_EXEC_UNCONFINED, |
2115 | 61 | 'p': AA_EXEC_PROFILE | AA_EXEC_UNSAFE, # Profile + unsafe | 61 | 'p': AA_EXEC_PROFILE | AA_EXEC_UNSAFE, # Profile + unsafe |
2116 | 62 | 'P': AA_EXEC_PROFILE, | 62 | 'P': AA_EXEC_PROFILE, |
2117 | 63 | 'c': AA_EXEC_CHILD | AA_EXEC_UNSAFE, # Child + Unsafe | 63 | 'c': AA_EXEC_CHILD | AA_EXEC_UNSAFE, # Child + Unsafe |
2118 | 64 | 'C': AA_EXEC_CHILD, | 64 | 'C': AA_EXEC_CHILD, |
2119 | 65 | 'n': AA_EXEC_NT | AA_EXEC_UNSAFE, | 65 | 'n': AA_EXEC_NT | AA_EXEC_UNSAFE, |
2120 | 66 | 'N': AA_EXEC_NT | 66 | 'N': AA_EXEC_NT |
2121 | 67 | } | 67 | } |
2122 | 68 | 68 | ||
2123 | 69 | LOG_MODE_RE = re.compile('(r|w|l|m|k|a|x|ix|ux|px|cx|nx|pix|cix|Ix|Ux|Px|PUx|Cx|Nx|Pix|Cix)') | 69 | LOG_MODE_RE = re.compile('(r|w|l|m|k|a|x|ix|ux|px|cx|nx|pix|cix|Ix|Ux|Px|PUx|Cx|Nx|Pix|Cix)') |
2124 | 70 | MODE_MAP_RE = re.compile('(r|w|l|m|k|a|x|i|u|p|c|n|I|U|P|C|N)') | 70 | MODE_MAP_RE = re.compile('(r|w|l|m|k|a|x|i|u|p|c|n|I|U|P|C|N)') |
2125 | 71 | 71 | ||
2126 | === modified file 'apparmor/common.py' | |||
2127 | --- apparmor/common.py 2014-02-01 01:34:08 +0000 | |||
2128 | +++ apparmor/common.py 2014-02-12 00:39:55 +0000 | |||
2129 | @@ -11,7 +11,6 @@ | |||
2130 | 11 | from __future__ import print_function | 11 | from __future__ import print_function |
2131 | 12 | import codecs | 12 | import codecs |
2132 | 13 | import collections | 13 | import collections |
2133 | 14 | import gettext | ||
2134 | 15 | import glob | 14 | import glob |
2135 | 16 | import logging | 15 | import logging |
2136 | 17 | import os | 16 | import os |
2137 | @@ -23,6 +22,7 @@ | |||
2138 | 23 | 22 | ||
2139 | 24 | DEBUGGING = False | 23 | DEBUGGING = False |
2140 | 25 | 24 | ||
2141 | 25 | |||
2142 | 26 | # | 26 | # |
2143 | 27 | # Utility classes | 27 | # Utility classes |
2144 | 28 | # | 28 | # |
2145 | @@ -110,7 +110,7 @@ | |||
2146 | 110 | debug("%s (relative)" % (m)) | 110 | debug("%s (relative)" % (m)) |
2147 | 111 | return False | 111 | return False |
2148 | 112 | 112 | ||
2150 | 113 | if '"' in path: # We double quote elsewhere | 113 | if '"' in path: # We double quote elsewhere |
2151 | 114 | return False | 114 | return False |
2152 | 115 | 115 | ||
2153 | 116 | try: | 116 | try: |
2154 | @@ -166,13 +166,6 @@ | |||
2155 | 166 | # Creates a dictionary for any depth and returns empty dictionary otherwise | 166 | # Creates a dictionary for any depth and returns empty dictionary otherwise |
2156 | 167 | return collections.defaultdict(hasher) | 167 | return collections.defaultdict(hasher) |
2157 | 168 | 168 | ||
2158 | 169 | def init_translations(domain='apparmor-utils'): | ||
2159 | 170 | """Installs the translations for the given domain, defaults to apparmor-utils domain""" | ||
2160 | 171 | #Setup Translation | ||
2161 | 172 | gettext.translation(domain, fallback=True) | ||
2162 | 173 | gettext.install(domain) | ||
2163 | 174 | |||
2164 | 175 | |||
2165 | 176 | def convert_regexp(regexp): | 169 | def convert_regexp(regexp): |
2166 | 177 | regex_paren = re.compile('^(.*){([^}]*)}(.*)$') | 170 | regex_paren = re.compile('^(.*){([^}]*)}(.*)$') |
2167 | 178 | regexp = regexp.strip() | 171 | regexp = regexp.strip() |
2168 | @@ -182,8 +175,8 @@ | |||
2169 | 182 | match = regex_paren.search(new_reg).groups() | 175 | match = regex_paren.search(new_reg).groups() |
2170 | 183 | prev = match[0] | 176 | prev = match[0] |
2171 | 184 | after = match[2] | 177 | after = match[2] |
2174 | 185 | p1 = match[1].replace(',','|') | 178 | p1 = match[1].replace(',', '|') |
2175 | 186 | new_reg = prev+'('+p1+')'+after | 179 | new_reg = prev + '(' + p1 + ')' + after |
2176 | 187 | 180 | ||
2177 | 188 | new_reg = new_reg.replace('?', '[^/\000]') | 181 | new_reg = new_reg.replace('?', '[^/\000]') |
2178 | 189 | 182 | ||
2179 | @@ -198,7 +191,7 @@ | |||
2180 | 198 | if regexp[0] != '^': | 191 | if regexp[0] != '^': |
2181 | 199 | new_reg = '^' + new_reg | 192 | new_reg = '^' + new_reg |
2182 | 200 | if regexp[-1] != '$': | 193 | if regexp[-1] != '$': |
2184 | 201 | new_reg = new_reg + '$' | 194 | new_reg = new_reg + '$' |
2185 | 202 | return new_reg | 195 | return new_reg |
2186 | 203 | 196 | ||
2187 | 204 | def user_perm(prof_dir): | 197 | def user_perm(prof_dir): |
2188 | @@ -221,7 +214,7 @@ | |||
2189 | 221 | self.debugging = False | 214 | self.debugging = False |
2190 | 222 | if self.debugging not in range(0, 4): | 215 | if self.debugging not in range(0, 4): |
2191 | 223 | sys.stdout.write('Environment Variable: LOGPROF_DEBUG contains invalid value: %s' | 216 | sys.stdout.write('Environment Variable: LOGPROF_DEBUG contains invalid value: %s' |
2193 | 224 | %os.getenv('LOGPROF_DEBUG')) | 217 | % os.getenv('LOGPROF_DEBUG')) |
2194 | 225 | if self.debugging == 0: # debugging disabled, don't need to setup logging | 218 | if self.debugging == 0: # debugging disabled, don't need to setup logging |
2195 | 226 | return | 219 | return |
2196 | 227 | if self.debugging == 1: | 220 | if self.debugging == 1: |
2197 | @@ -230,22 +223,21 @@ | |||
2198 | 230 | self.debug_level = logging.INFO | 223 | self.debug_level = logging.INFO |
2199 | 231 | elif self.debugging == 3: | 224 | elif self.debugging == 3: |
2200 | 232 | self.debug_level = logging.DEBUG | 225 | self.debug_level = logging.DEBUG |
2202 | 233 | 226 | ||
2203 | 234 | try: | 227 | try: |
2204 | 235 | logging.basicConfig(filename=self.logfile, level=self.debug_level, | 228 | logging.basicConfig(filename=self.logfile, level=self.debug_level, |
2205 | 236 | format='%(asctime)s - %(name)s - %(message)s\n') | 229 | format='%(asctime)s - %(name)s - %(message)s\n') |
2206 | 237 | except OSError: | 230 | except OSError: |
2207 | 238 | # Unable to open the default logfile, so create a temporary logfile and tell use about it | 231 | # Unable to open the default logfile, so create a temporary logfile and tell use about it |
2208 | 239 | import tempfile | 232 | import tempfile |
2212 | 240 | templog = tempfile.NamedTemporaryFile('w', prefix='apparmor', suffix='.log' ,delete=False) | 233 | templog = tempfile.NamedTemporaryFile('w', prefix='apparmor', suffix='.log', delete=False) |
2213 | 241 | sys.stdout.write("\nCould not open: %s\nLogging to: %s\n"%(self.logfile, templog.name)) | 234 | sys.stdout.write("\nCould not open: %s\nLogging to: %s\n" % (self.logfile, templog.name)) |
2214 | 242 | 235 | ||
2215 | 243 | logging.basicConfig(filename=templog.name, level=self.debug_level, | 236 | logging.basicConfig(filename=templog.name, level=self.debug_level, |
2216 | 244 | format='%(asctime)s - %(name)s - %(message)s\n') | 237 | format='%(asctime)s - %(name)s - %(message)s\n') |
2218 | 245 | 238 | ||
2219 | 246 | self.logger = logging.getLogger(module_name) | 239 | self.logger = logging.getLogger(module_name) |
2220 | 247 | 240 | ||
2221 | 248 | |||
2222 | 249 | def error(self, message): | 241 | def error(self, message): |
2223 | 250 | if self.debugging: | 242 | if self.debugging: |
2224 | 251 | self.logger.error(message) | 243 | self.logger.error(message) |
2225 | 252 | 244 | ||
2226 | === modified file 'apparmor/config.py' | |||
2227 | --- apparmor/config.py 2013-12-29 09:42:30 +0000 | |||
2228 | +++ apparmor/config.py 2014-02-12 00:39:55 +0000 | |||
2229 | @@ -20,6 +20,7 @@ | |||
2230 | 20 | import tempfile | 20 | import tempfile |
2231 | 21 | if sys.version_info < (3, 0): | 21 | if sys.version_info < (3, 0): |
2232 | 22 | import ConfigParser as configparser | 22 | import ConfigParser as configparser |
2233 | 23 | |||
2234 | 23 | # Class to provide the object[section][option] behavior in Python2 | 24 | # Class to provide the object[section][option] behavior in Python2 |
2235 | 24 | class configparser_py2(configparser.ConfigParser): | 25 | class configparser_py2(configparser.ConfigParser): |
2236 | 25 | def __getitem__(self, section): | 26 | def __getitem__(self, section): |
2237 | @@ -34,7 +35,7 @@ | |||
2238 | 34 | import configparser | 35 | import configparser |
2239 | 35 | 36 | ||
2240 | 36 | 37 | ||
2242 | 37 | from apparmor.common import AppArmorException, open_file_read#, warn, msg, | 38 | from apparmor.common import AppArmorException, open_file_read # , warn, msg, |
2243 | 38 | 39 | ||
2244 | 39 | 40 | ||
2245 | 40 | # CFG = None | 41 | # CFG = None |
2246 | @@ -110,7 +111,6 @@ | |||
2247 | 110 | # Replace the target config file with the temporary file | 111 | # Replace the target config file with the temporary file |
2248 | 111 | os.rename(config_file.name, filepath) | 112 | os.rename(config_file.name, filepath) |
2249 | 112 | 113 | ||
2250 | 113 | |||
2251 | 114 | def find_first_file(self, file_list): | 114 | def find_first_file(self, file_list): |
2252 | 115 | """Returns name of first matching file None otherwise""" | 115 | """Returns name of first matching file None otherwise""" |
2253 | 116 | filename = None | 116 | filename = None |
2254 | @@ -164,7 +164,7 @@ | |||
2255 | 164 | option, value = result[0].split('=') | 164 | option, value = result[0].split('=') |
2256 | 165 | if '#' in line: | 165 | if '#' in line: |
2257 | 166 | comment = value.split('#', 1)[1] | 166 | comment = value.split('#', 1)[1] |
2259 | 167 | comment = '#'+comment | 167 | comment = '#' + comment |
2260 | 168 | else: | 168 | else: |
2261 | 169 | comment = '' | 169 | comment = '' |
2262 | 170 | # If option exists in the new config file | 170 | # If option exists in the new config file |
2263 | @@ -172,7 +172,7 @@ | |||
2264 | 172 | # If value is different | 172 | # If value is different |
2265 | 173 | if value != config[''][option]: | 173 | if value != config[''][option]: |
2266 | 174 | value_new = config[''][option] | 174 | value_new = config[''][option] |
2268 | 175 | if value_new != None: | 175 | if value_new is not None: |
2269 | 176 | # Update value | 176 | # Update value |
2270 | 177 | if '"' in line: | 177 | if '"' in line: |
2271 | 178 | value_new = '"' + value_new + '"' | 178 | value_new = '"' + value_new + '"' |
2272 | @@ -190,7 +190,7 @@ | |||
2273 | 190 | # If option exists in the new config file | 190 | # If option exists in the new config file |
2274 | 191 | if option in options: | 191 | if option in options: |
2275 | 192 | # If its no longer option type | 192 | # If its no longer option type |
2277 | 193 | if config[''][option] != None: | 193 | if config[''][option] is not None: |
2278 | 194 | value = config[''][option] | 194 | value = config[''][option] |
2279 | 195 | line = option + '=' + value + '\n' | 195 | line = option + '=' + value + '\n' |
2280 | 196 | f_out.write(line) | 196 | f_out.write(line) |
2281 | @@ -204,7 +204,7 @@ | |||
2282 | 204 | for option in options: | 204 | for option in options: |
2283 | 205 | value = config[''][option] | 205 | value = config[''][option] |
2284 | 206 | # option type entry | 206 | # option type entry |
2286 | 207 | if value == None: | 207 | if value is None: |
2287 | 208 | line = option + '\n' | 208 | line = option + '\n' |
2288 | 209 | # option=value type entry | 209 | # option=value type entry |
2289 | 210 | else: | 210 | else: |
2290 | @@ -273,7 +273,7 @@ | |||
2291 | 273 | if section in sections: | 273 | if section in sections: |
2292 | 274 | sections.remove(section) | 274 | sections.remove(section) |
2293 | 275 | for section in sections: | 275 | for section in sections: |
2295 | 276 | f_out.write('\n['+section+']\n') | 276 | f_out.write('\n[%s]\n' % section) |
2296 | 277 | options = config.options(section) | 277 | options = config.options(section) |
2297 | 278 | for option in options: | 278 | for option in options: |
2298 | 279 | line = ' ' + option + ' = ' + config[section][option] + '\n' | 279 | line = ' ' + option + ' = ' + config[section][option] + '\n' |
2299 | 280 | 280 | ||
2300 | === modified file 'apparmor/logparser.py' | |||
2301 | --- apparmor/logparser.py 2013-09-28 15:13:06 +0000 | |||
2302 | +++ apparmor/logparser.py 2014-02-12 00:39:55 +0000 | |||
2303 | @@ -11,16 +11,22 @@ | |||
2304 | 11 | # GNU General Public License for more details. | 11 | # GNU General Public License for more details. |
2305 | 12 | # | 12 | # |
2306 | 13 | # ---------------------------------------------------------------------- | 13 | # ---------------------------------------------------------------------- |
2307 | 14 | import gettext | ||
2308 | 14 | import os | 15 | import os |
2309 | 15 | import re | 16 | import re |
2310 | 16 | import sys | 17 | import sys |
2311 | 17 | import time | 18 | import time |
2312 | 18 | import LibAppArmor | 19 | import LibAppArmor |
2318 | 19 | from apparmor.common import (AppArmorException, error, debug, msg, | 20 | from apparmor.common import (AppArmorException, error, debug, |
2319 | 20 | open_file_read, valid_path, | 21 | open_file_read, valid_path, hasher, |
2320 | 21 | hasher, open_file_write, convert_regexp, DebugLogger) | 22 | open_file_write, convert_regexp, |
2321 | 22 | 23 | DebugLogger) | |
2322 | 23 | from apparmor.aamode import * | 24 | |
2323 | 25 | from apparmor.aamode import validate_log_mode, log_str_to_mode, hide_log_mode, AA_MAY_EXEC | ||
2324 | 26 | |||
2325 | 27 | # setup module translations | ||
2326 | 28 | from apparmor.translations import init_translation | ||
2327 | 29 | _ = init_translation() | ||
2328 | 24 | 30 | ||
2329 | 25 | class ReadLog: | 31 | class ReadLog: |
2330 | 26 | RE_LOG_v2_6_syslog = re.compile('kernel:\s+(\[[\d\.\s]+\]\s+)?type=\d+\s+audit\([\d\.\:]+\):\s+apparmor=') | 32 | RE_LOG_v2_6_syslog = re.compile('kernel:\s+(\[[\d\.\s]+\]\s+)?type=\d+\s+audit\([\d\.\:]+\):\s+apparmor=') |
2331 | @@ -31,9 +37,8 @@ | |||
2332 | 31 | PROFILE_MODE_NT_RE = re.compile('r|w|l|m|k|a|x|ix|ux|px|cx|pix|cix|Ux|Px|PUx|Cx|Pix|Cix') | 37 | PROFILE_MODE_NT_RE = re.compile('r|w|l|m|k|a|x|ix|ux|px|cx|pix|cix|Ux|Px|PUx|Cx|Pix|Cix') |
2333 | 32 | PROFILE_MODE_DENY_RE = re.compile('r|w|l|m|k|a|x') | 38 | PROFILE_MODE_DENY_RE = re.compile('r|w|l|m|k|a|x') |
2334 | 33 | # Used by netdomain to identify the operation types | 39 | # Used by netdomain to identify the operation types |
2338 | 34 | OPERATION_TYPES = { | 40 | # New socket names |
2339 | 35 | # New socket names | 41 | OPERATION_TYPES = {'create': 'net', |
2337 | 36 | 'create': 'net', | ||
2340 | 37 | 'post_create': 'net', | 42 | 'post_create': 'net', |
2341 | 38 | 'bind': 'net', | 43 | 'bind': 'net', |
2342 | 39 | 'connect': 'net', | 44 | 'connect': 'net', |
2343 | @@ -47,6 +52,7 @@ | |||
2344 | 47 | 'setsockopt': 'net', | 52 | 'setsockopt': 'net', |
2345 | 48 | 'sock_shutdown': 'net' | 53 | 'sock_shutdown': 'net' |
2346 | 49 | } | 54 | } |
2347 | 55 | |||
2348 | 50 | def __init__(self, pid, filename, existing_profiles, profile_dir, log): | 56 | def __init__(self, pid, filename, existing_profiles, profile_dir, log): |
2349 | 51 | self.filename = filename | 57 | self.filename = filename |
2350 | 52 | self.profile_dir = profile_dir | 58 | self.profile_dir = profile_dir |
2351 | @@ -96,7 +102,7 @@ | |||
2352 | 96 | msg = msg.strip() | 102 | msg = msg.strip() |
2353 | 97 | self.debug_logger.info('parse_event: %s' % msg) | 103 | self.debug_logger.info('parse_event: %s' % msg) |
2354 | 98 | #print(repr(msg)) | 104 | #print(repr(msg)) |
2356 | 99 | if sys.version_info < (3,0): | 105 | if sys.version_info < (3, 0): |
2357 | 100 | # parse_record fails with u'foo' style strings hence typecasting to string | 106 | # parse_record fails with u'foo' style strings hence typecasting to string |
2358 | 101 | msg = str(msg) | 107 | msg = str(msg) |
2359 | 102 | event = LibAppArmor.parse_record(msg) | 108 | event = LibAppArmor.parse_record(msg) |
2360 | @@ -152,8 +158,7 @@ | |||
2361 | 152 | 158 | ||
2362 | 153 | if ev['aamode']: | 159 | if ev['aamode']: |
2363 | 154 | # Convert aamode values to their counter-parts | 160 | # Convert aamode values to their counter-parts |
2366 | 155 | mode_convertor = { | 161 | mode_convertor = {0: 'UNKNOWN', |
2365 | 156 | 0: 'UNKNOWN', | ||
2367 | 157 | 1: 'ERROR', | 162 | 1: 'ERROR', |
2368 | 158 | 2: 'AUDITING', | 163 | 2: 'AUDITING', |
2369 | 159 | 3: 'PERMITTING', | 164 | 3: 'PERMITTING', |
2370 | @@ -254,30 +259,30 @@ | |||
2371 | 254 | if e['operation'] == 'exec': | 259 | if e['operation'] == 'exec': |
2372 | 255 | if e.get('info', False) and e['info'] == 'mandatory profile missing': | 260 | if e.get('info', False) and e['info'] == 'mandatory profile missing': |
2373 | 256 | self.add_to_tree(e['pid'], e['parent'], 'exec', | 261 | self.add_to_tree(e['pid'], e['parent'], 'exec', |
2375 | 257 | [profile, hat, aamode, 'PERMITTING', e['denied_mask'], e['name'], e['name2']]) | 262 | [profile, hat, aamode, 'PERMITTING', e['denied_mask'], e['name'], e['name2']]) |
2376 | 258 | elif e.get('name2', False) and '\\null-/' in e['name2']: | 263 | elif e.get('name2', False) and '\\null-/' in e['name2']: |
2377 | 259 | self.add_to_tree(e['pid'], e['parent'], 'exec', | 264 | self.add_to_tree(e['pid'], e['parent'], 'exec', |
2379 | 260 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 265 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2380 | 261 | elif e.get('name', False): | 266 | elif e.get('name', False): |
2381 | 262 | self.add_to_tree(e['pid'], e['parent'], 'exec', | 267 | self.add_to_tree(e['pid'], e['parent'], 'exec', |
2383 | 263 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 268 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2384 | 264 | else: | 269 | else: |
2385 | 265 | self.debug_logger.debug('add_event_to_tree: dropped exec event in %s' % e['profile']) | 270 | self.debug_logger.debug('add_event_to_tree: dropped exec event in %s' % e['profile']) |
2386 | 266 | 271 | ||
2387 | 267 | elif 'file_' in e['operation']: | 272 | elif 'file_' in e['operation']: |
2388 | 268 | self.add_to_tree(e['pid'], e['parent'], 'path', | 273 | self.add_to_tree(e['pid'], e['parent'], 'path', |
2390 | 269 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 274 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2391 | 270 | elif e['operation'] in ['open', 'truncate', 'mkdir', 'mknod', 'rename_src', | 275 | elif e['operation'] in ['open', 'truncate', 'mkdir', 'mknod', 'rename_src', |
2392 | 271 | 'rename_dest', 'unlink', 'rmdir', 'symlink_create', 'link']: | 276 | 'rename_dest', 'unlink', 'rmdir', 'symlink_create', 'link']: |
2393 | 272 | #print(e['operation'], e['name']) | 277 | #print(e['operation'], e['name']) |
2394 | 273 | self.add_to_tree(e['pid'], e['parent'], 'path', | 278 | self.add_to_tree(e['pid'], e['parent'], 'path', |
2396 | 274 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 279 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2397 | 275 | elif e['operation'] == 'capable': | 280 | elif e['operation'] == 'capable': |
2398 | 276 | self.add_to_tree(e['pid'], e['parent'], 'capability', | 281 | self.add_to_tree(e['pid'], e['parent'], 'capability', |
2400 | 277 | [profile, hat, prog, aamode, e['name'], '']) | 282 | [profile, hat, prog, aamode, e['name'], '']) |
2401 | 278 | elif e['operation'] == 'setattr' or 'xattr' in e['operation']: | 283 | elif e['operation'] == 'setattr' or 'xattr' in e['operation']: |
2402 | 279 | self.add_to_tree(e['pid'], e['parent'], 'path', | 284 | self.add_to_tree(e['pid'], e['parent'], 'path', |
2404 | 280 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 285 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2405 | 281 | elif 'inode_' in e['operation']: | 286 | elif 'inode_' in e['operation']: |
2406 | 282 | is_domain_change = False | 287 | is_domain_change = False |
2407 | 283 | if e['operation'] == 'inode_permission' and (e['denied_mask'] & AA_MAY_EXEC) and aamode == 'PERMITTING': | 288 | if e['operation'] == 'inode_permission' and (e['denied_mask'] & AA_MAY_EXEC) and aamode == 'PERMITTING': |
2408 | @@ -290,17 +295,17 @@ | |||
2409 | 290 | 295 | ||
2410 | 291 | if is_domain_change: | 296 | if is_domain_change: |
2411 | 292 | self.add_to_tree(e['pid'], e['parent'], 'exec', | 297 | self.add_to_tree(e['pid'], e['parent'], 'exec', |
2413 | 293 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], e['name2']]) | 298 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], e['name2']]) |
2414 | 294 | else: | 299 | else: |
2415 | 295 | self.add_to_tree(e['pid'], e['parent'], 'path', | 300 | self.add_to_tree(e['pid'], e['parent'], 'path', |
2417 | 296 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 301 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2418 | 297 | 302 | ||
2419 | 298 | elif e['operation'] == 'sysctl': | 303 | elif e['operation'] == 'sysctl': |
2420 | 299 | self.add_to_tree(e['pid'], e['parent'], 'path', | 304 | self.add_to_tree(e['pid'], e['parent'], 'path', |
2422 | 300 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) | 305 | [profile, hat, prog, aamode, e['denied_mask'], e['name'], '']) |
2423 | 301 | 306 | ||
2424 | 302 | elif e['operation'] == 'clone': | 307 | elif e['operation'] == 'clone': |
2426 | 303 | parent , child = e['pid'], e['task'] | 308 | parent, child = e['pid'], e['task'] |
2427 | 304 | if not parent: | 309 | if not parent: |
2428 | 305 | parent = 'null-complain-profile' | 310 | parent = 'null-complain-profile' |
2429 | 306 | if not hat: | 311 | if not hat: |
2430 | @@ -321,10 +326,10 @@ | |||
2431 | 321 | 326 | ||
2432 | 322 | elif self.op_type(e['operation']) == 'net': | 327 | elif self.op_type(e['operation']) == 'net': |
2433 | 323 | self.add_to_tree(e['pid'], e['parent'], 'netdomain', | 328 | self.add_to_tree(e['pid'], e['parent'], 'netdomain', |
2435 | 324 | [profile, hat, prog, aamode, e['family'], e['sock_type'], e['protocol']]) | 329 | [profile, hat, prog, aamode, e['family'], e['sock_type'], e['protocol']]) |
2436 | 325 | elif e['operation'] == 'change_hat': | 330 | elif e['operation'] == 'change_hat': |
2437 | 326 | self.add_to_tree(e['pid'], e['parent'], 'unknown_hat', | 331 | self.add_to_tree(e['pid'], e['parent'], 'unknown_hat', |
2439 | 327 | [profile, hat, aamode, hat]) | 332 | [profile, hat, aamode, hat]) |
2440 | 328 | else: | 333 | else: |
2441 | 329 | self.debug_logger.debug('UNHANDLED: %s' % e) | 334 | self.debug_logger.debug('UNHANDLED: %s' % e) |
2442 | 330 | 335 | ||
2443 | @@ -351,7 +356,7 @@ | |||
2444 | 351 | if self.logmark in line: | 356 | if self.logmark in line: |
2445 | 352 | seenmark = True | 357 | seenmark = True |
2446 | 353 | 358 | ||
2448 | 354 | self.debug_logger.debug('read_log: seenmark = %s' %seenmark) | 359 | self.debug_logger.debug('read_log: seenmark = %s' % seenmark) |
2449 | 355 | if not seenmark: | 360 | if not seenmark: |
2450 | 356 | continue | 361 | continue |
2451 | 357 | 362 | ||
2452 | @@ -382,7 +387,6 @@ | |||
2453 | 382 | return True | 387 | return True |
2454 | 383 | return False | 388 | return False |
2455 | 384 | 389 | ||
2456 | 385 | |||
2457 | 386 | def get_profile_filename(self, profile): | 390 | def get_profile_filename(self, profile): |
2458 | 387 | """Returns the full profile name""" | 391 | """Returns the full profile name""" |
2459 | 388 | if profile.startswith('/'): | 392 | if profile.startswith('/'): |
2460 | @@ -392,4 +396,4 @@ | |||
2461 | 392 | profile = "profile_" + profile | 396 | profile = "profile_" + profile |
2462 | 393 | profile = profile.replace('/', '.') | 397 | profile = profile.replace('/', '.') |
2463 | 394 | full_profilename = self.profile_dir + '/' + profile | 398 | full_profilename = self.profile_dir + '/' + profile |
2464 | 395 | return full_profilename | ||
2465 | 396 | \ No newline at end of file | 399 | \ No newline at end of file |
2466 | 400 | return full_profilename | ||
2467 | 397 | 401 | ||
2468 | === modified file 'apparmor/severity.py' | |||
2469 | --- apparmor/severity.py 2014-02-01 00:44:05 +0000 | |||
2470 | +++ apparmor/severity.py 2014-02-12 00:39:55 +0000 | |||
2471 | @@ -14,7 +14,7 @@ | |||
2472 | 14 | from __future__ import with_statement | 14 | from __future__ import with_statement |
2473 | 15 | import os | 15 | import os |
2474 | 16 | import re | 16 | import re |
2476 | 17 | from apparmor.common import AppArmorException, open_file_read, warn, convert_regexp #, msg, error, debug | 17 | from apparmor.common import AppArmorException, open_file_read, warn, convert_regexp # , msg, error, debug |
2477 | 18 | 18 | ||
2478 | 19 | class Severity(object): | 19 | class Severity(object): |
2479 | 20 | def __init__(self, dbname=None, default_rank=10): | 20 | def __init__(self, dbname=None, default_rank=10): |
2480 | @@ -31,10 +31,10 @@ | |||
2481 | 31 | if not dbname: | 31 | if not dbname: |
2482 | 32 | return None | 32 | return None |
2483 | 33 | 33 | ||
2485 | 34 | with open_file_read(dbname) as database:#open(dbname, 'r') | 34 | with open_file_read(dbname) as database: # open(dbname, 'r') |
2486 | 35 | for lineno, line in enumerate(database, start=1): | 35 | for lineno, line in enumerate(database, start=1): |
2489 | 36 | line = line.strip() # or only rstrip and lstrip? | 36 | line = line.strip() # or only rstrip and lstrip? |
2490 | 37 | if line == '' or line.startswith('#') : | 37 | if line == '' or line.startswith('#'): |
2491 | 38 | continue | 38 | continue |
2492 | 39 | if line.startswith('/'): | 39 | if line.startswith('/'): |
2493 | 40 | try: | 40 | try: |
2494 | @@ -43,7 +43,7 @@ | |||
2495 | 43 | except ValueError: | 43 | except ValueError: |
2496 | 44 | raise AppArmorException("Insufficient values for permissions in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) | 44 | raise AppArmorException("Insufficient values for permissions in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) |
2497 | 45 | else: | 45 | else: |
2499 | 46 | if read not in range(0, 11) or write not in range(0,11) or execute not in range(0,11): | 46 | if read not in range(0, 11) or write not in range(0, 11) or execute not in range(0, 11): |
2500 | 47 | raise AppArmorException("Inappropriate values for permissions in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) | 47 | raise AppArmorException("Inappropriate values for permissions in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) |
2501 | 48 | path = path.lstrip('/') | 48 | path = path.lstrip('/') |
2502 | 49 | if '*' not in path: | 49 | if '*' not in path: |
2503 | @@ -67,7 +67,7 @@ | |||
2504 | 67 | except ValueError as e: | 67 | except ValueError as e: |
2505 | 68 | error_message = 'No severity value present in file: %s\n\t[Line %s]: %s' % (dbname, lineno, line) | 68 | error_message = 'No severity value present in file: %s\n\t[Line %s]: %s' % (dbname, lineno, line) |
2506 | 69 | #error(error_message) | 69 | #error(error_message) |
2508 | 70 | raise AppArmorException(error_message) # from None | 70 | raise AppArmorException(error_message) # from None |
2509 | 71 | else: | 71 | else: |
2510 | 72 | if severity not in range(0, 11): | 72 | if severity not in range(0, 11): |
2511 | 73 | raise AppArmorException("Inappropriate severity value present in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) | 73 | raise AppArmorException("Inappropriate severity value present in file: %s\n\t[Line %s]: %s" % (dbname, lineno, line)) |
2512 | @@ -83,7 +83,6 @@ | |||
2513 | 83 | warn("unknown capability: %s" % resource) | 83 | warn("unknown capability: %s" % resource) |
2514 | 84 | return self.severity['DEFAULT_RANK'] | 84 | return self.severity['DEFAULT_RANK'] |
2515 | 85 | 85 | ||
2516 | 86 | |||
2517 | 87 | def check_subtree(self, tree, mode, sev, segments): | 86 | def check_subtree(self, tree, mode, sev, segments): |
2518 | 88 | """Returns the max severity from the regex tree""" | 87 | """Returns the max severity from the regex tree""" |
2519 | 89 | if len(segments) == 0: | 88 | if len(segments) == 0: |
2520 | @@ -91,21 +90,21 @@ | |||
2521 | 91 | else: | 90 | else: |
2522 | 92 | first = segments[0] | 91 | first = segments[0] |
2523 | 93 | rest = segments[1:] | 92 | rest = segments[1:] |
2525 | 94 | path = '/'.join([first]+rest) | 93 | path = '/'.join([first] + rest) |
2526 | 95 | # Check if we have a matching directory tree to descend into | 94 | # Check if we have a matching directory tree to descend into |
2527 | 96 | if tree.get(first, False): | 95 | if tree.get(first, False): |
2528 | 97 | sev = self.check_subtree(tree[first], mode, sev, rest) | 96 | sev = self.check_subtree(tree[first], mode, sev, rest) |
2529 | 98 | # If severity still not found, match against globs | 97 | # If severity still not found, match against globs |
2531 | 99 | if sev == None: | 98 | if sev is None: |
2532 | 100 | # Match against all globs at this directory level | 99 | # Match against all globs at this directory level |
2533 | 101 | for chunk in tree.keys(): | 100 | for chunk in tree.keys(): |
2534 | 102 | if '*' in chunk: | 101 | if '*' in chunk: |
2535 | 103 | # Match rest of the path | 102 | # Match rest of the path |
2537 | 104 | if re.search("^"+chunk, path): | 103 | if re.search("^" + chunk, path): |
2538 | 105 | # Find max rank | 104 | # Find max rank |
2539 | 106 | if "AA_RANK" in tree[chunk].keys(): | 105 | if "AA_RANK" in tree[chunk].keys(): |
2540 | 107 | for m in mode: | 106 | for m in mode: |
2542 | 108 | if sev == None or tree[chunk]["AA_RANK"].get(m, -1) > sev: | 107 | if sev is None or tree[chunk]["AA_RANK"].get(m, -1) > sev: |
2543 | 109 | sev = tree[chunk]["AA_RANK"].get(m, None) | 108 | sev = tree[chunk]["AA_RANK"].get(m, None) |
2544 | 110 | return sev | 109 | return sev |
2545 | 111 | 110 | ||
2546 | @@ -118,12 +117,12 @@ | |||
2547 | 118 | if resource in self.severity['FILES'].keys(): | 117 | if resource in self.severity['FILES'].keys(): |
2548 | 119 | # Find max value among the given modes | 118 | # Find max value among the given modes |
2549 | 120 | for m in mode: | 119 | for m in mode: |
2551 | 121 | if sev == None or self.severity['FILES'][resource].get(m, -1) > sev: | 120 | if sev is None or self.severity['FILES'][resource].get(m, -1) > sev: |
2552 | 122 | sev = self.severity['FILES'][resource].get(m, None) | 121 | sev = self.severity['FILES'][resource].get(m, None) |
2553 | 123 | else: | 122 | else: |
2554 | 124 | # Search regex tree for matching glob | 123 | # Search regex tree for matching glob |
2555 | 125 | sev = self.check_subtree(self.severity['REGEXPS'], mode, sev, pieces) | 124 | sev = self.check_subtree(self.severity['REGEXPS'], mode, sev, pieces) |
2557 | 126 | if sev == None: | 125 | if sev is None: |
2558 | 127 | # Return default rank if severity cannot be found | 126 | # Return default rank if severity cannot be found |
2559 | 128 | return self.severity['DEFAULT_RANK'] | 127 | return self.severity['DEFAULT_RANK'] |
2560 | 129 | else: | 128 | else: |
2561 | @@ -146,13 +145,13 @@ | |||
2562 | 146 | rank = None | 145 | rank = None |
2563 | 147 | if '@' in resource: | 146 | if '@' in resource: |
2564 | 148 | variable = regex_variable.search(resource).groups()[0] | 147 | variable = regex_variable.search(resource).groups()[0] |
2566 | 149 | variable = '@{'+variable+'}' | 148 | variable = '@{%s}' % variable |
2567 | 150 | #variables = regex_variable.findall(resource) | 149 | #variables = regex_variable.findall(resource) |
2568 | 151 | for replacement in self.severity['VARIABLES'][variable]: | 150 | for replacement in self.severity['VARIABLES'][variable]: |
2569 | 152 | resource_replaced = self.variable_replace(variable, replacement, resource) | 151 | resource_replaced = self.variable_replace(variable, replacement, resource) |
2570 | 153 | rank_new = self.handle_variable_rank(resource_replaced, mode) | 152 | rank_new = self.handle_variable_rank(resource_replaced, mode) |
2571 | 154 | #rank_new = self.handle_variable_rank(resource.replace('@{'+variable+'}', replacement), mode) | 153 | #rank_new = self.handle_variable_rank(resource.replace('@{'+variable+'}', replacement), mode) |
2573 | 155 | if rank == None or rank_new > rank: | 154 | if rank is None or rank_new > rank: |
2574 | 156 | rank = rank_new | 155 | rank = rank_new |
2575 | 157 | return rank | 156 | return rank |
2576 | 158 | else: | 157 | else: |
2577 | @@ -163,13 +162,13 @@ | |||
2578 | 163 | leading = False | 162 | leading = False |
2579 | 164 | trailing = False | 163 | trailing = False |
2580 | 165 | # Check for leading or trailing / that may need to be collapsed | 164 | # Check for leading or trailing / that may need to be collapsed |
2582 | 166 | if resource.find("/"+variable) != -1 and resource.find("//"+variable) == -1: # find that a single / exists before variable or not | 165 | if resource.find("/" + variable) != -1 and resource.find("//" + variable) == -1: # find that a single / exists before variable or not |
2583 | 167 | leading = True | 166 | leading = True |
2585 | 168 | if resource.find(variable+"/") != -1 and resource.find(variable+"//") == -1: | 167 | if resource.find(variable + "/") != -1 and resource.find(variable + "//") == -1: |
2586 | 169 | trailing = True | 168 | trailing = True |
2588 | 170 | if replacement[0] == '/' and replacement[:2] != '//' and leading: # finds if the replacement has leading / or not | 169 | if replacement[0] == '/' and replacement[:2] != '//' and leading: # finds if the replacement has leading / or not |
2589 | 171 | replacement = replacement[1:] | 170 | replacement = replacement[1:] |
2591 | 172 | if replacement[-1] == '/' and replacement[-2:] !='//' and trailing: | 171 | if replacement[-1] == '/' and replacement[-2:] != '//' and trailing: |
2592 | 173 | replacement = replacement[:-1] | 172 | replacement = replacement[:-1] |
2593 | 174 | return resource.replace(variable, replacement) | 173 | return resource.replace(variable, replacement) |
2594 | 175 | 174 | ||
2595 | 176 | 175 | ||
2596 | === modified file 'apparmor/tools.py' | |||
2597 | --- apparmor/tools.py 2014-02-01 01:34:08 +0000 | |||
2598 | +++ apparmor/tools.py 2014-02-12 00:39:55 +0000 | |||
2599 | @@ -11,12 +11,17 @@ | |||
2600 | 11 | # GNU General Public License for more details. | 11 | # GNU General Public License for more details. |
2601 | 12 | # | 12 | # |
2602 | 13 | # ---------------------------------------------------------------------- | 13 | # ---------------------------------------------------------------------- |
2603 | 14 | import gettext | ||
2604 | 14 | import os | 15 | import os |
2605 | 15 | import sys | 16 | import sys |
2606 | 16 | 17 | ||
2607 | 17 | import apparmor.aa as apparmor | 18 | import apparmor.aa as apparmor |
2608 | 18 | from apparmor.common import user_perm | 19 | from apparmor.common import user_perm |
2609 | 19 | 20 | ||
2610 | 21 | # setup module translations | ||
2611 | 22 | from apparmor.translations import init_translation | ||
2612 | 23 | _ = init_translation() | ||
2613 | 24 | |||
2614 | 20 | class aa_tools: | 25 | class aa_tools: |
2615 | 21 | def __init__(self, tool_name, args): | 26 | def __init__(self, tool_name, args): |
2616 | 22 | self.name = tool_name | 27 | self.name = tool_name |
2617 | @@ -24,12 +29,12 @@ | |||
2618 | 24 | self.profiling = args.program | 29 | self.profiling = args.program |
2619 | 25 | self.check_profile_dir() | 30 | self.check_profile_dir() |
2620 | 26 | self.silent = None | 31 | self.silent = None |
2622 | 27 | 32 | ||
2623 | 28 | if tool_name in ['audit', 'complain']: | 33 | if tool_name in ['audit', 'complain']: |
2624 | 29 | self.remove = args.remove | 34 | self.remove = args.remove |
2625 | 30 | elif tool_name == 'disable': | 35 | elif tool_name == 'disable': |
2626 | 31 | self.revert = args.revert | 36 | self.revert = args.revert |
2628 | 32 | self.disabledir = apparmor.profile_dir+'/disable' | 37 | self.disabledir = apparmor.profile_dir + '/disable' |
2629 | 33 | self.check_disable_dir() | 38 | self.check_disable_dir() |
2630 | 34 | elif tool_name == 'autodep': | 39 | elif tool_name == 'autodep': |
2631 | 35 | self.force = args.force | 40 | self.force = args.force |
2632 | @@ -41,14 +46,14 @@ | |||
2633 | 41 | if self.profiledir: | 46 | if self.profiledir: |
2634 | 42 | apparmor.profile_dir = apparmor.get_full_path(self.profiledir) | 47 | apparmor.profile_dir = apparmor.get_full_path(self.profiledir) |
2635 | 43 | if not os.path.isdir(apparmor.profile_dir): | 48 | if not os.path.isdir(apparmor.profile_dir): |
2637 | 44 | raise apparmor.AppArmorException("%s is not a directory." %self.profiledir) | 49 | raise apparmor.AppArmorException("%s is not a directory." % self.profiledir) |
2638 | 45 | 50 | ||
2639 | 46 | if not user_perm(apparmor.profile_dir): | 51 | if not user_perm(apparmor.profile_dir): |
2641 | 47 | raise apparmor.AppArmorException("Cannot write to profile directory: %s" %(apparmor.profile_dir)) | 52 | raise apparmor.AppArmorException("Cannot write to profile directory: %s" % (apparmor.profile_dir)) |
2642 | 48 | 53 | ||
2643 | 49 | def check_disable_dir(self): | 54 | def check_disable_dir(self): |
2644 | 50 | if not os.path.isdir(self.disabledir): | 55 | if not os.path.isdir(self.disabledir): |
2646 | 51 | raise apparmor.AppArmorException("Can't find AppArmor disable directory %s" %self.disabledir) | 56 | raise apparmor.AppArmorException("Can't find AppArmor disable directory %s" % self.disabledir) |
2647 | 52 | 57 | ||
2648 | 53 | def act(self): | 58 | def act(self): |
2649 | 54 | for p in self.profiling: | 59 | for p in self.profiling: |
2650 | @@ -72,12 +77,12 @@ | |||
2651 | 72 | if program and not program.startswith('/'): | 77 | if program and not program.startswith('/'): |
2652 | 73 | program = apparmor.UI_GetString(_('The given program cannot be found, please try with the fully qualified path name of the program: '), '') | 78 | program = apparmor.UI_GetString(_('The given program cannot be found, please try with the fully qualified path name of the program: '), '') |
2653 | 74 | else: | 79 | else: |
2655 | 75 | apparmor.UI_Info(_("%s does not exist, please double-check the path.")%p) | 80 | apparmor.UI_Info(_("%s does not exist, please double-check the path.") % p) |
2656 | 76 | sys.exit(1) | 81 | sys.exit(1) |
2657 | 77 | 82 | ||
2658 | 78 | if self.name == 'autodep' and program and os.path.exists(program): | 83 | if self.name == 'autodep' and program and os.path.exists(program): |
2659 | 79 | self.use_autodep(program) | 84 | self.use_autodep(program) |
2661 | 80 | 85 | ||
2662 | 81 | elif program and apparmor.profile_exists(program): | 86 | elif program and apparmor.profile_exists(program): |
2663 | 82 | if self.name == 'cleanprof': | 87 | if self.name == 'cleanprof': |
2664 | 83 | self.clean_profile(program, p) | 88 | self.clean_profile(program, p) |
2665 | @@ -86,21 +91,21 @@ | |||
2666 | 86 | filename = apparmor.get_profile_filename(program) | 91 | filename = apparmor.get_profile_filename(program) |
2667 | 87 | 92 | ||
2668 | 88 | if not os.path.isfile(filename) or apparmor.is_skippable_file(filename): | 93 | if not os.path.isfile(filename) or apparmor.is_skippable_file(filename): |
2670 | 89 | apparmor.UI_Info(_('Profile for %s not found, skipping')%p) | 94 | apparmor.UI_Info(_('Profile for %s not found, skipping') % p) |
2671 | 90 | 95 | ||
2672 | 91 | elif self.name == 'disable': | 96 | elif self.name == 'disable': |
2673 | 92 | if not self.revert: | 97 | if not self.revert: |
2675 | 93 | apparmor.UI_Info(_('Disabling %s.')%program) | 98 | apparmor.UI_Info(_('Disabling %s.') % program) |
2676 | 94 | self.disable_profile(filename) | 99 | self.disable_profile(filename) |
2677 | 95 | else: | 100 | else: |
2679 | 96 | apparmor.UI_Info(_('Enabling %s.')%program) | 101 | apparmor.UI_Info(_('Enabling %s.') % program) |
2680 | 97 | self.enable_profile(filename) | 102 | self.enable_profile(filename) |
2681 | 98 | 103 | ||
2682 | 99 | elif self.name == 'audit': | 104 | elif self.name == 'audit': |
2683 | 100 | if not self.remove: | 105 | if not self.remove: |
2685 | 101 | apparmor.UI_Info(_('Setting %s to audit mode.')%program) | 106 | apparmor.UI_Info(_('Setting %s to audit mode.') % program) |
2686 | 102 | else: | 107 | else: |
2688 | 103 | apparmor.UI_Info(_('Removing audit mode from %s.')%program) | 108 | apparmor.UI_Info(_('Removing audit mode from %s.') % program) |
2689 | 104 | apparmor.change_profile_flags(filename, program, 'audit', not self.remove) | 109 | apparmor.change_profile_flags(filename, program, 'audit', not self.remove) |
2690 | 105 | 110 | ||
2691 | 106 | elif self.name == 'complain': | 111 | elif self.name == 'complain': |
2692 | @@ -111,9 +116,9 @@ | |||
2693 | 111 | #apparmor.set_profile_flags(filename, self.name) | 116 | #apparmor.set_profile_flags(filename, self.name) |
2694 | 112 | else: | 117 | else: |
2695 | 113 | # One simply does not walk in here! | 118 | # One simply does not walk in here! |
2697 | 114 | raise apparmor.AppArmorException('Unknown tool: %s'%self.name) | 119 | raise apparmor.AppArmorException('Unknown tool: %s' % self.name) |
2698 | 115 | 120 | ||
2700 | 116 | cmd_info = apparmor.cmd([apparmor.parser, filename, '-I%s'%apparmor.profile_dir, '-R 2>&1', '1>/dev/null']) | 121 | cmd_info = apparmor.cmd([apparmor.parser, filename, '-I%s' % apparmor.profile_dir, '-R 2>&1', '1>/dev/null']) |
2701 | 117 | #cmd_info = apparmor.cmd(['cat', filename, '|', apparmor.parser, '-I%s'%apparmor.profile_dir, '-R 2>&1', '1>/dev/null']) | 122 | #cmd_info = apparmor.cmd(['cat', filename, '|', apparmor.parser, '-I%s'%apparmor.profile_dir, '-R 2>&1', '1>/dev/null']) |
2702 | 118 | 123 | ||
2703 | 119 | if cmd_info[0] != 0: | 124 | if cmd_info[0] != 0: |
2704 | @@ -121,9 +126,9 @@ | |||
2705 | 121 | 126 | ||
2706 | 122 | else: | 127 | else: |
2707 | 123 | if '/' not in p: | 128 | if '/' not in p: |
2709 | 124 | apparmor.UI_Info(_("Can't find %s in the system path list. If the name of the application\nis correct, please run 'which %s' as a user with correct PATH\nenvironment set up in order to find the fully-qualified path and\nuse the full path as parameter.")%(p, p)) | 129 | apparmor.UI_Info(_("Can't find %s in the system path list. If the name of the application\nis correct, please run 'which %s' as a user with correct PATH\nenvironment set up in order to find the fully-qualified path and\nuse the full path as parameter.") % (p, p)) |
2710 | 125 | else: | 130 | else: |
2712 | 126 | apparmor.UI_Info(_("%s does not exist, please double-check the path.")%p) | 131 | apparmor.UI_Info(_("%s does not exist, please double-check the path.") % p) |
2713 | 127 | sys.exit(1) | 132 | sys.exit(1) |
2714 | 128 | 133 | ||
2715 | 129 | def clean_profile(self, program, p): | 134 | def clean_profile(self, program, p): |
2716 | @@ -140,12 +145,12 @@ | |||
2717 | 140 | q = apparmor.hasher() | 145 | q = apparmor.hasher() |
2718 | 141 | q['title'] = 'Changed Local Profiles' | 146 | q['title'] = 'Changed Local Profiles' |
2719 | 142 | q['headers'] = [] | 147 | q['headers'] = [] |
2721 | 143 | q['explanation'] = _('The local profile for %s in file %s was changed. Would you like to save it?') %(program, filename) | 148 | q['explanation'] = _('The local profile for %s in file %s was changed. Would you like to save it?') % (program, filename) |
2722 | 144 | q['functions'] = ['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT'] | 149 | q['functions'] = ['CMD_SAVE_CHANGES', 'CMD_VIEW_CHANGES', 'CMD_ABORT'] |
2723 | 145 | q['default'] = 'CMD_VIEW_CHANGES' | 150 | q['default'] = 'CMD_VIEW_CHANGES' |
2724 | 146 | q['options'] = [] | 151 | q['options'] = [] |
2725 | 147 | q['selected'] = 0 | 152 | q['selected'] = 0 |
2727 | 148 | p =None | 153 | p = None |
2728 | 149 | ans = '' | 154 | ans = '' |
2729 | 150 | arg = None | 155 | arg = None |
2730 | 151 | while ans != 'CMD_SAVE_CHANGES': | 156 | while ans != 'CMD_SAVE_CHANGES': |
2731 | @@ -161,13 +166,13 @@ | |||
2732 | 161 | apparmor.write_profile_ui_feedback(program) | 166 | apparmor.write_profile_ui_feedback(program) |
2733 | 162 | apparmor.reload_base(program) | 167 | apparmor.reload_base(program) |
2734 | 163 | else: | 168 | else: |
2736 | 164 | raise apparmor.AppArmorException(_('The profile for %s does not exists. Nothing to clean.')%p) | 169 | raise apparmor.AppArmorException(_('The profile for %s does not exists. Nothing to clean.') % p) |
2737 | 165 | 170 | ||
2738 | 166 | def use_autodep(self, program): | 171 | def use_autodep(self, program): |
2739 | 167 | apparmor.check_qualifiers(program) | 172 | apparmor.check_qualifiers(program) |
2740 | 168 | 173 | ||
2741 | 169 | if os.path.exists(apparmor.get_profile_filename(program) and not self.force): | 174 | if os.path.exists(apparmor.get_profile_filename(program) and not self.force): |
2743 | 170 | apparmor.UI_Info('Profile for %s already exists - skipping.'%program) | 175 | apparmor.UI_Info('Profile for %s already exists - skipping.' % program) |
2744 | 171 | else: | 176 | else: |
2745 | 172 | apparmor.autodep(program) | 177 | apparmor.autodep(program) |
2746 | 173 | if self.aa_mountpoint: | 178 | if self.aa_mountpoint: |
2747 | @@ -177,4 +182,4 @@ | |||
2748 | 177 | apparmor.delete_symlink('disable', filename) | 182 | apparmor.delete_symlink('disable', filename) |
2749 | 178 | 183 | ||
2750 | 179 | def disable_profile(self, filename): | 184 | def disable_profile(self, filename): |
2751 | 180 | apparmor.create_symlink('disable', filename) | ||
2752 | 181 | \ No newline at end of file | 185 | \ No newline at end of file |
2753 | 186 | apparmor.create_symlink('disable', filename) | ||
2754 | 182 | 187 | ||
2755 | === modified file 'apparmor/ui.py' | |||
2756 | --- apparmor/ui.py 2014-02-01 00:44:05 +0000 | |||
2757 | +++ apparmor/ui.py 2014-02-12 00:39:55 +0000 | |||
2758 | @@ -11,12 +11,16 @@ | |||
2759 | 11 | # GNU General Public License for more details. | 11 | # GNU General Public License for more details. |
2760 | 12 | # | 12 | # |
2761 | 13 | # ---------------------------------------------------------------------- | 13 | # ---------------------------------------------------------------------- |
2762 | 14 | import gettext | ||
2763 | 14 | import sys | 15 | import sys |
2764 | 15 | import os | ||
2765 | 16 | import re | 16 | import re |
2766 | 17 | from apparmor.yasti import yastLog, SendDataToYast, GetDataFromYast | 17 | from apparmor.yasti import yastLog, SendDataToYast, GetDataFromYast |
2767 | 18 | 18 | ||
2769 | 19 | from apparmor.common import readkey, AppArmorException, DebugLogger, msg | 19 | from apparmor.common import readkey, AppArmorException, DebugLogger |
2770 | 20 | |||
2771 | 21 | # setup module translations | ||
2772 | 22 | from apparmor.translations import init_translation | ||
2773 | 23 | _ = init_translation() | ||
2774 | 20 | 24 | ||
2775 | 21 | # Set up UI logger for separate messages from UI module | 25 | # Set up UI logger for separate messages from UI module |
2776 | 22 | debug_logger = DebugLogger('UI') | 26 | debug_logger = DebugLogger('UI') |
2777 | @@ -48,14 +52,13 @@ | |||
2778 | 48 | if UI_mode == 'text': | 52 | if UI_mode == 'text': |
2779 | 49 | sys.stdout.write('\n' + text + '\n') | 53 | sys.stdout.write('\n' + text + '\n') |
2780 | 50 | else: | 54 | else: |
2783 | 51 | SendDataToYast({ | 55 | SendDataToYast({'type': 'dialog-error', |
2782 | 52 | 'type': 'dialog-error', | ||
2784 | 53 | 'message': text | 56 | 'message': text |
2785 | 54 | }) | 57 | }) |
2786 | 55 | path, yarg = GetDataFromYast() | 58 | path, yarg = GetDataFromYast() |
2787 | 56 | 59 | ||
2788 | 57 | def get_translated_hotkey(translated, cmsg=''): | 60 | def get_translated_hotkey(translated, cmsg=''): |
2790 | 58 | msg = 'PromptUser: '+_('Invalid hotkey for') | 61 | msg = 'PromptUser: ' + _('Invalid hotkey for') |
2791 | 59 | 62 | ||
2792 | 60 | # Originally (\S) was used but with translations it would not work :( | 63 | # Originally (\S) was used but with translations it would not work :( |
2793 | 61 | if re.search('\((\S+)\)', translated, re.LOCALE): | 64 | if re.search('\((\S+)\)', translated, re.LOCALE): |
2794 | @@ -64,10 +67,10 @@ | |||
2795 | 64 | if cmsg: | 67 | if cmsg: |
2796 | 65 | raise AppArmorException(cmsg) | 68 | raise AppArmorException(cmsg) |
2797 | 66 | else: | 69 | else: |
2799 | 67 | raise AppArmorException('%s %s' %(msg, translated)) | 70 | raise AppArmorException('%s %s' % (msg, translated)) |
2800 | 68 | 71 | ||
2801 | 69 | def UI_YesNo(text, default): | 72 | def UI_YesNo(text, default): |
2803 | 70 | debug_logger.debug('UI_YesNo: %s: %s %s' %(UI_mode, text, default)) | 73 | debug_logger.debug('UI_YesNo: %s: %s %s' % (UI_mode, text, default)) |
2804 | 71 | default = default.lower() | 74 | default = default.lower() |
2805 | 72 | ans = None | 75 | ans = None |
2806 | 73 | if UI_mode == 'text': | 76 | if UI_mode == 'text': |
2807 | @@ -101,10 +104,9 @@ | |||
2808 | 101 | ans = default | 104 | ans = default |
2809 | 102 | 105 | ||
2810 | 103 | else: | 106 | else: |
2815 | 104 | SendDataToYast({ | 107 | SendDataToYast({'type': 'dialog-yesno', |
2816 | 105 | 'type': 'dialog-yesno', | 108 | 'question': text |
2817 | 106 | 'question': text | 109 | }) |
2814 | 107 | }) | ||
2818 | 108 | ypath, yarg = GetDataFromYast() | 110 | ypath, yarg = GetDataFromYast() |
2819 | 109 | ans = yarg['answer'] | 111 | ans = yarg['answer'] |
2820 | 110 | if not ans: | 112 | if not ans: |
2821 | @@ -142,7 +144,7 @@ | |||
2822 | 142 | elif ans == nokey: | 144 | elif ans == nokey: |
2823 | 143 | ans = 'n' | 145 | ans = 'n' |
2824 | 144 | elif ans == cancelkey: | 146 | elif ans == cancelkey: |
2826 | 145 | ans= 'c' | 147 | ans = 'c' |
2827 | 146 | elif ans == 'left': | 148 | elif ans == 'left': |
2828 | 147 | if default == 'n': | 149 | if default == 'n': |
2829 | 148 | default = 'y' | 150 | default = 'y' |
2830 | @@ -156,8 +158,7 @@ | |||
2831 | 156 | else: | 158 | else: |
2832 | 157 | ans = default | 159 | ans = default |
2833 | 158 | else: | 160 | else: |
2836 | 159 | SendDataToYast({ | 161 | SendDataToYast({'type': 'dialog-yesnocancel', |
2835 | 160 | 'type': 'dialog-yesnocancel', | ||
2837 | 161 | 'question': text | 162 | 'question': text |
2838 | 162 | }) | 163 | }) |
2839 | 163 | ypath, yarg = GetDataFromYast() | 164 | ypath, yarg = GetDataFromYast() |
2840 | @@ -173,8 +174,7 @@ | |||
2841 | 173 | sys.stdout.write('\n' + text) | 174 | sys.stdout.write('\n' + text) |
2842 | 174 | string = sys.stdin.readline() | 175 | string = sys.stdin.readline() |
2843 | 175 | else: | 176 | else: |
2846 | 176 | SendDataToYast({ | 177 | SendDataToYast({'type': 'dialog-getstring', |
2845 | 177 | 'type': 'dialog-getstring', | ||
2847 | 178 | 'label': text, | 178 | 'label': text, |
2848 | 179 | 'default': default | 179 | 'default': default |
2849 | 180 | }) | 180 | }) |
2850 | @@ -201,8 +201,7 @@ | |||
2851 | 201 | if UI_mode == 'text': | 201 | if UI_mode == 'text': |
2852 | 202 | UI_Info(message) | 202 | UI_Info(message) |
2853 | 203 | else: | 203 | else: |
2856 | 204 | SendDataToYast({ | 204 | SendDataToYast({'type': 'dialog-busy-start', |
2855 | 205 | 'type': 'dialog-busy-start', | ||
2857 | 206 | 'message': message | 205 | 'message': message |
2858 | 207 | }) | 206 | }) |
2859 | 208 | ypath, yarg = GetDataFromYast() | 207 | ypath, yarg = GetDataFromYast() |
2860 | @@ -213,8 +212,7 @@ | |||
2861 | 213 | SendDataToYast({'type': 'dialog-busy-stop'}) | 212 | SendDataToYast({'type': 'dialog-busy-stop'}) |
2862 | 214 | ypath, yarg = GetDataFromYast() | 213 | ypath, yarg = GetDataFromYast() |
2863 | 215 | 214 | ||
2866 | 216 | CMDS = { | 215 | CMDS = {'CMD_ALLOW': _('(A)llow'), |
2865 | 217 | 'CMD_ALLOW': _('(A)llow'), | ||
2867 | 218 | 'CMD_OTHER': _('(M)ore'), | 216 | 'CMD_OTHER': _('(M)ore'), |
2868 | 219 | 'CMD_AUDIT_NEW': _('Audi(t)'), | 217 | 'CMD_AUDIT_NEW': _('Audi(t)'), |
2869 | 220 | 'CMD_AUDIT_OFF': _('Audi(t) off'), | 218 | 'CMD_AUDIT_OFF': _('Audi(t) off'), |
2870 | @@ -307,16 +305,14 @@ | |||
2871 | 307 | sys.exit(0) | 305 | sys.exit(0) |
2872 | 308 | 306 | ||
2873 | 309 | def UI_ShortMessage(title, message): | 307 | def UI_ShortMessage(title, message): |
2876 | 310 | SendDataToYast({ | 308 | SendDataToYast({'type': 'short-dialog-message', |
2875 | 311 | 'type': 'short-dialog-message', | ||
2877 | 312 | 'headline': title, | 309 | 'headline': title, |
2878 | 313 | 'message': message | 310 | 'message': message |
2879 | 314 | }) | 311 | }) |
2880 | 315 | ypath, yarg = GetDataFromYast() | 312 | ypath, yarg = GetDataFromYast() |
2881 | 316 | 313 | ||
2882 | 317 | def UI_LongMessage(title, message): | 314 | def UI_LongMessage(title, message): |
2885 | 318 | SendDataToYast({ | 315 | SendDataToYast({'type': 'long-dialog-message', |
2884 | 319 | 'type': 'long-dialog-message', | ||
2886 | 320 | 'headline': title, | 316 | 'headline': title, |
2887 | 321 | 'message': message | 317 | 'message': message |
2888 | 322 | }) | 318 | }) |
2889 | @@ -356,7 +352,7 @@ | |||
2890 | 356 | keys[key] = cmd | 352 | keys[key] = cmd |
2891 | 357 | 353 | ||
2892 | 358 | if default and default == cmd: | 354 | if default and default == cmd: |
2894 | 359 | menutext = '[%s]' %menutext | 355 | menutext = '[%s]' % menutext |
2895 | 360 | 356 | ||
2896 | 361 | menu_items.append(menutext) | 357 | menu_items.append(menutext) |
2897 | 362 | 358 | ||
2898 | @@ -392,14 +388,14 @@ | |||
2899 | 392 | 388 | ||
2900 | 393 | prompt = '\n' | 389 | prompt = '\n' |
2901 | 394 | if title: | 390 | if title: |
2903 | 395 | prompt += '= %s =\n\n' %title | 391 | prompt += '= %s =\n\n' % title |
2904 | 396 | 392 | ||
2905 | 397 | if headers: | 393 | if headers: |
2906 | 398 | header_copy = headers[:] | 394 | header_copy = headers[:] |
2907 | 399 | while header_copy: | 395 | while header_copy: |
2908 | 400 | header = header_copy.pop(0) | 396 | header = header_copy.pop(0) |
2909 | 401 | value = header_copy.pop(0) | 397 | value = header_copy.pop(0) |
2911 | 402 | prompt += formatstr %(header+':', value) | 398 | prompt += formatstr % (header + ':', value) |
2912 | 403 | prompt += '\n' | 399 | prompt += '\n' |
2913 | 404 | 400 | ||
2914 | 405 | if explanation: | 401 | if explanation: |
2915 | @@ -411,12 +407,12 @@ | |||
2916 | 411 | format_option = ' [%s - %s]' | 407 | format_option = ' [%s - %s]' |
2917 | 412 | else: | 408 | else: |
2918 | 413 | format_option = ' %s - %s ' | 409 | format_option = ' %s - %s ' |
2920 | 414 | prompt += format_option %(index+1, option) | 410 | prompt += format_option % (index + 1, option) |
2921 | 415 | prompt += '\n' | 411 | prompt += '\n' |
2922 | 416 | 412 | ||
2923 | 417 | prompt += ' / '.join(menu_items) | 413 | prompt += ' / '.join(menu_items) |
2924 | 418 | 414 | ||
2926 | 419 | sys.stdout.write(prompt+'\n') | 415 | sys.stdout.write(prompt + '\n') |
2927 | 420 | 416 | ||
2928 | 421 | ans = getkey().lower() | 417 | ans = getkey().lower() |
2929 | 422 | 418 | ||
2930 | @@ -427,7 +423,7 @@ | |||
2931 | 427 | ans = 'XXXINVALIDXXX' | 423 | ans = 'XXXINVALIDXXX' |
2932 | 428 | 424 | ||
2933 | 429 | elif ans == 'down': | 425 | elif ans == 'down': |
2935 | 430 | if options and selected < len(options)-1: | 426 | if options and selected < len(options) - 1: |
2936 | 431 | selected += 1 | 427 | selected += 1 |
2937 | 432 | ans = 'XXXINVALIDXXX' | 428 | ans = 'XXXINVALIDXXX' |
2938 | 433 | 429 | ||
2939 | @@ -446,7 +442,7 @@ | |||
2940 | 446 | ans = 'XXXINVALIDXXX' | 442 | ans = 'XXXINVALIDXXX' |
2941 | 447 | 443 | ||
2942 | 448 | if keys.get(ans, False) == 'CMD_HELP': | 444 | if keys.get(ans, False) == 'CMD_HELP': |
2944 | 449 | sys.stdout.write('\n%s\n' %helptext) | 445 | sys.stdout.write('\n%s\n' % helptext) |
2945 | 450 | ans = 'again' | 446 | ans = 'again' |
2946 | 451 | 447 | ||
2947 | 452 | if keys.get(ans, False): | 448 | if keys.get(ans, False): |
2948 | 453 | 449 | ||
2949 | === removed file 'apparmor/writeprofile.py' | |||
2950 | === modified file 'apparmor/yasti.py' | |||
2951 | --- apparmor/yasti.py 2013-09-28 15:13:06 +0000 | |||
2952 | +++ apparmor/yasti.py 2014-02-12 00:39:55 +0000 | |||
2953 | @@ -101,4 +101,3 @@ | |||
2954 | 101 | else: | 101 | else: |
2955 | 102 | ret += argref | 102 | ret += argref |
2956 | 103 | return ret | 103 | return ret |
2957 | 104 |
Hello,
Am Dienstag, 11. Februar 2014 schrieb Steve Beattie: /code.launchpad .net/~sbeattie/ apparmor- profile- tools/pre- merger +merge/ 205701
> Steve Beattie has proposed merging
> lp:~sbeattie/apparmor-profile-tools/pre-merger-cleanups into
> lp:apparmor-profile-tools.
>
> Requested reviews:
> Kshitij Gupta (kgupta8592)
>
> For more details, see:
> https:/
> -cleanups/
>
> Here are some simple cleanups in preparation for merging the new
> profile tools into trunk.
I had a look at the changes (hint: they are easier to read if you check
the individual commits, for example via the "For more details" link
above - for the pep8 commit, you might want to ignore whitespace
changes) and they all look good.
The only detail I don't like too much is that the changed translation
handling adds some lines to all aa-* tools - but that's something we
should fix with one of the next commits.
To sum it up: Kshitij, IMHO you can merge this :-)
or to say it in a more formal way:
Acked-by: Christian Boltz <email address hidden>
I'd recommend to merge it _before_ commiting my patches - Steve's
changes affect more lines, which also means the risk of merge conflicts
is quite big if you commit my patches first.
Regards,
Christian Boltz
--
Unix: Alles ist ein File, und was kein File ist, hat sich gefaelligst
als ein solches zu tarnen. [Wolfgang Weisselberg in linux-liste]