mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
Added checks for profile syntax and error dialogs in the yastui.
This commit is contained in:
parent
c231a42cf4
commit
1fe7e92955
13 changed files with 230 additions and 114 deletions
|
@ -27,24 +27,24 @@ use Data::Dumper;
|
|||
|
||||
sub getSubdomainStatus {
|
||||
|
||||
my $sdStatus = "disabled";
|
||||
my $sdStatus = "disabled";
|
||||
|
||||
# Ok check that there are profiles loaded to
|
||||
# determine status
|
||||
my $mountpoint = Immunix::SubDomain::check_for_subdomain();
|
||||
if ( $mountpoint ) {
|
||||
open( PROFILES, "cat $mountpoint/profiles|" );
|
||||
while (<PROFILES>) {
|
||||
# Ensure we have loaded profiles
|
||||
# not just a loaded module
|
||||
if ( /\// ) {
|
||||
$sdStatus = "enabled";
|
||||
last;
|
||||
}
|
||||
}
|
||||
close PROFILES;
|
||||
# Ok check that there are profiles loaded to
|
||||
# determine status
|
||||
my $mountpoint = Immunix::SubDomain::check_for_subdomain();
|
||||
if ( $mountpoint ) {
|
||||
open( PROFILES, "cat $mountpoint/profiles|" );
|
||||
while (<PROFILES>) {
|
||||
# Ensure we have loaded profiles
|
||||
# not just a loaded module
|
||||
if ( /\// ) {
|
||||
$sdStatus = "enabled";
|
||||
last;
|
||||
}
|
||||
}
|
||||
return $sdStatus;
|
||||
close PROFILES;
|
||||
}
|
||||
return $sdStatus;
|
||||
}
|
||||
|
||||
sub getNotifySettings {
|
||||
|
@ -79,43 +79,58 @@ sub getNotifyStatus {
|
|||
return $noteStatus;
|
||||
}
|
||||
|
||||
sub profileSyntaxCheck {
|
||||
my $errlist = [];
|
||||
Immunix::SubDomain::checkIncludeSyntax($errlist);
|
||||
Immunix::SubDomain::checkProfileSyntax($errlist);
|
||||
my @errlist = Immunix::SubDomain::uniq(@$errlist);
|
||||
return \@errlist;
|
||||
}
|
||||
|
||||
|
||||
# Main
|
||||
################################################################################
|
||||
|
||||
|
||||
my $line = <STDIN>;
|
||||
|
||||
my ($command, $path, $argument) = Immunix::Ycp::ParseCommand($line);
|
||||
while ( <STDIN> ) {
|
||||
my ($command, $path, $argument) = Immunix::Ycp::ParseCommand($_);
|
||||
|
||||
my $result = undef;
|
||||
my $donereturn = 0;
|
||||
if ( $command && $path && $argument ) {
|
||||
if ( $argument eq 'sd-all') {
|
||||
my %hResult = ''; # hashed result, duh
|
||||
$hResult{'sd-status'} = getSubdomainStatus();
|
||||
$hResult{'sd-notify'} = getNotifyStatus();
|
||||
Immunix::Ycp::ycpReturnHashAsMap( %hResult );
|
||||
$donereturn = 1;
|
||||
} elsif ( $argument eq 'sd-status') {
|
||||
$result = getSubdomainStatus();
|
||||
} elsif ( $argument eq 'sd-notify') {
|
||||
$result = getNotifyStatus();
|
||||
} elsif ( $argument eq 'sd-notify-settings') {
|
||||
$result = getNotifySettings();
|
||||
Immunix::Ycp::ycpReturn($result);
|
||||
$donereturn = 1;
|
||||
}
|
||||
|
||||
Immunix::Ycp::ycpReturnSkalarAsString( $result ) if ( ! $donereturn );
|
||||
|
||||
} else {
|
||||
|
||||
my $ycpCmd = ycpGetCommand() || "";
|
||||
my $ycpArg = ycpGetArgType() || "";
|
||||
$result = "Unknown instruction $ycpCmd or argument: $ycpArg\n";
|
||||
Immunix::Ycp::ycpReturnSkalarAsString( $result );
|
||||
my $result = undef;
|
||||
my $donereturn = 0;
|
||||
if ( $command && $path && $argument ) {
|
||||
if ( $argument eq 'sd-all') {
|
||||
my %hResult = ''; # hashed result, duh
|
||||
$hResult{'sd-status'} = getSubdomainStatus();
|
||||
$hResult{'sd-notify'} = getNotifyStatus();
|
||||
Immunix::Ycp::ycpReturnHashAsMap( %hResult );
|
||||
$donereturn = 1;
|
||||
} elsif ( $argument eq 'sd-status') {
|
||||
$result = getSubdomainStatus();
|
||||
} elsif ( $argument eq 'sd-notify') {
|
||||
$result = getNotifyStatus();
|
||||
} elsif ( $command eq "Read" and $argument eq 'custom-includes') {
|
||||
Immunix::SubDomain::readconfig();
|
||||
Immunix::Ycp::ycpReturn(\@Immunix::SubDomain::custom_includes);
|
||||
$donereturn = 1;
|
||||
} elsif ( $command eq "Execute" and $argument eq 'profile-syntax-check') {
|
||||
$result = profileSyntaxCheck();
|
||||
Immunix::Ycp::ycpReturn($result);
|
||||
$donereturn = 1;
|
||||
} elsif ( $argument eq 'sd-notify-settings') {
|
||||
$result = getNotifySettings();
|
||||
Immunix::Ycp::ycpReturn($result);
|
||||
$donereturn = 1;
|
||||
}
|
||||
Immunix::Ycp::ycpReturnSkalarAsString( $result ) if ( ! $donereturn );
|
||||
} else {
|
||||
my $ycpCmd = ycpGetCommand() || "";
|
||||
my $ycpArg = ycpGetArgType() || "";
|
||||
$result = "Unknown instruction $ycpCmd or argument: $ycpArg\n";
|
||||
Immunix::Ycp::ycpReturnSkalarAsString( $result );
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ while ( <STDIN> ) {
|
|||
}
|
||||
} elsif ( $command eq "Read") {
|
||||
$UI_Mode = "yast";
|
||||
Immunix::SubDomain::readprofile("$profiledir/$argument");
|
||||
Immunix::SubDomain::readprofile("$profiledir/$argument", \&$Immunix::SubDomain::fatal_error);
|
||||
Immunix::Ycp::Return( \%sd );
|
||||
} elsif ( $command eq "Write" and $path eq ".delete") {
|
||||
if ( $argument ne "" ) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
import "Wizard";
|
||||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_profile_check.ycp";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
|
@ -37,6 +38,9 @@
|
|||
if (!installAppArmorPackages()) {
|
||||
return;
|
||||
}
|
||||
if (!checkProfileSyntax()) {
|
||||
return;
|
||||
}
|
||||
// initiate the handshake with the backend agent
|
||||
map agent_data = (map) SCR::Read(.genprof);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/apparmor_profile_check.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
boolean done = false;
|
||||
|
@ -37,6 +38,9 @@
|
|||
if (!installAppArmorPackages()) {
|
||||
return;
|
||||
}
|
||||
if (!checkProfileSyntax()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// initiate the handshake with the backend agent
|
||||
map agent_data = (map) SCR::Read(.logprof);
|
||||
|
|
|
@ -12,6 +12,7 @@ import "Wizard";
|
|||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/apparmor_profile_check.ycp";
|
||||
include "subdomain/profile_dialogs.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
|
@ -86,6 +87,9 @@ any ret = nil;
|
|||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
if (!checkProfileSyntax()) {
|
||||
return ret;
|
||||
}
|
||||
ret = MainSequence();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import "Wizard";
|
|||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/apparmor_profile_check.ycp";
|
||||
include "subdomain/profile_dialogs.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
|
@ -67,6 +68,11 @@ any ret = nil;
|
|||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!checkProfileSyntax()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ret = MainSequence();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import "Wizard";
|
|||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/apparmor_profile_check.ycp";
|
||||
include "subdomain/profile_dialogs.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
||||
|
@ -67,9 +68,16 @@ define any MainSequence() ``{
|
|||
// YEAH BABY RUN BABY RUN
|
||||
//
|
||||
any ret = nil;
|
||||
|
||||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!checkProfileSyntax()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ret = MainSequence();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import "Wizard";
|
|||
import "Popup";
|
||||
import "Sequencer";
|
||||
include "subdomain/apparmor_packages.ycp";
|
||||
include "subdomain/apparmor_profile_check.ycp";
|
||||
include "subdomain/reporting_dialogues.ycp";
|
||||
include "subdomain/report_helptext.ycp";
|
||||
textdomain "yast2-apparmor";
|
||||
|
@ -29,11 +30,6 @@ define any mainSequence() ``{
|
|||
"schedReport" : ``(displaySchedForm()),
|
||||
"viewreport" : ``(displayArchForm()),
|
||||
"runReport" : ``(displayRunForm())
|
||||
/*
|
||||
"addSched" : ``(addSchedForm()),
|
||||
"editSched" : ``(editSchedForm()),
|
||||
"delSched" : ``(delSchedForm())
|
||||
*/
|
||||
];
|
||||
|
||||
map sequence = $[
|
||||
|
@ -48,44 +44,18 @@ define any mainSequence() ``{
|
|||
"schedReport": $[
|
||||
`back : `ws_start,
|
||||
`abort : `abort,
|
||||
// `add : "mainreport",
|
||||
// `edit : "editSched",
|
||||
// `del : "delSched",
|
||||
`viewrep : "viewreport",
|
||||
`runrep : "runReport",
|
||||
`next : "runReport",
|
||||
`finish : `ws_finish
|
||||
],
|
||||
/*
|
||||
"addSched" : $[
|
||||
`back : "schedReport",
|
||||
`abort : `abort,
|
||||
`save : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"editSched" : $[
|
||||
`back : "schedReport",
|
||||
`abort : `abort,
|
||||
`save : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"delSched" : $[
|
||||
`back : "schedReport",
|
||||
`abort : `abort,
|
||||
`save : `finish,
|
||||
`finish : `ws_finish
|
||||
],
|
||||
*/
|
||||
"viewreport" : $[
|
||||
//`back : "viewreport",
|
||||
`back : "mainreport",
|
||||
`abort : `abort,
|
||||
//`next : `finish,
|
||||
`next : "mainreport",
|
||||
`finish : `ws_finish
|
||||
],
|
||||
"runReport": $[
|
||||
//`back : "runReport",
|
||||
`back : `back,
|
||||
`abort : `abort,
|
||||
`next : `finish,
|
||||
|
@ -116,9 +86,13 @@ any ret = nil;
|
|||
if (!installAppArmorPackages()) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
checkProfileSyntax();
|
||||
|
||||
ret = mainSequence();
|
||||
return ret;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -622,15 +622,34 @@ define symbol DisplayProfileForm(string pathname, boolean hat) {
|
|||
return `showhat;
|
||||
}
|
||||
} else if ( id == `include ) {
|
||||
string newInclude = UI::AskForExistingFile( "/etc/apparmor.d", "", _("Select File To Include"));
|
||||
if ( newInclude == nil || (string)newInclude == "" ) {
|
||||
any ci = SCR::Read(.subdomain, "custom-includes");
|
||||
list <any> customIncludes = tolist(ci);
|
||||
string newInclude = UI::AskForExistingFile( "/etc/apparmor.d/abstractions", "", _("Select File To Include"));
|
||||
if ( newInclude == nil || (string)newInclude == "" ) {
|
||||
continue;
|
||||
}
|
||||
integer includeRootBad = find (newInclude, "/etc/apparmor.d");
|
||||
if ( includeRootBad == -1 ) {
|
||||
Popup::Error("AppArmor include files must be located in the directory /etc/apparmor.d");
|
||||
list <string> validIncludes = [ "/etc/apparmor.d/abstractions", "/etc/apparmor.d/program-chunks", "/etc/apparmor.d/tunables" ];
|
||||
foreach( any incPath, (list<any>) customIncludes, {
|
||||
string incPathStr = tostring(incPath);
|
||||
validIncludes = add( validIncludes, "/etc/apparmor.d/" + incPathStr);
|
||||
});
|
||||
|
||||
integer result = 0;
|
||||
boolean includePathOK = false;
|
||||
foreach( string pathToCheck, (list<string>) validIncludes, {
|
||||
result = find (newInclude, pathToCheck);
|
||||
if ( result != -1 ) {
|
||||
includePathOK = true;
|
||||
}
|
||||
});
|
||||
|
||||
if ( ! includePathOK ) {
|
||||
string pathListMsg = "";
|
||||
foreach( string pathItem, (list<string>) validIncludes, {
|
||||
pathListMsg = pathListMsg + "\n " + pathItem;
|
||||
});
|
||||
Popup::Error(_("Invalid #include file. Include files must be located in one of these directores: \n") + pathListMsg );
|
||||
} else {
|
||||
// string includeName = substring(newInclude, 17 );
|
||||
string includeName = substring(newInclude, 16 );
|
||||
includes = add( includes, includeName, 1 );
|
||||
profile["include"] = includes;
|
||||
|
@ -647,7 +666,7 @@ define symbol DisplayProfileForm(string pathname, boolean hat) {
|
|||
if ( ! hat ) {
|
||||
if (Popup::YesNoHeadline(_("Save changes to the Profile"),
|
||||
"Would you like to save the changes to this profile? \n(Note: after saving the changes the AppArmor profiles will be reloaded.)")) {
|
||||
map argmap = $[ "PROFILE_HASH" : Settings["PROFILE_MAP"]:$[],
|
||||
map argmap = $[ "PROFILE_HASH" : Settings["PROFILE_MAP"]:$[],
|
||||
"PROFILE_NAME" : pathname
|
||||
];
|
||||
any result = SCR::Write(.subdomain_profiles, argmap);
|
||||
|
@ -677,7 +696,7 @@ define symbol DisplayProfileForm(string pathname, boolean hat) {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Select a profile to edit and populate
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
Summary: Yast2 plugins for AppArmor management
|
||||
Name: yast2-apparmor
|
||||
Version: @@immunix_version@@
|
||||
Release: 7.10
|
||||
Release: 7.11
|
||||
Group: Productivity/Security
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: GPL and LGPL
|
||||
|
@ -88,6 +88,8 @@ REPDIR3='/var/log/apparmor/reports-exported'
|
|||
%preun
|
||||
|
||||
%changelog
|
||||
* Thu Oct 5 2006 Dominic Reynolds <dreynolds@suse.de> 2.0-7.11
|
||||
- Add syntax checks for profiles and display to user.
|
||||
* Wed May 31 2006 Dominic Reynolds <dreynolds@suse.de> 2.0-7.10
|
||||
- Fixes for https://bugzilla.novell.com/show_bug.cgi?id=175388,
|
||||
https://bugzilla.novell.com/show_bug.cgi?id=172061. Added support
|
||||
|
|
|
@ -36,7 +36,7 @@ use Immunix::Severity;
|
|||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw(%sd $filename $profiledir $parser %qualifiers %include %helpers $UI_Mode which getprofilefilename getprofileflags setprofileflags complain enforce autodep reload UI_GetString UI_GetFile UI_YesNo UI_Important UI_Info getkey do_logprof_pass readconfig loadincludes check_for_subdomain UI_PromptUser $running_under_genprof GetDataFromYast SendDataToYast setup_yast shutdown_yast readprofile readprofiles writeprofile get_full_path fatal_error);
|
||||
our @EXPORT = qw(%sd $filename $profiledir $parser %qualifiers %include %helpers $UI_Mode which getprofilefilename getprofileflags setprofileflags complain enforce autodep reload UI_GetString UI_GetFile UI_YesNo UI_Important UI_Info getkey do_logprof_pass readconfig loadincludes check_for_subdomain UI_PromptUser $running_under_genprof GetDataFromYast SendDataToYast setup_yast shutdown_yast readprofile readprofiles writeprofile get_full_path fatal_error checkProfileSyntax checkIncludeSyntax);
|
||||
|
||||
no warnings 'all';
|
||||
|
||||
|
@ -95,6 +95,7 @@ our %qualifiers;
|
|||
our %required_hats;
|
||||
our %defaulthat;
|
||||
our %globmap;
|
||||
our @custom_includes;
|
||||
|
||||
# these are globs that the user specifically entered. we'll keep track of
|
||||
# them so that if one later matches, we'll suggest it again.
|
||||
|
@ -1359,7 +1360,7 @@ sub do_logprof_pass {
|
|||
%variables = ( );
|
||||
|
||||
UI_Info(sprintf(gettext('Reading log entries from %s.'), $filename));
|
||||
UI_Info(sprintf(gettext('Updating subdomain profiles in %s.'), $profiledir));
|
||||
UI_Info(sprintf(gettext('Updating AppArmor profiles in %s.'), $profiledir));
|
||||
|
||||
readprofiles();
|
||||
|
||||
|
@ -1778,15 +1779,24 @@ sub do_logprof_pass {
|
|||
|
||||
# check the path against the available set of include files
|
||||
my @newincludes;
|
||||
my $includevalid;
|
||||
for my $incname (keys %include) {
|
||||
$includevalid = 0;
|
||||
|
||||
# don't suggest it if we're already including it, that's dumb
|
||||
next if $sd{$profile}{$hat}{$incname};
|
||||
|
||||
# only match includes that can be suggested to the user
|
||||
for my $incmatch( @custom_includes ) {
|
||||
$includevalid = 1 if $incname =~ /$incmatch/;
|
||||
}
|
||||
$includevalid = 1 if $incname =~ /abstractions/;
|
||||
next if ( $includevalid == 0 );
|
||||
|
||||
($cm, @m) = matchinclude($incname, $path);
|
||||
if($cm && contains($cm, $mode)) {
|
||||
unless(grep { $_ eq "/**" } @m) {
|
||||
push @newincludes, $incname if $incname =~ /abstractions/;
|
||||
push @newincludes, $incname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2135,18 +2145,70 @@ sub contains ($$) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub checkIncludeSyntax($) {
|
||||
my $errors = shift;
|
||||
|
||||
|
||||
if(opendir(SDDIR, $profiledir )) {
|
||||
my @incdirs = grep { (! /^\./) && (-d "$profiledir/$_") } readdir(SDDIR);
|
||||
close(SDDIR);
|
||||
while(my $id = shift @incdirs) {
|
||||
if(opendir(SDDIR, "$profiledir/$id" )) {
|
||||
for my $path (grep { ! /^\./ } readdir(SDDIR)) {
|
||||
chomp($path);
|
||||
next if $path =~ /\.rpm(save|new)$/;
|
||||
if(-f "$profiledir/$id/$path") {
|
||||
my $file = "$id/$path";
|
||||
$file =~ s/$profiledir\///;
|
||||
my $err = loadinclude($file, \&printMessageErrorHandler);
|
||||
if ( $err ne 0 ) {
|
||||
push @$errors, $err;
|
||||
}
|
||||
} elsif(-d "$id/$path") {
|
||||
push @incdirs, "$id/$path";
|
||||
}
|
||||
}
|
||||
closedir(SDDIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
|
||||
sub checkProfileSyntax ($) {
|
||||
my $errors = shift;
|
||||
# Check the syntax of profiles
|
||||
|
||||
opendir(SDDIR, $profiledir) or fatal_error "Can't read AppArmor profiles in $profiledir.";
|
||||
for my $file (grep { -f "$profiledir/$_" } readdir(SDDIR)) {
|
||||
next if $file =~ /\.rpm(save|new)$/;
|
||||
my $err = readprofile( "$profiledir/$file", \&printMessageErrorHandler);
|
||||
if ( defined $err and $err ne 1) {
|
||||
push @$errors, $err;
|
||||
}
|
||||
}
|
||||
closedir(SDDIR);
|
||||
return $errors;
|
||||
}
|
||||
|
||||
sub printMessageErrorHandler ($) {
|
||||
my $message = shift;
|
||||
return $message
|
||||
}
|
||||
|
||||
sub readprofiles () {
|
||||
opendir(SDDIR, $profiledir) or fatal_error "Can't read AppArmor profiles in $profiledir.";
|
||||
for my $file (grep { -f "$profiledir/$_" } readdir(SDDIR)) {
|
||||
next if $file =~ /\.rpm(save|new)$/;
|
||||
readprofile("$profiledir/$file");
|
||||
readprofile("$profiledir/$file", \&fatal_error);
|
||||
}
|
||||
closedir(SDDIR);
|
||||
}
|
||||
|
||||
sub readprofile ($) {
|
||||
sub readprofile ($$) {
|
||||
my $file = shift;
|
||||
|
||||
my $error_handler = shift;
|
||||
if(open(SDPROF, "$file")) {
|
||||
my ($profile, $hat, $in_contained_hat);
|
||||
my $initial_comment = "";
|
||||
|
@ -2162,7 +2224,7 @@ sub readprofile ($) {
|
|||
# if we run into the start of a profile while we're already in a
|
||||
# profile, something's wrong...
|
||||
if($profile) {
|
||||
fatal_error "$profile profile in $file contains syntax errors.";
|
||||
return &$error_handler( "$profile profile in $file contains syntax errors.");
|
||||
}
|
||||
|
||||
# we hit the start of a profile, keep track of it...
|
||||
|
@ -2202,7 +2264,7 @@ sub readprofile ($) {
|
|||
# if we hit the end of a profile when we're not in one, something's
|
||||
# wrong...
|
||||
if(not $profile) {
|
||||
fatal_error(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
return &$error_handler( sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
}
|
||||
|
||||
if($in_contained_hat) {
|
||||
|
@ -2232,7 +2294,7 @@ sub readprofile ($) {
|
|||
|
||||
} elsif(m/^\s*capability\s+(\S+)\s*,\s*$/) { # capability entry
|
||||
if(not $profile) {
|
||||
fatal_error(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
return &$error_handler(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
}
|
||||
|
||||
my $capability = $1;
|
||||
|
@ -2246,7 +2308,7 @@ sub readprofile ($) {
|
|||
} elsif(m/^\s*if\s+(not\s+)?defined\s+(\$\{?[[:alpha:]][[:alnum:]_]+\}?)\s*\{\s*$/) { # conditional -- boolean defined
|
||||
} elsif(m/^\s*([\"\@\/].*)\s+(\S+)\s*,\s*$/) { # path entry
|
||||
if(not $profile) {
|
||||
fatal_error(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
return &$error_handler(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
}
|
||||
|
||||
my ($path, $mode) = ($1, $2);
|
||||
|
@ -2260,7 +2322,7 @@ sub readprofile ($) {
|
|||
my $p_re = convert_regexp($path);
|
||||
eval { "foo" =~ m/^$p_re$/; };
|
||||
if($@) {
|
||||
fatal_error sprintf(gettext('Profile %s contains invalid regexp %s.'), $file, $path);
|
||||
return &$error_handler(sprintf(gettext('Profile %s contains invalid regexp %s.'), $file, $path));
|
||||
}
|
||||
|
||||
$sd{$profile}{$hat}{path}{$path} = $mode;
|
||||
|
@ -2276,12 +2338,12 @@ sub readprofile ($) {
|
|||
}
|
||||
$variables{$file}{"#" . $include} = 1; # sorry
|
||||
}
|
||||
|
||||
loadinclude($include);
|
||||
my $ret = loadinclude($include, $error_handler);
|
||||
return $ret if ( $ret != 0 );
|
||||
|
||||
} elsif(/^\s*(tcp_connect|tcp_accept|udp_send|udp_receive)/) {
|
||||
if(not $profile) {
|
||||
fatal_error(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
return &$error_handler(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
}
|
||||
|
||||
# XXX - BUGBUGBUG - don't strip netdomain entries
|
||||
|
@ -2301,7 +2363,7 @@ sub readprofile ($) {
|
|||
# if we hit the start of a contained hat when we're not in a profile
|
||||
# something is wrong...
|
||||
if(not $profile) {
|
||||
fatal_error(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
return &$error_handler(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
}
|
||||
|
||||
$in_contained_hat = 1;
|
||||
|
@ -2338,20 +2400,19 @@ sub readprofile ($) {
|
|||
} else {
|
||||
|
||||
# we hit something we don't understand in a profile...
|
||||
fatal_error(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
return &$error_handler(sprintf(gettext('%s contains syntax errors.'), $file));
|
||||
}
|
||||
}
|
||||
|
||||
# if we're still in a profile when we hit the end of the file, it's bad
|
||||
if($profile) {
|
||||
fatal_error "Reached the end of $file while we were still inside the $profile profile.";
|
||||
return &$error_handler("Reached the end of $file while we were still inside the $profile profile.");
|
||||
}
|
||||
|
||||
close(SDPROF);
|
||||
} else {
|
||||
$DEBUGGING && debug "readprofile: can't read $file - skipping";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub escape($) {
|
||||
|
@ -2476,7 +2537,7 @@ sub writeprofile ($) {
|
|||
|
||||
open(SDPROF, ">$filename") or fatal_error "Can't write new AppArmor profile $filename: $!";
|
||||
|
||||
# stick in a vim mode line to turn on subdomain syntax highlighting
|
||||
# stick in a vim mode line to turn on AppArmor syntax highlighting
|
||||
print SDPROF "# vim:syntax=apparmor\n";
|
||||
|
||||
# keep track of when the file was last updated
|
||||
|
@ -2557,7 +2618,7 @@ sub matchliteral {
|
|||
sub reload ($) {
|
||||
my $bin = shift;
|
||||
|
||||
# don't try to reload profile if subdomain is not running
|
||||
# don't try to reload profile if AppArmor is not running
|
||||
return unless check_for_subdomain();
|
||||
|
||||
# don't reload the profile if the corresponding executable doesn't exist
|
||||
|
@ -2570,9 +2631,10 @@ sub reload ($) {
|
|||
|
||||
sub loadinclude {
|
||||
my $which= shift;
|
||||
my $error_handler = shift;
|
||||
|
||||
# don't bother loading it again if we already have
|
||||
return if $include{$which};
|
||||
return 0 if $include{$which};
|
||||
|
||||
my @loadincludes = ( $which );
|
||||
while(my $incfile = shift @loadincludes) {
|
||||
|
@ -2602,7 +2664,7 @@ sub loadinclude {
|
|||
my $p_re = convert_regexp($path);
|
||||
eval { "foo" =~ m/^$p_re$/; };
|
||||
if($@) {
|
||||
fatal_error sprintf(gettext('Include %s contains invalid regexp %s.'), $incfile, $path);
|
||||
return &$error_handler(sprintf(gettext('Include file %s contains invalid regexp %s.'), $incfile, $path));
|
||||
}
|
||||
|
||||
$include{$incfile}{path}{$path} = $mode;
|
||||
|
@ -2625,12 +2687,12 @@ sub loadinclude {
|
|||
next if /^\s*\#/;
|
||||
|
||||
# we hit something we don't understand in a profile...
|
||||
fatal_error sprintf(gettext('%s contains syntax errors.'), $incfile);
|
||||
return &$error_handler(sprintf(gettext('Include file %s contains syntax errors or is not a valid #include file.'), $incfile));
|
||||
}
|
||||
|
||||
}
|
||||
close(INCLUDE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub rematchfrag{
|
||||
|
@ -2664,7 +2726,7 @@ sub matchincludes {
|
|||
# scan the include fragments for this profile looking for matches
|
||||
my @includelist = keys %{$frag->{include}};
|
||||
while(my $include = shift @includelist) {
|
||||
loadinclude($include);
|
||||
loadinclude($include, \&fatal_error);
|
||||
my ($cm, @m) = rematchfrag($include{$include}, $path);
|
||||
if($cm) {
|
||||
$combinedmode .= $cm;
|
||||
|
@ -2741,6 +2803,11 @@ sub readconfig () {
|
|||
} elsif($which eq "required_hats") {
|
||||
$required_hats{$key} = $value;
|
||||
}
|
||||
} elsif(m/^\s*(\S+)\s*$/) {
|
||||
my $val = $1;
|
||||
if($which eq "custom_includes") {
|
||||
push @custom_includes, $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(LPCONF);
|
||||
|
@ -2760,7 +2827,7 @@ if(opendir(SDDIR, $profiledir )) {
|
|||
if(-f "$profiledir/$id/$path") {
|
||||
my $file = "$id/$path";
|
||||
$file =~ s/$profiledir\///;
|
||||
loadinclude($file);
|
||||
loadinclude($file, \&fatal_error);
|
||||
} elsif(-d "$id/$path") {
|
||||
push @incdirs, "$id/$path";
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
Summary: AppArmor userlevel utilities that are useful in creating AppArmor profiles.
|
||||
Name: apparmor-utils
|
||||
Version: @@immunix_version@@
|
||||
Release: 6
|
||||
Release: 7
|
||||
Group: Productivity/Security
|
||||
Source0: %{name}-%{version}-@@repo_version@@.tar.gz
|
||||
License: GPL
|
||||
|
@ -95,6 +95,8 @@ fi
|
|||
|
||||
|
||||
%changelog
|
||||
* Thu Oct 5 2006 - <dreynolds@suse.de> 2.0-7
|
||||
- add support syntax checking for profiles.
|
||||
* Thu Jun 01 2006 - jmichael@suse.de
|
||||
- add support for the new m mode (#175388)
|
||||
- add support for the new Px/Ux modes (#172061)
|
||||
|
|
|
@ -98,3 +98,14 @@
|
|||
|
||||
^/etc/pam.d/[^\/]+$ = /etc/pam.d/*
|
||||
^/etc/profile.d/[^\/]+\.sh$ = /etc/profile.d/*.sh
|
||||
|
||||
[custom_includes]
|
||||
# custom directory locations to look for #includes
|
||||
#
|
||||
# One directory name per-line - each name should be a valid directory
|
||||
# containing possble #include candidate fies under the profile dir
|
||||
# which by default is /etc/apparmor.d.
|
||||
# So an entry of my-includes will allow /etc/apparmor.d/my-includes to
|
||||
# be used by the yast UI and profiling tools as a source of #include
|
||||
# files.
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue