4
# newrules.pl, Copyright (C) 2001 Justin R. Smith (jsmith@mcs.drexel.edu)
6
# This program is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU General Public License as
8
# published by the Free Software Foundation; either version 2 of
9
# the License, or (at your option) any later version.
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
# GNU General Public License for more details.
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20
# 2003 Oct 11: Add -l option by Yuichi Nakamura(ynakam@users.sourceforge.jp)
23
$load_policy_pattern="avc:.*granted.*{.*load_policy.*}";
25
while ($opt = shift @ARGV) {
26
if ($opt eq "-d") { $read_dmesg++; }
27
elsif ($opt eq "-v") { $verbose++; }
28
elsif ($opt eq "-i") { $input = shift @ARGV; }
29
elsif ($opt eq "-o") { $output= shift @ARGV; }
30
elsif ($opt eq "-l") { $load_policy++; }
31
elsif ($opt eq "--help") { &printUsage; }
32
else { print "unknown option, '$opt'\n\n"; &printUsage; }
35
if ($read_dmesg && $input) {
36
print "Error, can't read from both dmesg and $input\n\n";
40
if ($read_dmesg) { open (IN, "/bin/dmesg|"); }
41
elsif ($input) { open (IN, "$input"); }
42
else { open (IN, "-"); } # STDIN
44
if ($output) { open (OUT, ">>$output"); }
45
else { open (OUT, ">-"); } # STDOUT
47
if($load_policy){ #store logs after last "load_policy" in @log_buf
48
while ($line = <IN>) {
49
if($line=~/$load_policy_pattern/) {
50
#stored logs are unnecessary
60
while ($line=&readNewline) {
61
next unless ($line =~ m/avc:\s*denied\s*\{((\w|\s)*)\}/);
62
@types=split /\ /,$line;
66
foreach $i(0..$#types){
67
next if($types[$i]!~/[=\{]/);
68
if($types[$i]=~/^\{/){
70
while($types[$j]!~/\}/){
71
$command.=" $types[$j]";
76
my($a,$b) = split /=/,$types[$i];
82
if(($a eq "scontext")||($a eq "tcontext")||($a eq "tclass")){
84
my($c,$c,$c) = split /:/, $b;
96
my($c,$c,$c,$c) = split /\|/, $group;
97
$info=~s/\ $c=\S+\ //gi;
98
# escape regexp patterns --<g>
99
$info=~s/([^\w])/\\$1/g;
101
@atypes=split /\ /,$command;
102
foreach $i(0..$#atypes){
103
$rules{$group}{$atypes[$i]}++;
107
if($occur{$group}!~$info){
108
$occur{$group}.="\t#$info: $command\n";
111
my ($a,$b) = split /$info:\ /, $occur{$group};
112
my ($temp) = split /\n/, $b;
114
@com=split /\ /, $command;
115
foreach $i(1..$#com){
116
$b=" $com[$i]$b" if($temp!~$com[$i]);
118
$occur{$group}="$a$info: $b";
122
# done with the input file
123
# now generate the rules
124
foreach $k (sort keys %rules)
126
my ($a,$scontext,$tcontext,$tclass) = split /\|/, $k;
127
if ($scontext eq $tcontext) {
130
print OUT "allow $scontext $tcontext:$tclass";
132
my $access_types = $rules{$k};
133
$len=(keys %$access_types);
134
if ($len gt 2 ) { print OUT " {"; }
135
foreach $t (sort keys %$access_types) {
136
if ($t ne "") {print OUT " $t";}
138
if ($len gt 2 ) { print OUT " }"; }
140
$occur{$k} =~ s/\\(.)/$1/g; # de-escape string
141
print OUT "$occur{$k}\n" if ($verbose);
148
$newline=shift @log_buf;
156
print "audit2allow [-d] [-v] [-l] [-i <inputfile> ] [-o <outputfile>]
157
-d read input from output of /bin/dmesg
159
-l read input only after last \"load_policy\"
160
-i read input from <inputfile>
161
-o append output to <outputfile>\n";