File apparmor-utils-logparse.diff of Package apparmor-utils
Index: trunk/utils/SubDomain.pm
===================================================================
--- trunk.orig/utils/SubDomain.pm
+++ trunk/utils/SubDomain.pm
@@ -39,6 +39,7 @@ use Storable qw(dclone);
use Term::ReadKey;
use Immunix::Severity;
+use LibAppArmor;
require Exporter;
our @ISA = qw(Exporter);
@@ -2069,33 +2070,9 @@ sub parse_log_record_v_2_0 ($@) {
return $last;
}
-sub parse_log_record_v_2_1 ($) {
- $_ = shift;
- $DEBUGGING && debug "parse_log_record_v_2_1: $_";
- return if ( ! $_ );
- my $e = { };
-
- # first pull out any name="blah blah blah" strings
- s/\b(\w+)="([^"]+)"\s*/$e->{$1} = $2; "";/ge;
-
- # yank off any remaining name=value pairs
- s/\b(\w+)=(\S+)\)\'\s*/$e->{$1} = $2; "";/ge;
- s/\b(\w+)=(\S+)\,\s*/$e->{$1} = $2; "";/ge;
- s/\b(\w+)=(\S+)\s*/$e->{$1} = $2; "";/ge;
-
- s/\s$//;
-
- # audit_log_untrustedstring() is used for name, name2, and profile in
- # order to escape strings with special characters
- for my $key (keys %$e) {
- next unless $key =~ /^(name|name2|profile)$/;
- # needs to be an even number of hex characters
- if ($e->{$key} =~ /^([0-9a-f]{2})+$/i) {
- # convert the hex string back to a raw string
- $e->{$key} = pack("H*", $e->{$key});
- }
- }
-
+sub parse_log_record ($) {
+ my $record = shift;
+ my $e = parse_event($record);
if ($e->{requested_mask} && !validate_log_mode($e->{requested_mask})) {
fatal_error(sprintf(gettext('Log contains unknown mode %s.'), $e->{requested_mask}));
}
@@ -2103,32 +2080,35 @@ sub parse_log_record_v_2_1 ($) {
if ($e->{denied_mask} && !validate_log_mode($e->{denied_mask})) {
fatal_error(sprintf(gettext('Log contains unknown mode %s.'), $e->{denied_mask}));
}
-
return $e;
}
+
sub add_event_to_tree ($) {
my $e = shift;
- my $sdmode = "NONE";
- if ( $e->{type} =~ /(UNKNOWN\[1501\]|APPARMOR_AUDIT|1501)/ ) {
- $sdmode = "AUDIT";
- } elsif ( $e->{type} =~ /(UNKNOWN\[1502\]|APPARMOR_ALLOWED|1502)/ ) {
- $sdmode = "PERMITTING";
- } elsif ( $e->{type} =~ /(UNKNOWN\[1503\]|APPARMOR_DENIED|1503)/ ) {
- $sdmode = "REJECTING";
- } elsif ( $e->{type} =~ /(UNKNOWN\[1504\]|APPARMOR_HINT|1504)/ ) {
- $sdmode = "HINT";
- } elsif ( $e->{type} =~ /(UNKNOWN\[1505\]|APPARMOR_STATUS|1505)/ ) {
- $sdmode = "STATUS";
- return;
- } elsif ( $e->{type} =~ /(UNKNOWN\[1506\]|APPARMOR_ERROR|1506)/ ) {
- $sdmode = "ERROR";
- return;
- } else {
- $sdmode = "UNKNOWN_SD_MODE";
- return;
+ my $sdmode = $e->{sdmode}?$e->{sdmode}:"";
+ if ( $e->{type} ) {
+ if ( $e->{type} =~ /(UNKNOWN\[1501\]|APPARMOR_AUDIT|1501)/ ) {
+ $sdmode = "AUDIT";
+ } elsif ( $e->{type} =~ /(UNKNOWN\[1502\]|APPARMOR_ALLOWED|1502)/ ) {
+ $sdmode = "PERMITTING";
+ } elsif ( $e->{type} =~ /(UNKNOWN\[1503\]|APPARMOR_DENIED|1503)/ ) {
+ $sdmode = "REJECTING";
+ } elsif ( $e->{type} =~ /(UNKNOWN\[1504\]|APPARMOR_HINT|1504)/ ) {
+ $sdmode = "HINT";
+ } elsif ( $e->{type} =~ /(UNKNOWN\[1505\]|APPARMOR_STATUS|1505)/ ) {
+ $sdmode = "STATUS";
+ return;
+ } elsif ( $e->{type} =~ /(UNKNOWN\[1506\]|APPARMOR_ERROR|1506)/ ) {
+ $sdmode = "ERROR";
+ return;
+ } else {
+ $sdmode = "UNKNOWN_SD_MODE";
+ return;
+ }
}
+ return if ( $sdmode eq "" );
my ($profile, $hat);
($profile, $hat) = split /\/\//, $e->{profile};
@@ -2194,7 +2174,7 @@ sub add_event_to_tree ($) {
my $following = peek_at_next_log_entry();
if ($following) {
- my $entry = parse_log_record_v_2_1($following);
+ my $entry = parse_log_record($following);
if ($entry &&
$entry->{info} &&
$entry->{info} eq "set profile" ) {
@@ -2291,12 +2271,9 @@ sub read_log {
# all we care about is apparmor messages
if (/$RE_LOG_v2_0_syslog/ || /$RE_LOG_v2_0_audit/) {
$last_match = parse_log_record_v_2_0( $_, $last_match );
- } elsif (/$RE_LOG_v2_1_audit/ || /$RE_LOG_v2_1_syslog/) {
- my $event = parse_log_record_v_2_1($_);
- add_event_to_tree($event);
} else {
- # not a known apparmor log event
- $DEBUGGING && debug "read_log UNHANDLED: $_";
+ my $event = parse_log_record($_);
+ add_event_to_tree($event) if ( $event );
}
}
close($LOG);
@@ -5395,6 +5372,70 @@ sub Text_PromptUser ($) {
}
+# Parse event record into key-value pairs
+sub parse_event($) {
+ my %ev = ();
+ my $msg = shift;
+ chomp($msg);
+ my $event = LibAppArmor::parse_record($msg);
+
+ $ev{'resource'} = LibAppArmor::aa_log_record::swig_info_get($event);
+ $ev{'active_hat'} = LibAppArmor::aa_log_record::swig_active_hat_get($event);
+ $ev{'sdmode'} = LibAppArmor::aa_log_record::swig_event_get($event);
+ $ev{'time'} = LibAppArmor::aa_log_record::swig_epoch_get($event);
+ $ev{'operation'} = LibAppArmor::aa_log_record::swig_operation_get($event);
+ $ev{'profile'} = LibAppArmor::aa_log_record::swig_profile_get($event);
+ $ev{'name'} = LibAppArmor::aa_log_record::swig_name_get($event);
+ $ev{'name2'} = LibAppArmor::aa_log_record::swig_name2_get($event);
+ $ev{'attr'} = LibAppArmor::aa_log_record::swig_attribute_get($event);
+ $ev{'parent'} = LibAppArmor::aa_log_record::swig_parent_get($event);
+ $ev{'pid'} = LibAppArmor::aa_log_record::swig_pid_get($event);
+ $ev{'denied_mask'} =
+ LibAppArmor::aa_log_record::swig_denied_mask_get($event);
+ $ev{'request_mask'} =
+ LibAppArmor::aa_log_record::swig_requested_mask_get($event);
+ $ev{'magic_token'} =
+ LibAppArmor::aa_log_record::swig_magic_token_get($event);
+
+ # NetDomain
+ if ( $ev{'operation'} && $ev{'operation'} =~ /socket/ ) {
+ $ev{'family'} =
+ LibAppArmor::aa_log_record::swig_net_family_get($event);
+ $ev{'protocol'} =
+ LibAppArmor::aa_log_record::swig_net_protocol_get($event);
+ $ev{'sock_type'} =
+ LibAppArmor::aa_log_record::swig_net_sock_type_get($event);
+ }
+
+ LibAppArmor::free_record($event);
+
+ if ( ! $ev{'time'} ) { $ev{'time'} = time; }
+
+ # remove null responses
+ for (keys(%ev)) {
+ if ( ! $ev{$_} || $ev{$_} !~ /\w+/) { delete($ev{$_}); }
+ }
+
+ if ( $ev{'sdmode'} ) {
+ #0 = invalid, 1 = error, 2 = AUDIT, 3 = ALLOW/PERMIT,
+ #4 = DENIED/REJECTED, 5 = HINT, 6 = STATUS/config change
+ if ( $ev{'sdmode'} == 0 ) { $ev{'sdmode'} = "UNKNOWN"; }
+ elsif ( $ev{'sdmode'} == 1 ) { $ev{'sdmode'} = "ERROR"; }
+ elsif ( $ev{'sdmode'} == 2 ) { $ev{'sdmode'} = "AUDITING"; }
+ elsif ( $ev{'sdmode'} == 3 ) { $ev{'sdmode'} = "PERMITTING"; }
+ elsif ( $ev{'sdmode'} == 4 ) { $ev{'sdmode'} = "REJECTING"; }
+ elsif ( $ev{'sdmode'} == 5 ) { $ev{'sdmode'} = "HINT"; }
+ elsif ( $ev{'sdmode'} == 6 ) { $ev{'sdmode'} = "STATUS"; }
+ else { delete($ev{'sdmode'}); }
+ }
+ if ( $ev{sdmode} ) {
+ $DEBUGGING && debug( Data::Dumper->Dump([%ev], [qw(*event)]));
+ return \%ev;
+ } else {
+ return( undef );
+ }
+}
+
###############################################################################
# required initialization