~ubuntu-branches/ubuntu/oneiric/apparmor/oneiric-security

« back to all changes in this revision

Viewing changes to utils/aa-eventd

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2011-04-27 10:38:07 UTC
  • mfrom: (5.1.118 natty)
  • Revision ID: james.westby@ubuntu.com-20110427103807-ym3rhwys6o84ith0
Tags: 2.6.1-2
debian/copyright: clarify for some full organization names.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/perl -w
2
2
 
3
 
# $Id: aa-eventd 458 2007-03-20 22:58:38Z jmichael-at-suse-de $
4
 
#
5
3
# ----------------------------------------------------------------------
6
4
#    Copyright (c) 2005 Novell, Inc. All Rights Reserved.
7
5
#
33
31
use File::Tail;
34
32
 
35
33
use Immunix::Severity;
 
34
require LibAppArmor;
36
35
 
37
36
##########################################################################
38
37
# locations
93
92
my $total   = 0;
94
93
 
95
94
my @commit_buffer;
 
95
my @debug_buffer;
96
96
 
97
97
my @verbose_buffer;
98
98
my @summary_buffer;
101
101
my $date_module = "None";
102
102
 
103
103
my %templates = (
104
 
    "path"                => "(time,counter,type,profile,sdmode,mode,resource,prog,pid,severity)   VALUES(?,?,'path',?,?,?,?,?,?,?)",
105
 
    "link"                => "(time,counter,type,profile,sdmode,resource,target,prog,pid,severity) VALUES(?,?,'link',?,?,?,?,?,?,?)",
106
 
    "chattr"              => "(time,counter,type,profile,sdmode,resource,mode,prog,pid,severity)   VALUES(?,?,'chattr',?,?,?,?,?,?,?)",
107
 
    "capability"          => "(time,counter,type,profile,sdmode,resource,prog,pid,severity)        VALUES(?,?,'capability',?,?,?,?,?,?)",
108
 
    "unknown_hat"         => "(time,counter,type,profile,sdmode,resource,pid)                      VALUES(?,?,'unknown_hat',?,?,?,?)",
109
 
    "fork"                => "(time,counter,type,profile,sdmode,pid,resource)                      VALUES(?,?,'fork',?,?,?,?)",
110
 
    "changing_profile"    => "(time,counter,type,profile,sdmode,pid)                               VALUES(?,?,'changing_profile',?,?,?)",
111
 
    "profile_replacement" => "(time,counter,type,profile,sdmode,prog,pid,severity)                 VALUES(?,?,'profile_replacement',?,?,?,?,?)",
112
 
    "removed"             => "(time,counter,type,severity)                                         VALUES(?,?,'removed',?)",
113
 
    "initialized"         => "(time,counter,type,resource,severity)                                VALUES(?,?,'initialized',?,?)",
114
 
    "ctrl_var"            => "(time,counter,type,resource,mode,severity)                           VALUES(?,?,'ctrl_var',?,?,?)",
 
104
    "path"                => "(time,counter,type,op,profile,sdmode,mode_req,mode_deny,resource,prog,pid,severity) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)",
 
105
    "link"                => "(time,counter,type,op,profile,sdmode,resource,target,prog,pid,severity)    VALUES(?,?,?,?,?,?,?,?,?,?,?)",
 
106
    "chattr"              => "(time,counter,type,op,profile,sdmode,resource,mode_req,mode_deny,prog,pid,severity) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)",
 
107
    "capability"          => "(time,counter,type,op,profile,sdmode,resource,prog,pid,severity)           VALUES(?,?,?,?,?,?,?,?,?,?)",
 
108
    "capable"             => "(time,counter,type,op,prog,pid,profile)                                    VALUES(?,?,?,?,?,?,?)",
 
109
    "unknown_hat"         => "(time,counter,type,op,profile,sdmode,resource,pid)                         VALUES(?,?,?,?,?,?,?,?)",
 
110
    "fork"                => "(time,counter,type,op,profile,sdmode,pid,resource)                         VALUES(?,?,?,?,?,?,?,?)",
 
111
    "changing_profile"    => "(time,counter,type,op,profile,sdmode,pid)                                  VALUES(?,?,?,?,?,?,?)",
 
112
    "profile_replacement" => "(time,counter,type,op,profile,sdmode,prog,pid,severity)                    VALUES(?,?,?,?,?,?,?,?,?)",
 
113
        "net"                 => "(time,counter,type,op,net_family,net_socktype,net_proto,pid,profile)       VALUES(?,?,?,?,?,?,?,?,?)",
 
114
    "removed"             => "(time,counter,type,op,severity)                                            VALUES(?,?,?,?,?)",
 
115
    "initialized"         => "(time,counter,type,op,resource,severity)                                   VALUES(?,?,?,?,?,?)",
 
116
    "ctrl_var"            => "(time,counter,type,op,resource,mode_req,mode_deny,severity)                         VALUES(?,?,?,?,?,?,?,?)",
 
117
        "profile_load"        => "(time,counter,type,op,resource,prog,pid)                                   VALUES(?,?,?,?,?,?,?)",
115
118
);
116
119
 
117
120
##########################################################################
119
122
 
120
123
sub errlog ($) {
121
124
    my $mesg = shift;
122
 
 
123
125
    my $localtime = localtime(time);
124
126
    print ERRLOG "[$localtime] $mesg\n";
125
127
}
126
128
 
127
129
sub readconfig () {
128
 
 
129
130
    my $cfg = {};
130
131
 
131
132
    # record when we read the config file
174
175
sub connect_database ($) {
175
176
    my $dbdir = shift;
176
177
 
177
 
    my $dbh = DBI->connect("dbi:SQLite:dbname=$dbdir/events.db", "", "");
 
178
    my $dbh = DBI->connect("dbi:SQLite:dbname=$dbdir/events.db", "", "", {RaiseError=>1});
178
179
 
179
180
    # we'll do the commits ourselves so performance doesn't suck
180
181
    $dbh->{AutoCommit} = 0;
199
200
 
200
201
        $dbh->do("CREATE TABLE info (name,value)");
201
202
        $sth = $dbh->prepare("INSERT INTO info(name,value) VALUES(?,?)");
202
 
        $sth->execute("version", "0.1");
 
203
        $sth->execute("version", "0.2");
203
204
        $sth->execute("host",    "$host");
204
205
    }
205
206
 
206
 
    # create the events table
 
207
        # create the events table
207
208
    unless ($existing_tables{events}) {
208
209
        $dbh->do(
209
210
            "CREATE TABLE events (
210
211
                id       INTEGER PRIMARY KEY AUTOINCREMENT,
211
212
                time     INTEGER NOT NULL,
212
213
                counter  INTEGER NOT NULL,
 
214
                op,
213
215
                pid,
214
216
                sdmode,
215
217
                type,
216
 
                mode,
 
218
                mode_deny,
 
219
                mode_req,
217
220
                resource,
218
221
                target,
219
222
                profile,
220
223
                prog,
 
224
                name_alt,
 
225
                attr,
 
226
                parent,
 
227
                active_hat,
 
228
                net_family,
 
229
                net_proto,
 
230
                net_socktype,
221
231
                severity INTEGER
222
 
              )"
 
232
             )"
223
233
        );
224
234
 
225
235
        # set up the indexes we want
226
 
        my @indexes = qw(time type sdmode mode resource profile prog severity);
 
236
        #my @indexes = qw(time type sdmode mode resource profile prog severity);
 
237
        my @indexes = qw(time type op sdmode mode_req mode_deny resource profile prog severity);
227
238
        for my $index (@indexes) {
228
239
            $dbh->do("CREATE INDEX " . $index . "_idx ON events($index)");
229
240
        }
230
241
    }
231
 
 
232
242
    # make sure our changes actually get saved
233
243
    $dbh->commit || errlog "Error commiting changes: $!";
234
244
 
401
411
}
402
412
 
403
413
##########################################################################
 
414
# Parse event record into key-value pairs
 
415
sub parseEvent($) {
 
416
 
 
417
    my %ev = ();
 
418
    my $msg = shift;
 
419
        chomp($msg);
 
420
 
 
421
    my $event = LibAppArmor::parse_record($msg);
 
422
 
 
423
    # resource is an alternate term for 'name1' below
 
424
    # mode is an alternate term for 'mode_deny' below
 
425
    $ev{'time'} = LibAppArmor::aa_log_record::swig_epoch_get($event);
 
426
    $ev{'op'} = LibAppArmor::aa_log_record::swig_operation_get($event);
 
427
    $ev{'pid'} = LibAppArmor::aa_log_record::swig_pid_get($event);
 
428
    $ev{'mode_deny'} = LibAppArmor::aa_log_record::swig_denied_mask_get($event);
 
429
    $ev{'mode_req'} = LibAppArmor::aa_log_record::swig_requested_mask_get($event);
 
430
    $ev{'profile'}= LibAppArmor::aa_log_record::swig_profile_get($event);
 
431
    $ev{'prog'} = LibAppArmor::aa_log_record::swig_name_get($event);
 
432
    $ev{'name2'} = LibAppArmor::aa_log_record::swig_name2_get($event);
 
433
    $ev{'attr'} = LibAppArmor::aa_log_record::swig_attribute_get($event);
 
434
    $ev{'parent'} = LibAppArmor::aa_log_record::swig_parent_get($event);
 
435
    $ev{'magic_token'} = LibAppArmor::aa_log_record::swig_magic_token_get($event);
 
436
    $ev{'resource'} = LibAppArmor::aa_log_record::swig_info_get($event);
 
437
    $ev{'active_hat'} = LibAppArmor::aa_log_record::swig_active_hat_get($event);
 
438
    $ev{'sdmode'} = LibAppArmor::aa_log_record::swig_event_get($event);
 
439
 
 
440
        # NetDomain 
 
441
        if ( $ev{'op'} && $ev{'op'} =~ /socket/ ) {
 
442
                next if $ev{'op'} =~ /create/;
 
443
                $ev{'net_family'} = LibAppArmor::aa_log_record::swig_net_family_get($event);
 
444
                $ev{'net_proto'} = LibAppArmor::aa_log_record::swig_net_protocol_get($event);
 
445
                $ev{'net_socktype'} = LibAppArmor::aa_log_record::swig_net_sock_type_get($event);
 
446
        }
 
447
 
 
448
    LibAppArmor::free_record($event);
 
449
 
 
450
    if ( ! $ev{'time'} ) { $ev{'time'} = time; }
 
451
 
 
452
    # remove null responses
 
453
    for (keys(%ev)) {
 
454
                if ( ! $ev{$_} || $ev{$_} !~ /\w+/) {delete($ev{$_}); }
 
455
                #errlog "EVENT:  $_ is $ev{$_}";
 
456
    }
 
457
 
 
458
    if ( $ev{'sdmode'} ) {
 
459
        #0 = invalid, 1 = error, 2 = AUDIT, 3 = ALLOW/PERMIT,
 
460
        #4 = DENIED/REJECTED, 5 = HINT, 6 = STATUS/config change
 
461
        if    ( $ev{'sdmode'} == 2 ) { $ev{'sdmode'} = "AUDITING"; }
 
462
        elsif ( $ev{'sdmode'} == 3 ) { $ev{'sdmode'} = "PERMITING"; }
 
463
        elsif ( $ev{'sdmode'} == 4 ) { $ev{'sdmode'} = "REJECTING"; }
 
464
        else  { delete($ev{'sdmode'}); }
 
465
    }
 
466
 
 
467
    return \%ev;
 
468
}
404
469
 
405
470
sub process_event ($$) {
 
471
 
406
472
    my $dbh    = shift;
407
473
    my $logmsg = shift;
408
474
    my $sth;
409
 
 
410
 
    my ($time, $mesg);
411
 
    if ($logmsg =~ /^(?:type=(?:APPARMOR|UNKNOWN\[1500\]) msg=|$REdate\s+\S+\s+(?:kernel:\s+)*)audit\((\d+).\d+:\d+\): (.+)$/) {
412
 
        ($time, $mesg) = ($1, $2);
413
 
 
414
 
        # have we rolled over to another second yet?
415
 
        if ($time ne $lasttime) {
416
 
            $counter   = 0;
417
 
            $timestamp = $time;
418
 
            $lasttime  = $time;
419
 
        }
420
 
    } elsif ($logmsg =~ /^\s*($REdate)\s+\S+\s+(?:kernel:\s+)*(SubDomain|AppArmor):\s+(.+)$/) {
421
 
        ($time, $mesg) = ($1, $3);
422
 
 
423
 
        # have we rolled over to another second yet?
424
 
        if ($time ne $lasttime) {
425
 
            $counter   = 0;
426
 
            $timestamp = parsedate($time);
427
 
            $lasttime  = $time;
428
 
        }
429
 
    } else {
430
 
 
431
 
        # not one of ours, just return
432
 
        return;
 
475
    my $severity = "";
 
476
        my @eventList = ();
 
477
        my $type = undef;
 
478
        my $time = undef;
 
479
 
 
480
        return unless $logmsg && $logmsg =~ /APPARMOR/;
 
481
        my $ev = parseEvent($logmsg);
 
482
 
 
483
    # skip logprof hints
 
484
    if ( ! $ev->{'op'} || $ev->{'op'} eq 'clone') { return; }
 
485
 
 
486
        $time = time;           # XXX - do we want current time or $ev->{'time'}?
 
487
 
 
488
    if ($time ne $lasttime) {
 
489
        $counter   = 0;
 
490
        $timestamp = $time;
 
491
        $lasttime  = $time;
433
492
    }
434
493
 
435
494
    $counter++;
449
508
        $last_inserted_time = undef;
450
509
    }
451
510
 
452
 
    # workaround for syslog uglyness.
453
 
    if ($mesg =~ s/(PERMITTING|REJECTING|AUDITING)-SYSLOGFIX/$1/) {
454
 
        $mesg =~ s/%%/%/g;
455
 
    }
456
 
 
457
 
    if ($mesg =~ /(PERMITTING|REJECTING|AUDITING) (\S+) access to (.+?) \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
458
 
        my ($sdmode, $mode, $resource, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6, $7);
459
 
 
460
 
        $profile .= "^$hat" if $profile ne $hat;
461
 
 
462
 
        my $severity = "";
463
 
        if ($sdmode eq "REJECTING") {
464
 
            $severity = $sevdb->rank($resource, $mode);
465
 
 
466
 
            # we only do notification for enforce mode events
467
 
            if ($config->{verbose_freq}) {
468
 
                if (   ($severity >= $config->{verbose_level})
469
 
                    || (($severity == -1) && $config->{verbose_unknown}))
470
 
                {
471
 
                    push @verbose_buffer, [ $timestamp, $counter, $logmsg ];
472
 
                }
473
 
            }
474
 
 
475
 
            if ($config->{summary_freq}) {
476
 
                if (   ($severity >= $config->{summary_level})
477
 
                    || (($severity == -1) && $config->{summary_unknown}))
478
 
                {
479
 
                    push @summary_buffer, [ $timestamp, $counter, "path", $prog, $mode, $resource ];
480
 
                }
481
 
            }
482
 
 
483
 
            if ($config->{terse_freq}) {
484
 
                if (   ($severity >= $config->{terse_level})
485
 
                    || (($severity == -1) && $config->{terse_unknown}))
486
 
                {
487
 
                    push @terse_buffer, [ $timestamp, $counter, "dummy" ];
488
 
                }
489
 
            }
490
 
 
491
 
        }
492
 
 
493
 
        push @commit_buffer, [ "path", $timestamp, $counter, $profile, $sdmode, $mode, $resource, $prog, $pid, $severity ];
494
 
        $inserts++;
495
 
 
496
 
    } elsif ($mesg =~ /(PERMITTING|REJECTING|AUDITING) link access from (.+?) to (.+?) \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
497
 
        my ($sdmode, $link, $target, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6, $7);
498
 
 
499
 
        $profile .= "^$hat" if $profile ne $hat;
500
 
 
501
 
        my $severity = "";
502
 
        if ($sdmode eq "REJECTING") {
503
 
            $severity = $sevdb->rank($target, "l");
504
 
 
505
 
            # we only do notification for enforce mode events
506
 
            if ($config->{verbose_freq}) {
507
 
                if (   ($severity >= $config->{verbose_level})
508
 
                    || (($severity == -1) && $config->{verbose_unknown}))
509
 
                {
510
 
                    push @verbose_buffer, [ $timestamp, $counter, $logmsg ];
511
 
                }
512
 
            }
513
 
 
514
 
            if ($config->{summary_freq}) {
515
 
                if (   ($severity >= $config->{summary_level})
516
 
                    || (($severity == -1) && $config->{summary_unknown}))
517
 
                {
518
 
                    push @summary_buffer, [ $timestamp, $counter, "link", $prog, $link, $target ];
519
 
                }
520
 
            }
521
 
 
522
 
            if ($config->{terse_freq}) {
523
 
                if (   ($severity >= $config->{terse_level})
524
 
                    || (($severity == -1) && $config->{terse_unknown}))
525
 
                {
526
 
                    push @terse_buffer, [ $timestamp, $counter ];
527
 
                }
528
 
            }
529
 
        }
530
 
 
531
 
        push @commit_buffer, [ "link", $timestamp, $counter, $profile, $sdmode, $link, $target, $prog, $pid, $severity ];
532
 
        $inserts++;
533
 
 
534
 
    } elsif ($mesg =~ /(PERMITTING|REJECTING|AUDITING) attribute \((\S*)\) change to (.+)? \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
535
 
        my ($sdmode, $attrch, $resource, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6, $7);
536
 
 
537
 
        $profile .= "^$hat" if $profile ne $hat;
538
 
 
539
 
        my $severity = "";
540
 
        if ($sdmode eq "REJECTING") {
541
 
            $severity = $sevdb->rank($resource, "w");
542
 
 
543
 
            # we only do notification for enforce mode events
544
 
            if ($config->{verbose_freq}) {
545
 
                if (   ($severity >= $config->{verbose_level})
546
 
                    || (($severity == -1) && $config->{verbose_unknown}))
547
 
                {
548
 
                    push @verbose_buffer, [ $timestamp, $counter, $logmsg ];
549
 
                }
550
 
            }
551
 
 
552
 
            if ($config->{summary_freq}) {
553
 
                if (   ($severity >= $config->{summary_level})
554
 
                    || (($severity == -1) && $config->{summary_unknown}))
555
 
                {
556
 
                    push @summary_buffer, [ $timestamp, $counter, "attrch", $prog, $resource, $attrch ];
557
 
                }
558
 
            }
559
 
 
560
 
            if ($config->{terse_freq}) {
561
 
                if (   ($severity >= $config->{terse_level})
562
 
                    || (($severity == -1) && $config->{terse_unknown}))
563
 
                {
564
 
                    push @terse_buffer, [ $timestamp, $counter ];
565
 
                }
566
 
            }
567
 
        }
568
 
 
569
 
        push @commit_buffer, [ "chattr", $timestamp, $counter, $profile, $sdmode, $resource, $attrch, $prog, $pid, $severity ];
570
 
        $inserts++;
571
 
 
572
 
    } elsif (m/(PERMITTING|REJECTING) (?:mk|rm)dir on (.+) \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
573
 
        my ($sdmode, $resource, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6);
574
 
 
575
 
        $profile .= "^$hat" if $profile ne $hat;
576
 
 
577
 
        my $mode = "w";
578
 
 
579
 
        my $severity = "";
580
 
        if ($sdmode eq "REJECTING") {
581
 
            $severity = $sevdb->rank($resource, $mode);
582
 
 
583
 
            # we only do notification for enforce mode events
584
 
            if ($config->{verbose_freq}) {
585
 
                if (   ($severity >= $config->{verbose_level})
586
 
                    || (($severity == -1) && $config->{verbose_unknown}))
587
 
                {
588
 
                    push @verbose_buffer, [ $timestamp, $counter, $logmsg ];
589
 
                }
590
 
            }
591
 
 
592
 
            if ($config->{summary_freq}) {
593
 
                if (   ($severity >= $config->{summary_level})
594
 
                    || (($severity == -1) && $config->{summary_unknown}))
595
 
                {
596
 
                    push @summary_buffer, [ $timestamp, $counter, "path", $prog, $mode, $resource ];
597
 
                }
598
 
            }
599
 
 
600
 
            if ($config->{terse_freq}) {
601
 
                if (   ($severity >= $config->{terse_level})
602
 
                    || (($severity == -1) && $config->{terse_unknown}))
603
 
                {
604
 
                    push @terse_buffer, [ $timestamp, $counter, "dummy" ];
605
 
                }
606
 
            }
607
 
 
608
 
        }
609
 
 
610
 
        push @commit_buffer, [ "path", $timestamp, $counter, $profile, $sdmode, $mode, $resource, $prog, $pid, $severity ];
611
 
        $inserts++;
612
 
    } elsif (/(PERMITTING|REJECTING) xattr (\S+) on (.+) \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
613
 
        my ($sdmode, $xattr_op, $resource, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6, $7);
614
 
 
615
 
        $profile .= "^$hat" if $profile ne $hat;
616
 
 
617
 
        my $mode;
618
 
        if ($xattr_op eq "get" || $xattr_op eq "list") {
619
 
            $mode = "r";
620
 
        } elsif ($xattr_op eq "set" || $xattr_op eq "remove") {
621
 
            $mode = "w";
622
 
        }
623
 
 
624
 
        my $severity = "";
625
 
        if ($sdmode eq "REJECTING") {
626
 
            $severity = $sevdb->rank($resource, $mode);
627
 
 
628
 
            # we only do notification for enforce mode events
629
 
            if ($config->{verbose_freq}) {
630
 
                if (   ($severity >= $config->{verbose_level})
631
 
                    || (($severity == -1) && $config->{verbose_unknown}))
632
 
                {
633
 
                    push @verbose_buffer, [ $timestamp, $counter, $logmsg ];
634
 
                }
635
 
            }
636
 
 
637
 
            if ($config->{summary_freq}) {
638
 
                if (   ($severity >= $config->{summary_level})
639
 
                    || (($severity == -1) && $config->{summary_unknown}))
640
 
                {
641
 
                    push @summary_buffer, [ $timestamp, $counter, "path", $prog, $mode, $resource ];
642
 
                }
643
 
            }
644
 
 
645
 
            if ($config->{terse_freq}) {
646
 
                if (   ($severity >= $config->{terse_level})
647
 
                    || (($severity == -1) && $config->{terse_unknown}))
648
 
                {
649
 
                    push @terse_buffer, [ $timestamp, $counter, "dummy" ];
650
 
                }
651
 
            }
652
 
 
653
 
        }
654
 
 
655
 
        push @commit_buffer, [ "path", $timestamp, $counter, $profile, $sdmode, $mode, $resource, $prog, $pid, $severity ];
656
 
        $inserts++;
657
 
 
658
 
    } elsif ($mesg =~ /(PERMITTING|REJECTING|AUDITING) access to capability '(.+?)' \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
659
 
        my ($sdmode, $capability, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6, $7);
660
 
 
661
 
        $profile .= "^$hat" if $profile ne $hat;
662
 
 
663
 
        my $severity = "";
664
 
        if ($sdmode eq "REJECTING") {
665
 
            $severity = $sevdb->rank(uc("cap_$capability"));
666
 
 
667
 
            # we only do notification for enforce mode events
668
 
            if ($config->{verbose_freq}) {
669
 
                if (   ($severity >= $config->{verbose_level})
670
 
                    || (($severity == -1) && $config->{verbose_unknown}))
671
 
                {
672
 
                    push @verbose_buffer, [ $timestamp, $counter, $logmsg ];
673
 
                }
674
 
            }
675
 
 
676
 
            if ($config->{summary_freq}) {
677
 
                if (   ($severity >= $config->{summary_level})
678
 
                    || (($severity == -1) && $config->{summary_unknown}))
679
 
                {
680
 
                    push @summary_buffer, [ $timestamp, $counter, "capability", $prog, $capability ];
681
 
                }
682
 
            }
683
 
 
684
 
            if ($config->{terse_freq}) {
685
 
                if (   ($severity >= $config->{terse_level})
686
 
                    || (($severity == -1) && $config->{terse_unknown}))
687
 
                {
688
 
                    push @terse_buffer, [ $timestamp, $counter ];
689
 
                }
690
 
            }
691
 
        }
692
 
 
693
 
        push @commit_buffer, [ "capability", $timestamp, $counter, $profile, $sdmode, $capability, $prog, $pid, $severity ];
694
 
        $inserts++;
695
 
 
696
 
    } elsif ($mesg =~ /LOGPROF-HINT unknown_hat (\S+) pid=(\d+) profile=(\S+) active=(\S+)/) {
697
 
        my ($uhat, $pid, $profile, $hat) = ($1, $2, $3, $4);
698
 
 
699
 
        $profile .= "^$hat" if $profile ne $hat;
700
 
 
701
 
        push @commit_buffer, [ "unknown_hat", $timestamp, $counter, $profile, "PERMITTING", $uhat, $pid ];
702
 
        $inserts++;
703
 
 
704
 
    } elsif ($mesg =~ /LOGPROF-HINT fork pid=(\d+) child=(\d+) profile=(\S+) active=(\S+)/) {
705
 
        my ($pid, $child, $profile, $hat) = ($1, $2, $3, $4);
706
 
 
707
 
        $profile .= "^$hat" if $profile ne $hat;
708
 
 
709
 
        push @commit_buffer, [ "fork", $timestamp, $counter, $profile, "PERMITTING", $pid, $child ];
710
 
        $inserts++;
711
 
 
712
 
    } elsif ($mesg =~ /LOGPROF-HINT changing_profile pid=(\d+) newprofile=(\S+)/) {
713
 
        my ($pid, $newprofile) = ($1, $2);
714
 
 
715
 
        push @commit_buffer, [ "changing_profile", $timestamp, $counter, $newprofile, "PERMITTING", $pid ];
716
 
        $inserts++;
717
 
 
718
 
    } elsif ($mesg =~ /LOGPROF-HINT fork pid=(\d+) child=(\d+)/) {
719
 
        my ($pid, $child) = ($1, $2);
720
 
 
721
 
        push @commit_buffer, [ "fork", $timestamp, $counter, "null-complain-profile", "PERMITTING", $pid, $child ];
722
 
        $inserts++;
723
 
 
724
 
    } elsif ($mesg =~ /LOGPROF-HINT changing_profile pid=(\d+)/) {
725
 
        my $pid = $1;
726
 
 
727
 
        push @commit_buffer, [ "changing_profile", $timestamp, $counter, "null-complain-profile", "PERMITTING", $pid ];
728
 
        $inserts++;
729
 
 
730
 
    } elsif ($mesg =~ /(PERMITTING|REJECTING|AUDITING) access to profile replacement \((\S+)\((\d+)\) profile (\S+) active (\S+)\)/) {
731
 
        my ($sdmode, $prog, $pid, $profile, $hat) = ($1, $2, $3, $4, $5, $6, $7);
732
 
 
733
 
        $profile .= "^$hat" if $profile ne $hat;
734
 
 
735
 
        my $severity = 10;
 
511
    if ( $ev->{'sdmode'} && $ev->{'sdmode'} eq "REJECTING") {
 
512
        $severity = $sevdb->rank($ev->{'prog'}, $ev->{'mode_req'});
 
513
                if ( ! $severity ) { $severity = "-1"; }
736
514
 
737
515
        # we only do notification for enforce mode events
738
516
        if ($config->{verbose_freq}) {
747
525
            if (   ($severity >= $config->{summary_level})
748
526
                || (($severity == -1) && $config->{summary_unknown}))
749
527
            {
750
 
                push @summary_buffer, [ $timestamp, $counter, "profile_replacement", $prog ];
 
528
                push @summary_buffer, [ $timestamp, $counter, "path",
 
529
                                        $ev->{'prog'}, $ev->{'mode_req'}, $ev->{'resource'} ];
751
530
            }
752
531
        }
753
532
 
755
534
            if (   ($severity >= $config->{terse_level})
756
535
                || (($severity == -1) && $config->{terse_unknown}))
757
536
            {
758
 
                push @terse_buffer, [ $timestamp, $counter ];
 
537
                push @terse_buffer, [ $timestamp, $counter, "dummy" ];
759
538
            }
760
539
        }
761
540
 
762
 
        push @commit_buffer, [ "profile_replacement", $timestamp, $counter, $profile, $sdmode, $prog, $pid, $severity ];
763
 
        $inserts++;
764
 
 
765
 
    } elsif ($mesg =~ /(SubDomain|AppArmor) protection removed/) {
766
 
 
767
 
        push @commit_buffer, [ "removed", $timestamp, $counter, 10 ];
768
 
        $inserts++;
769
 
 
770
 
    } elsif ($mesg =~ /(SubDomain|AppArmor) \(version (\S+)\) initialized/) {
771
 
        my $version = $1;
772
 
 
773
 
        push @commit_buffer, [ "initialized", $timestamp, $counter, $version, 10 ];
774
 
        $inserts++;
775
 
 
776
 
    } elsif ($mesg =~ /Control variable '(\S+)' changed to (\S+)/) {
777
 
        my ($variable, $value) = ($1, $2);
778
 
 
779
 
        push @commit_buffer, [ "ctrl_var", $timestamp, $counter, $variable, $value, 10 ];
780
 
        $inserts++;
781
 
 
 
541
    }
 
542
 
 
543
        unless ( $ev->{'op'} ) {
 
544
                my $errmsg = "ERROR: No operation found: ";
 
545
                for my $k (sort keys(%$ev)) {
 
546
                        $errmsg .= "$k is $ev->{$k}, ";
 
547
                }
 
548
                errlog("$errmsg\n");
 
549
                return;
 
550
        }
 
551
 
 
552
    # Format the message to match the db template 
 
553
    if ($ev->{'op'} eq 'link' ) {
 
554
                $type = 'link';
 
555
        push(@eventList, [$time,$counter,$type,$ev->{'profile'},$ev->{'sdmode'},
 
556
                        $ev->{'resource'},$ev->{'target'},$ev->{'prog'},$ev->{'pid'},$severity]); 
 
557
    } elsif ($ev->{'op'} eq 'attribute') {
 
558
                $type = 'chattr';
 
559
        push(@eventList, []);
 
560
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},$ev->{'sdmode'},
 
561
                        $ev->{'resource'},$ev->{'mode_req'},$ev->{'mode_deny'},$ev->{'prog'},
 
562
                        $ev->{'pid'},$severity]); 
 
563
    } elsif ($ev->{'op'} eq 'capability') {
 
564
                $type = 'capability';
 
565
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},$ev->{'sdmode'},
 
566
                        $ev->{'resource'},$ev->{'prog'},$ev->{'pid'},$severity]); 
 
567
    } elsif ($ev->{'op'} eq 'capable') {
 
568
                $type = 'capable';
 
569
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'prog'},
 
570
                        $ev->{'profile'},$ev->{'pid'}]); 
 
571
    } elsif ($ev->{'op'} =~ /ontrol variable/ ) {
 
572
        $type = 'ctrl_var';
 
573
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'resource'},
 
574
                        $ev->{'mode_req'},$ev->{'mode_deny'},$severity]); 
 
575
        } elsif ($ev->{'op'} eq 'unknown_hat') {
 
576
                $type = 'unknown_hat';
 
577
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},$ev->{'sdmode'},
 
578
                        $ev->{'resource'},$ev->{'pid'},$severity]); 
 
579
        } elsif ($ev->{'op'} eq 'fork') {
 
580
                $type = 'fork';
 
581
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},$ev->{'sdmode'},
 
582
                        $ev->{'pid'},$ev->{'resource'}]); 
 
583
        } elsif ($ev->{'op'} eq 'changing_profile') {
 
584
                $type = 'changing_profile';
 
585
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},$ev->{'sdmode'},
 
586
                        $ev->{'pid'}]); 
 
587
        } elsif ($ev->{'op'} eq 'profile_load') {
 
588
                $type = 'profile_load';
 
589
                push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'resource'},
 
590
                        $ev->{'prog'},$ev->{'pid'}]);
 
591
        } elsif ($ev->{'op'} eq 'profile_replace') {
 
592
                $type = 'profile_replacement';
 
593
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},$ev->{'sdmode'},
 
594
                        $ev->{'prog'},$ev->{'pid'},$severity]); 
 
595
        } elsif ($ev->{'op'} eq 'removed') {
 
596
            $type = 'removed';
 
597
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$severity]); 
 
598
        } elsif ($ev->{'op'} eq 'initialized') {
 
599
                $type = 'initialized';
 
600
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'resource'},$severity]); 
 
601
        } elsif ( $ev->{'op'} =~ /socket/) {
 
602
                $type = 'net';
 
603
                push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'net_family'},
 
604
                        $ev->{'net_sock_type'},$ev->{'net_proto'},$ev->{'pid'},$ev->{'profile'}]);
782
605
    } else {
783
 
        chomp $logmsg;
784
 
        errlog "Unhandled log message: $logmsg";
 
606
        $type = 'path';
 
607
                if ( ! $ev->{'prog'} ) { $ev->{'prog'} = "NIL"; }
 
608
        push(@eventList, [$time,$counter,$type,$ev->{'op'},$ev->{'profile'},
 
609
                        $ev->{'sdmode'},$ev->{'mode_req'},$ev->{'mode_deny'},$ev->{'resource'},
 
610
                        $ev->{'prog'},$ev->{'pid'},$severity]); 
785
611
    }
 
612
 
 
613
    push(@commit_buffer, @eventList);
 
614
    $inserts++;
 
615
 
786
616
}
787
617
 
788
618
sub dump_events {
818
648
 
819
649
        for my $event (sort { $a->[0] cmp $b->[0] } @commit_buffer) {
820
650
            my @event = @{$event};
821
 
            my $type  = shift @event;
822
 
 
823
 
            if ($type ne $last_prepare) {
824
 
                $sth          = $dbh->prepare("INSERT INTO events $templates{$type};");
825
 
                $last_prepare = $type;
826
 
            }
827
 
 
828
 
            $sth->execute(@event);
 
651
 
 
652
            #my $type  = shift @event;
 
653
            my $type  = $event[2];
 
654
 
 
655
                    eval {
 
656
                        if ($type ne $last_prepare) {
 
657
                            $sth          = $dbh->prepare("INSERT INTO events $templates{$type}");
 
658
                            $last_prepare = $type;
 
659
                        }
 
660
 
 
661
                        $sth->execute(@event);
 
662
                    };
 
663
 
 
664
                    if ($@) {
 
665
                        print ERRLOG "DBI Execution failed: $DBI::errstr\n";
 
666
                    }
 
667
 
 
668
            #$sth->execute(@event);
829
669
        }
830
670
 
831
671
        $dbh->commit || errlog "Error commiting changes: $!";
1016
856
$| = 1;
1017
857
select($oldfd);
1018
858
 
1019
 
errlog "Starting...";
1020
 
 
1021
859
$config = readconfig();
1022
860
 
1023
861
# fork off into the background.  we need to do this before we connect to