20
from apparmor.aa import available_buttons, combine_name, delete_duplicates, is_known_rule, match_includes
20
21
import apparmor.aamode
22
from apparmor.common import AppArmorException
23
from apparmor.regex import re_match_include
21
24
import apparmor.severity
22
25
import apparmor.cleanprofile as cleanprofile
23
26
import apparmor.ui as aaui
28
# setup exception handling
29
from apparmor.fail import enable_aa_exception_handler
30
enable_aa_exception_handler()
25
32
# setup module translations
26
33
from apparmor.translations import init_translation
27
34
_ = init_translation()
307
317
elif ans == 'CMD_FINISHED':
310
#Add the capabilities
311
for allow in ['allow', 'deny']:
312
if other.aa[profile][hat].get(allow, False):
314
for capability in sorted(other.aa[profile][hat][allow]['capability'].keys()):
315
severity = sev_db.rank('CAP_%s' % capability)
318
newincludes = apparmor.aa.match_cap_includes(self.user.aa[profile][hat], capability)
319
q = aaui.PromptQuestion()
321
options += list(map(lambda inc: '#include <%s>' %inc, sorted(set(newincludes))))
324
options.append('capability %s' % capability)
326
q.selected = default_option - 1
328
q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
329
q.headers += [_('Capability'), capability]
330
q.headers += [_('Severity'), severity]
334
q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_ABORT', 'CMD_FINISHED']
336
q.default = 'CMD_ALLOW'
340
ans, selected = q.promptUser()
341
# Ignore the log entry
342
if ans == 'CMD_IGNORE_ENTRY':
346
elif ans == 'CMD_FINISHED':
349
if ans == 'CMD_ALLOW':
352
selection = options[selected]
353
match = apparmor.aa.re_match_include(selection)
357
deleted = apparmor.aa.delete_duplicates(self.user.aa[profile][hat], inc)
358
self.user.aa[profile][hat]['include'][inc] = True
360
aaui.UI_Info(_('Adding %s to profile.') % selection)
362
aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted)
364
self.user.aa[profile][hat]['allow']['capability'][capability]['set'] = True
365
self.user.aa[profile][hat]['allow']['capability'][capability]['audit'] = other.aa[profile][hat]['allow']['capability'][capability]['audit']
367
apparmor.aa.changed[profile] = True
369
aaui.UI_Info(_('Adding capability %s to profile.'), capability)
372
elif ans == 'CMD_DENY':
373
self.user.aa[profile][hat]['deny']['capability'][capability]['set'] = True
374
apparmor.aa.changed[profile] = True
376
aaui.UI_Info(_('Denying capability %s to profile.') % capability)
381
320
# Process all the path entries.
382
321
for allow in ['allow', 'deny']:
383
322
for path in sorted(other.aa[profile][hat][allow]['path'].keys()):
384
323
#print(path, other.aa[profile][hat][allow]['path'][path])
385
324
mode = other.aa[profile][hat][allow]['path'][path]['mode']
387
if self.user.aa[profile][hat][allow]['path'].get(path, False):
388
mode = self.conflict_mode(profile, hat, allow, path, 'mode', other.aa[profile][hat][allow]['path'][path]['mode'], self.user.aa[profile][hat][allow]['path'][path]['mode'])
389
self.conflict_mode(profile, hat, allow, path, 'audit', other.aa[profile][hat][allow]['path'][path]['audit'], self.user.aa[profile][hat][allow]['path'][path]['audit'])
390
apparmor.aa.changed[profile] = True
326
if aa[profile][hat][allow]['path'].get(path, False):
327
mode = self.conflict_mode(profile, hat, allow, path, 'mode', other.aa[profile][hat][allow]['path'][path]['mode'], aa[profile][hat][allow]['path'][path]['mode'])
328
self.conflict_mode(profile, hat, allow, path, 'audit', other.aa[profile][hat][allow]['path'][path]['audit'], aa[profile][hat][allow]['path'][path]['audit'])
329
changed[profile] = True
392
331
# Lookup modes from profile
393
332
allow_mode = set()
395
334
deny_mode = set()
396
335
deny_audit = set()
398
fmode, famode, fm = apparmor.aa.rematchfrag(self.user.aa[profile][hat], 'allow', path)
337
fmode, famode, fm = apparmor.aa.rematchfrag(aa[profile][hat], 'allow', path)
400
339
allow_mode |= fmode
402
341
allow_audit |= famode
404
cm, cam, m = apparmor.aa.rematchfrag(self.user.aa[profile][hat], 'deny', path)
343
cm, cam, m = apparmor.aa.rematchfrag(aa[profile][hat], 'deny', path)
408
347
deny_audit |= cam
410
imode, iamode, im = apparmor.aa.match_prof_incs_to_path(self.user.aa[profile][hat], 'allow', path)
349
imode, iamode, im = apparmor.aa.match_prof_incs_to_path(aa[profile][hat], 'allow', path)
412
351
allow_mode |= imode
414
353
allow_audit |= iamode
416
cm, cam, m = apparmor.aa.match_prof_incs_to_path(self.user.aa[profile][hat], 'deny', path)
355
cm, cam, m = apparmor.aa.match_prof_incs_to_path(aa[profile][hat], 'deny', path)
598
529
elif ans == 'CMD_ALLOW':
599
530
path = options[selected]
601
match = apparmor.aa.re_match_include(path)
532
match = re_match_include(path)
605
deleted = apparmor.aa.delete_duplicates(self.user.aa[profile][hat], inc)
606
self.user.aa[profile][hat]['include'][inc] = True
607
apparmor.aa.changed[profile] = True
535
deleted = apparmor.aa.delete_duplicates(aa[profile][hat], inc)
536
aa[profile][hat]['include'][inc] = True
537
changed[profile] = True
608
538
aaui.UI_Info(_('Adding %s to profile.') % path)
610
540
aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted)
613
if self.user.aa[profile][hat]['allow']['path'][path].get('mode', False):
614
mode |= self.user.aa[profile][hat]['allow']['path'][path]['mode']
543
if aa[profile][hat]['allow']['path'][path].get('mode', False):
544
mode |= aa[profile][hat]['allow']['path'][path]['mode']
616
for entry in self.user.aa[profile][hat]['allow']['path'].keys():
546
for entry in aa[profile][hat]['allow']['path'].keys():
617
547
if path == entry:
620
550
if apparmor.aa.matchregexp(path, entry):
621
if apparmor.aa.mode_contains(mode, self.user.aa[profile][hat]['allow']['path'][entry]['mode']):
551
if apparmor.aa.mode_contains(mode, aa[profile][hat]['allow']['path'][entry]['mode']):
622
552
deleted.append(entry)
623
553
for entry in deleted:
624
self.user.aa[profile][hat]['allow']['path'].pop(entry)
554
aa[profile][hat]['allow']['path'].pop(entry)
625
555
deleted = len(deleted)
627
557
if owner_toggle == 0:
633
563
elif owner_toggle == 3:
634
564
mode = apparmor.aa.owner_flatten_mode(mode)
636
if not self.user.aa[profile][hat]['allow'].get(path, False):
637
self.user.aa[profile][hat]['allow']['path'][path]['mode'] = self.user.aa[profile][hat]['allow']['path'][path].get('mode', set()) | mode
566
if not aa[profile][hat]['allow'].get(path, False):
567
aa[profile][hat]['allow']['path'][path]['mode'] = aa[profile][hat]['allow']['path'][path].get('mode', set()) | mode
641
571
if audit_toggle == 1:
642
tmpmode = mode- allow_mode
572
tmpmode = mode - allow_mode
643
573
elif audit_toggle == 2:
646
self.user.aa[profile][hat]['allow']['path'][path]['audit'] = self.user.aa[profile][hat]['allow']['path'][path].get('audit', set()) | tmpmode
576
aa[profile][hat]['allow']['path'][path]['audit'] = aa[profile][hat]['allow']['path'][path].get('audit', set()) | tmpmode
648
apparmor.aa.changed[profile] = True
578
changed[profile] = True
650
580
aaui.UI_Info(_('Adding %(path)s %(mode)s to profile') % { 'path': path, 'mode': apparmor.aa.mode_to_str_user(mode) })
654
584
elif ans == 'CMD_DENY':
655
585
path = options[selected].strip()
657
self.user.aa[profile][hat]['deny']['path'][path]['mode'] = self.user.aa[profile][hat]['deny']['path'][path].get('mode', set()) | (mode - allow_mode)
659
self.user.aa[profile][hat]['deny']['path'][path]['audit'] = self.user.aa[profile][hat]['deny']['path'][path].get('audit', set())
661
apparmor.aa.changed[profile] = True
587
aa[profile][hat]['deny']['path'][path]['mode'] = aa[profile][hat]['deny']['path'][path].get('mode', set()) | (mode - allow_mode)
589
aa[profile][hat]['deny']['path'][path]['audit'] = aa[profile][hat]['deny']['path'][path].get('audit', set())
591
changed[profile] = True
665
595
elif ans == 'CMD_NEW':
666
596
arg = options[selected]
667
if not apparmor.aa.re_match_include(arg):
597
if not re_match_include(arg):
668
598
ans = aaui.UI_GetString(_('Enter new path: '), arg)
670
600
# if not matchliteral(ans, path):
701
631
elif re.search('\d', ans):
702
632
default_option = ans
705
for allow in ['allow', 'deny']:
706
for family in sorted(other.aa[profile][hat][allow]['netdomain']['rule'].keys()):
707
# severity handling for net toggles goes here
634
for ruletype in ['capability', 'network', 'change_profile']:
635
if other.aa[profile][hat].get(ruletype, False): # needed until we have proper profile initialization
636
for rule_obj in other.aa[profile][hat][ruletype].rules:
709
for sock_type in sorted(other.aa[profile][hat][allow]['netdomain']['rule'][family].keys()):
710
#if apparmor.aa.profile_known_network(self.user.aa[profile][hat], family, sock_type):
712
# disabled for now because it crashes, for details and impact see
713
# https://bugs.launchpad.net/apparmor/+bug/1382241
638
if is_known_rule(aa[profile][hat], ruletype, rule_obj):
715
641
default_option = 1
717
newincludes = apparmor.aa.match_net_includes(self.user.aa[profile][hat], family, sock_type)
643
newincludes = match_includes(aa[profile][hat], ruletype, rule_obj)
718
644
q = aaui.PromptQuestion()
720
options += list(map(lambda s: '#include <%s>'%s, sorted(set(newincludes))))
722
options.append('network %s %s' % (family, sock_type))
724
q.selected = default_option - 1
726
q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
727
q.headers += [_('Network Family'), family]
728
q.headers += [_('Socket Type'), sock_type]
731
q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_IGNORE_ENTRY', 'CMD_AUDIT_NEW',
732
'CMD_ABORT', 'CMD_FINISHED']
734
q.default = 'CMD_ALLOW'
646
options += list(map(lambda inc: '#include <%s>' % inc, sorted(set(newincludes))))
648
options.append(rule_obj.get_clean())
650
q.selected = default_option - 1
654
q.headers = [_('Profile'), combine_name(profile, hat)]
655
q.headers += rule_obj.logprof_header()
657
# Load variables into sev_db? Not needed/used for capabilities and network rules.
658
severity = rule_obj.severity(sev_db)
659
if severity != sev_db.NOT_IMPLEMENTED:
660
q.headers += [_('Severity'), severity]
662
q.functions = available_buttons(rule_obj)
663
q.default = q.functions[0]
738
665
ans, selected = q.promptUser()
739
666
if ans == 'CMD_IGNORE_ENTRY':
743
670
elif ans == 'CMD_FINISHED':
746
if ans.startswith('CMD_AUDIT'):
747
audit_toggle = not audit_toggle
751
q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_AUDIT_OFF',
752
'CMD_ABORT', 'CMD_FINISHED']
673
elif ans.startswith('CMD_AUDIT'):
674
if ans == 'CMD_AUDIT_NEW':
675
rule_obj.audit = True
676
rule_obj.raw_rule = None
754
q.functions = ['CMD_ALLOW', 'CMD_DENY', 'CMD_AUDIT_NEW',
755
'CMD_ABORT', 'CMD_FINISHED']
756
q.headers = [_('Profile'), apparmor.aa.combine_name(profile, hat)]
757
q.headers += [_('Network Family'), audit + family]
758
q.headers += [_('Socket Type'), sock_type]
678
rule_obj.audit = False
679
rule_obj.raw_rule = None
681
options[len(options) - 1] = rule_obj.get_clean()
760
684
elif ans == 'CMD_ALLOW':
761
#print(options, selected)
686
changed[profile] = True
762
688
selection = options[selected]
764
if apparmor.aa.re_match_include(selection): #re.search('#include\s+<.+>$', selection):
765
inc = apparmor.aa.re_match_include(selection) #re.search('#include\s+<(.+)>$', selection).groups()[0]
767
deleted = apparmor.aa.delete_duplicates(self.user.aa[profile][hat], inc)
769
self.user.aa[profile][hat]['include'][inc] = True
771
apparmor.aa.changed[profile] = True
773
aaui.UI_Info(_('Adding %s to profile') % selection)
690
inc = re_match_include(selection)
692
deleted = delete_duplicates(aa[profile][hat], inc)
694
aa[profile][hat]['include'][inc] = True
696
aaui.UI_Info(_('Adding %s to profile.') % selection)
775
698
aaui.UI_Info(_('Deleted %s previous matching profile entries.') % deleted)
778
self.user.aa[profile][hat]['allow']['netdomain']['audit'][family][sock_type] = audit_toggle
779
self.user.aa[profile][hat]['allow']['netdomain']['rule'][family][sock_type] = True
781
apparmor.aa.changed[profile] = True
783
aaui.UI_Info(_('Adding network access %(family)s %(type)s to profile.') % { 'family': family, 'type': sock_type })
701
aa[profile][hat][ruletype].add(rule_obj)
703
aaui.UI_Info(_('Adding %s to profile.') % rule_obj.get_clean())
785
705
elif ans == 'CMD_DENY':
787
self.user.aa[profile][hat]['deny']['netdomain']['rule'][family][sock_type] = True
788
apparmor.aa.changed[profile] = True
789
aaui.UI_Info(_('Denying network access %(family)s %(type)s to profile') % { 'family': family, 'type': sock_type })
707
changed[profile] = True
710
rule_obj.raw_rule = None # reset raw rule after manually modifying rule_obj
711
aa[profile][hat][ruletype].add(rule_obj)
712
aaui.UI_Info(_('Adding %s to profile.') % rule_obj.get_clean())