mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-09-05 00:35:13 +00:00
Refactoring cleanup for CMD_ABORT/CMD_FINISHED handling (jmichael)
This commit is contained in:
@@ -94,7 +94,6 @@ our @EXPORT = qw(
|
||||
our $confdir = "/etc/apparmor";
|
||||
|
||||
our $running_under_genprof = 0;
|
||||
our $finishing = 0;
|
||||
|
||||
our $DEBUGGING;
|
||||
|
||||
@@ -951,6 +950,14 @@ sub UI_PromptUser ($) {
|
||||
$arg = $yarg->{selected};
|
||||
}
|
||||
|
||||
if ($cmd eq "CMD_ABORT") {
|
||||
confirm_and_abort();
|
||||
$cmd = "XXXINVALIDXXX";
|
||||
} elsif ($cmd eq "CMD_FINISHED") {
|
||||
confirm_and_finish();
|
||||
$cmd = "XXXINVALIDXXX";
|
||||
}
|
||||
|
||||
return ($cmd, $arg);
|
||||
}
|
||||
|
||||
@@ -1021,6 +1028,26 @@ sub GetDataFromYast {
|
||||
fatal_error "GetDataFromYast: didn't receive YCP command before connection died";
|
||||
}
|
||||
|
||||
sub confirm_and_abort {
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to abandon this set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Abandoning all changes."));
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
}
|
||||
}
|
||||
|
||||
sub confirm_and_finish {
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to save the current set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Saving all changes."));
|
||||
|
||||
# need to wrap any calls to ui functions with eval { } blocks in order
|
||||
# to catch this exception
|
||||
die "FINISHING\n";
|
||||
}
|
||||
}
|
||||
|
||||
##########################################################################
|
||||
# this is the hideously ugly function that descends down the flow/event
|
||||
# trees that we've generated by parsing the logfile
|
||||
@@ -1089,9 +1116,8 @@ sub handlechildren {
|
||||
$q->{functions} = [];
|
||||
push @{ $q->{functions} }, "CMD_ADDHAT";
|
||||
push @{ $q->{functions} }, "CMD_USEDEFAULT" if $defaulthat;
|
||||
push @{ $q->{functions} }, "CMD_DENY";
|
||||
push @{ $q->{functions} }, "CMD_ABORT";
|
||||
push @{ $q->{functions} }, "CMD_FINISHED";
|
||||
push @{$q->{functions}}, "CMD_DENY", "CMD_ABORT",
|
||||
"CMD_FINISHED";
|
||||
|
||||
$q->{default} = ($sdmode eq "PERMITTING") ? "CMD_ADDHAT" : "CMD_DENY";
|
||||
|
||||
@@ -1114,23 +1140,6 @@ sub handlechildren {
|
||||
$hat = $defaulthat;
|
||||
} elsif ($ans eq "CMD_DENY") {
|
||||
return;
|
||||
} elsif ($ans eq "CMD_ABORT") {
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to abandon this set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Abandoning all changes."));
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
}
|
||||
} elsif ($ans eq "CMD_FINISHED") {
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to save the current set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Saving all changes."));
|
||||
$finishing = 1;
|
||||
|
||||
# XXX - BUGBUG - this is REALLY nasty, but i'm in
|
||||
# a hurry...
|
||||
goto SAVE_PROFILES;
|
||||
}
|
||||
}
|
||||
|
||||
} elsif ($type eq "capability") {
|
||||
@@ -1297,10 +1306,8 @@ sub handlechildren {
|
||||
if $options =~ /p/;
|
||||
push @{ $q->{functions} }, "CMD_UNCONFINED"
|
||||
if $options =~ /u/;
|
||||
push @{ $q->{functions} }, "CMD_DENY";
|
||||
push @{ $q->{functions} }, "CMD_ABORT";
|
||||
push @{ $q->{functions} }, "CMD_FINISHED";
|
||||
|
||||
push @{$q->{functions}}, "CMD_DENY", "CMD_ABORT",
|
||||
"CMD_FINISHED";
|
||||
$q->{default} = $default;
|
||||
|
||||
$options = join("|", split(//, $options));
|
||||
@@ -1311,26 +1318,7 @@ sub handlechildren {
|
||||
while ($ans !~ m/^CMD_(INHERIT|PROFILE|PROFILE_CLEAN|UNCONFINED|UNCONFINED_CLEAN|DENY)$/) {
|
||||
($ans, $arg) = UI_PromptUser($q);
|
||||
|
||||
# check for Abort or Finish
|
||||
if ($ans eq "CMD_ABORT") {
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to abandon this set of profile changes and exit?"), "n");
|
||||
$DEBUGGING && debug "back from abort yesno";
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Abandoning all changes."));
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
}
|
||||
} elsif ($ans eq "CMD_FINISHED") {
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to save the current set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Saving all changes."));
|
||||
$finishing = 1;
|
||||
|
||||
# XXX - BUGBUG - this is REALLY nasty,
|
||||
# but i'm in a hurry...
|
||||
goto SAVE_PROFILES;
|
||||
}
|
||||
} elsif ($ans eq "CMD_PROFILE") {
|
||||
if ($ans eq "CMD_PROFILE") {
|
||||
my $px_default = "n";
|
||||
my $px_mesg = gettext("Should AppArmor sanitize the environment when\nswitching profiles?\n\nSanitizing the environment is more secure,\nbut some applications depend on the presence\nof LD_PRELOAD or LD_LIBRARY_PATH.");
|
||||
if ($parent_uses_ld_xxx) {
|
||||
@@ -1449,30 +1437,9 @@ sub add_to_tree ($@) {
|
||||
push @{ $pid{$pid} }, [ $type, $pid, @event ];
|
||||
}
|
||||
|
||||
sub do_logprof_pass {
|
||||
my $logmark = shift || "";
|
||||
|
||||
# zero out the state variables for this pass...
|
||||
%t = ();
|
||||
%transitions = ();
|
||||
%seen = ();
|
||||
%sd = ();
|
||||
%profilechanges = ();
|
||||
%prelog = ();
|
||||
%log = ();
|
||||
%changed = ();
|
||||
%skip = ();
|
||||
%variables = ();
|
||||
|
||||
UI_Info(sprintf(gettext('Reading log entries from %s.'), $filename));
|
||||
UI_Info(sprintf(gettext('Updating AppArmor profiles in %s.'), $profiledir));
|
||||
|
||||
readprofiles();
|
||||
|
||||
sub read_log {
|
||||
my $logmark = shift;
|
||||
my $seenmark = $logmark ? 0 : 1;
|
||||
|
||||
$sevdb = new Immunix::Severity("$confdir/severity.db", gettext("unknown"));
|
||||
|
||||
my $stuffed = undef;
|
||||
my $last;
|
||||
|
||||
@@ -1696,17 +1663,9 @@ sub do_logprof_pass {
|
||||
}
|
||||
}
|
||||
close(LOG);
|
||||
}
|
||||
|
||||
for my $root (@log) {
|
||||
handlechildren(undef, undef, $root);
|
||||
}
|
||||
|
||||
for my $pid (sort { $a <=> $b } keys %profilechanges) {
|
||||
setprocess($pid, $profilechanges{$pid});
|
||||
}
|
||||
|
||||
collapselog();
|
||||
|
||||
sub ask_the_questions {
|
||||
my $found;
|
||||
|
||||
# do the magic foo-foo
|
||||
@@ -1754,7 +1713,9 @@ sub do_logprof_pass {
|
||||
push @{ $q->{headers} }, gettext("Capability"), $capability;
|
||||
push @{ $q->{headers} }, gettext("Severity"), $severity;
|
||||
|
||||
$q->{functions} = [ "CMD_ALLOW", "CMD_DENY", "CMD_ABORT", "CMD_FINISHED" ];
|
||||
$q->{functions} = [
|
||||
"CMD_ALLOW", "CMD_DENY", "CMD_ABORT", "CMD_FINISHED"
|
||||
];
|
||||
|
||||
# complain-mode events default to allow - enforce defaults
|
||||
# to deny
|
||||
@@ -1779,46 +1740,8 @@ sub do_logprof_pass {
|
||||
UI_Info(sprintf(gettext('Adding capability %s to profile.'), $capability));
|
||||
} elsif ($ans eq "CMD_DENY") {
|
||||
UI_Info(sprintf(gettext('Denying capability %s to profile.'), $capability));
|
||||
} elsif ($ans eq "CMD_ABORT") {
|
||||
|
||||
# if we're in yast, they've already been asked for
|
||||
# confirmation
|
||||
if ($UI_Mode eq "yast") {
|
||||
UI_Info(gettext("Abandoning all changes."));
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
}
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to abandon this set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Abandoning all changes."));
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
} else {
|
||||
redo;
|
||||
}
|
||||
} elsif ($ans eq "CMD_FINISHED") {
|
||||
|
||||
# if we're in yast, they've already been asked for
|
||||
# confirmation
|
||||
if ($UI_Mode eq "yast") {
|
||||
UI_Info(gettext("Saving all changes."));
|
||||
$finishing = 1;
|
||||
|
||||
# XXX - BUGBUG - this is REALLY nasty, but i'm in
|
||||
# a hurry...
|
||||
goto SAVE_PROFILES;
|
||||
}
|
||||
my $ans = UI_YesNo(gettext("Are you sure you want to save the current set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Saving all changes."));
|
||||
$finishing = 1;
|
||||
|
||||
# XXX - BUGBUG - this is REALLY nasty, but i'm in
|
||||
# a hurry...
|
||||
goto SAVE_PROFILES;
|
||||
} else {
|
||||
redo;
|
||||
}
|
||||
} else {
|
||||
redo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1997,7 +1920,10 @@ sub do_logprof_pass {
|
||||
$q->{options} = [@options];
|
||||
$q->{selected} = $defaultoption - 1;
|
||||
|
||||
$q->{functions} = [ "CMD_ALLOW", "CMD_DENY", "CMD_GLOB", "CMD_GLOBEXT", "CMD_NEW", "CMD_ABORT", "CMD_FINISHED" ];
|
||||
$q->{functions} = [
|
||||
"CMD_ALLOW", "CMD_DENY", "CMD_GLOB", "CMD_GLOBEXT", "CMD_NEW",
|
||||
"CMD_ABORT", "CMD_FINISHED"
|
||||
];
|
||||
|
||||
$q->{default} =
|
||||
($sdmode eq "PERMITTING")
|
||||
@@ -2129,23 +2055,6 @@ sub do_logprof_pass {
|
||||
}
|
||||
} elsif ($ans =~ /\d/) {
|
||||
$defaultoption = $ans;
|
||||
} elsif ($ans eq "CMD_ABORT") {
|
||||
$ans = UI_YesNo(gettext("Are you sure you want to abandon this set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Abandoning all changes."));
|
||||
shutdown_yast();
|
||||
exit 0;
|
||||
}
|
||||
} elsif ($ans eq "CMD_FINISHED") {
|
||||
$ans = UI_YesNo(gettext("Are you sure you want to save the current set of profile changes and exit?"), "n");
|
||||
if ($ans eq "y") {
|
||||
UI_Info(gettext("Saving all changes."));
|
||||
$finishing = 1;
|
||||
|
||||
# XXX - BUGBUG - this is REALLY nasty, but
|
||||
# i'm in a hurry...
|
||||
goto SAVE_PROFILES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2153,38 +2062,94 @@ sub do_logprof_pass {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($UI_Mode eq "yast") {
|
||||
if (not $running_under_genprof) {
|
||||
if ($seenevents) {
|
||||
my $w = { type => "wizard" };
|
||||
$w->{explanation} = gettext("The profile analyzer has completed processing the log files.\nAll updated profiles will be reloaded");
|
||||
$w->{functions} = [ "CMD_ABORT", "CMD_FINISHED" ];
|
||||
SendDataToYast($w);
|
||||
my $foo = GetDataFromYast();
|
||||
} else {
|
||||
my $w = { type => "wizard" };
|
||||
$w->{explanation} = gettext("No unhandled AppArmor events were found in the system log.");
|
||||
$w->{functions} = [ "CMD_ABORT", "CMD_FINISHED" ];
|
||||
SendDataToYast($w);
|
||||
my $foo = GetDataFromYast();
|
||||
sub do_logprof_pass {
|
||||
my $logmark = shift || "";
|
||||
|
||||
# zero out the state variables for this pass...
|
||||
%t = ( );
|
||||
%transitions = ( );
|
||||
%seen = ( );
|
||||
%sd = ( );
|
||||
%profilechanges = ( );
|
||||
%prelog = ( );
|
||||
@log = ( );
|
||||
%log = ( );
|
||||
%changed = ( );
|
||||
%skip = ( );
|
||||
%variables = ( );
|
||||
|
||||
UI_Info(sprintf(gettext('Reading log entries from %s.'), $filename));
|
||||
UI_Info(sprintf(gettext('Updating AppArmor profiles in %s.'), $profiledir));
|
||||
|
||||
readprofiles();
|
||||
|
||||
unless ($sevdb) {
|
||||
$sevdb = new Immunix::Severity("$confdir/severity.db", gettext("unknown"));
|
||||
}
|
||||
|
||||
# we need to be able to break all the way out of deep into subroutine calls
|
||||
# if they select "Finish" so we can take them back out to the genprof prompt
|
||||
eval {
|
||||
read_log($logmark);
|
||||
|
||||
for my $root (@log) {
|
||||
handlechildren(undef, undef, $root);
|
||||
}
|
||||
|
||||
for my $pid (sort { $a <=> $b } keys %profilechanges) {
|
||||
setprocess($pid, $profilechanges{$pid});
|
||||
}
|
||||
|
||||
collapselog();
|
||||
|
||||
ask_the_questions();
|
||||
|
||||
if ($UI_Mode eq "yast") {
|
||||
if (not $running_under_genprof) {
|
||||
if ($seenevents) {
|
||||
my $w = { type => "wizard" };
|
||||
$w->{explanation} = gettext("The profile analyzer has completed processing the log files.\n\nAll updated profiles will be reloaded");
|
||||
$w->{functions} = [ "CMD_ABORT", "CMD_FINISHED" ];
|
||||
SendDataToYast($w);
|
||||
my $foo = GetDataFromYast();
|
||||
} else {
|
||||
my $w = { type => "wizard" };
|
||||
$w->{explanation} = gettext("No unhandled AppArmor events were found in the system log.");
|
||||
$w->{functions} = [ "CMD_ABORT", "CMD_FINISHED" ];
|
||||
SendDataToYast($w);
|
||||
my $foo = GetDataFromYast();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
my $finishing = 0;
|
||||
if ($@) {
|
||||
if ($@ =~ /FINISHING/) {
|
||||
$finishing = 1;
|
||||
} else {
|
||||
die $@;
|
||||
}
|
||||
}
|
||||
|
||||
SAVE_PROFILES:
|
||||
|
||||
# make sure the profile changes we've made are saved to disk...
|
||||
for my $profile (sort keys %changed) {
|
||||
writeprofile($profile);
|
||||
reload($profile);
|
||||
}
|
||||
save_profiles();
|
||||
|
||||
# if they hit "Finish" we need to tell the caller that so we can exit
|
||||
# all the way instead of just going back to the genprof prompt
|
||||
return $finishing ? "FINISHED" : "NORMAL";
|
||||
}
|
||||
|
||||
sub save_profiles {
|
||||
# make sure the profile changes we've made are saved to disk...
|
||||
for my $profile (sort keys %changed) {
|
||||
writeprofile($profile);
|
||||
reload($profile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub setprocess ($$) {
|
||||
my ($pid, $profile) = @_;
|
||||
|
||||
@@ -3324,18 +3289,11 @@ sub Text_PromptUser ($) {
|
||||
# pull our command back from our hotkey map
|
||||
$ans = $keys{$ans} if $keys{$ans};
|
||||
|
||||
# if($options) {
|
||||
# die "ERROR: not looking for array when options passed" unless wantarray;
|
||||
if ($options) {
|
||||
return ($ans, $options->[$selected]);
|
||||
} else {
|
||||
return ($ans, $selected);
|
||||
}
|
||||
|
||||
# } else {
|
||||
# die "ERROR: looking for list when options not passed" if wantarray;
|
||||
# return $ans;
|
||||
# }
|
||||
}
|
||||
|
||||
unless (-x $ldd) {
|
||||
|
Reference in New Issue
Block a user