1 # Authors: Karl MacMillan <kmacmillan (at] mentalrootkit.com> 2 # 3 # Copyright (C) 2006 Red Hat 4 # see file 'COPYING' for use and warranty information 5 # 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; version 2 only 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program; if not, write to the Free Software 17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 # 19 20 import unittest 21 import sepolgen.audit 22 import sepolgen.refpolicy 23 24 # syslog message 25 audit1 = """Sep 12 08:26:43 dhcp83-5 kernel: audit(1158064002.046:4): avc: denied { read } for pid=2 496 comm="bluez-pin" name=".gdm1K3IFT" dev=dm-0 ino=3601333 scontext=user_u:system_r:bluetooth_helper_t:s0-s0:c0 tcontext=system_u:object_r:xdm_tmp_t:s0 tclass=file""" 26 27 # audit daemon messages 28 audit2 = """type=AVC msg=audit(1158584779.745:708): avc: denied { dac_read_search } for pid=8132 comm="sh" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability""" 29 30 log1 = """type=AVC msg=audit(1158584779.745:708): avc: denied { dac_read_search } for pid=8132 comm="sh" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 31 type=SYSCALL msg=audit(1158584779.745:708): arch=40000003 syscall=195 success=no exit=-13 a0=80d2437 a1=bf9132f8 a2=4c56cff4 a3=0 items=0 ppid=8131 pid=8132 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="sh" exe="/bin/bash" subj=user_u:system_r:vpnc_t:s0 key=(null) 32 type=AVC msg=audit(1158584779.753:709): avc: denied { dac_override } for pid=8133 comm="vpnc-script" capability=1 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 33 type=AVC msg=audit(1158584779.753:709): avc: denied { dac_read_search } for pid=8133 comm="vpnc-script" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 34 type=SYSCALL msg=audit(1158584779.753:709): arch=40000003 syscall=195 success=no exit=-13 a0=80d2437 a1=bf910a48 a2=4c56cff4 a3=0 items=0 ppid=8132 pid=8133 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="vpnc-script" exe="/bin/bash" subj=user_u:system_r:vpnc_t:s0 key=(null) 35 type=AVC msg=audit(1158584779.825:710): avc: denied { dac_override } for pid=8134 comm="vpnc-script" capability=1 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 36 type=AVC msg=audit(1158584779.825:710): avc: denied { dac_read_search } for pid=8134 comm="vpnc-script" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 37 type=SYSCALL msg=audit(1158584779.825:710): arch=40000003 syscall=195 success=no exit=-13 a0=80d2437 a1=bf910a48 a2=4c56cff4 a3=0 items=0 ppid=8132 pid=8134 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="vpnc-script" exe="/bin/bash" subj=user_u:system_r:vpnc_t:s0 key=(null) 38 type=AVC msg=audit(1158584780.793:711): avc: denied { dac_override } for pid=8144 comm="sh" capability=1 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 39 type=AVC msg=audit(1158584780.793:711): avc: denied { dac_read_search } for pid=8144 comm="sh" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 40 type=SYSCALL msg=audit(1158584780.793:711): arch=40000003 syscall=195 success=no exit=-13 a0=80d2437 a1=bfc0ba38 a2=4c56cff4 a3=0 items=0 ppid=8131 pid=8144 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="sh" exe="/bin/bash" subj=user_u:system_r:vpnc_t:s0 key=(null) 41 type=AVC msg=audit(1158584780.797:712): avc: denied { dac_override } for pid=8145 comm="vpnc-script" capability=1 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 42 type=AVC msg=audit(1158584780.797:712): avc: denied { dac_read_search } for pid=8145 comm="vpnc-script" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 43 type=SYSCALL msg=audit(1158584780.797:712): arch=40000003 syscall=195 success=no exit=-13 a0=80d2437 a1=bfc0b188 a2=4c56cff4 a3=0 items=0 ppid=8144 pid=8145 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="vpnc-script" exe="/bin/bash" subj=user_u:system_r:vpnc_t:s0 key=(null) 44 type=AVC msg=audit(1158584780.801:713): avc: denied { dac_override } for pid=8146 comm="vpnc-script" capability=1 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 45 type=AVC msg=audit(1158584780.801:713): avc: denied { dac_read_search } for pid=8146 comm="vpnc-script" capability=2 scontext=user_u:system_r:vpnc_t:s0 tcontext=user_u:system_r:vpnc_t:s0 tclass=capability 46 type=AVC_PATH msg=audit(1162850461.778:1113): path="/etc/rc.d/init.d/innd" 47 """ 48 49 granted1 = """type=AVC msg=audit(1188833848.190:34): avc: granted { getattr } for pid=4310 comm="ls" name="foo.pp" dev=sda5 ino=295171 scontext=user_u:system_r:unconfined_t:s0 tcontext=user_u:object_r:user_home_t:s0 tclass=file""" 50 51 path1 = """type=AVC_PATH msg=audit(1162852201.019:1225): path="/usr/lib/sa/sa1" 52 """ 53 54 log2 = """type=AVC_PATH msg=audit(1162852201.019:1225): path="/usr/lib/sa/sa1" 55 type=SYSCALL msg=audit(1162852201.019:1225): arch=40000003 syscall=11 success=yes exit=0 a0=87271b0 a1=8727358 a2=8727290 a3=8727008 items=0 ppid=6973 pid=6974 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) comm="sa1" exe="/bin/bash" subj=system_u:system_r:crond_t:s0-s0:c0.c1023 key=(null) 56 type=AVC msg=audit(1162852201.019:1225): avc: denied { execute_no_trans } for pid=6974 comm="sh" name="sa1" dev=dm-0 ino=13061698 scontext=system_u:system_r:crond_t:s0-s0:c0.c1023 tcontext=system_u:object_r:lib_t:s0 tclass=file 57 type=AVC msg=audit(1162852201.019:1225): avc: denied { execute } for pid=6974 comm="sh" name="sa1" dev=dm-0 ino=13061698 scontext=system_u:system_r:crond_t:s0-s0:c0.c1023 tcontext=system_u:object_r:lib_t:s0 tclass=file""" 58 59 class TestAVCMessage(unittest.TestCase): 60 def test_defs(self): 61 avc = sepolgen.audit.AVCMessage(audit1) 62 sc = sepolgen.refpolicy.SecurityContext() 63 self.assertEqual(avc.scontext, sc) 64 self.assertEqual(avc.tcontext, sc) 65 self.assertEqual(avc.tclass, "") 66 self.assertEqual(avc.accesses, []) 67 68 def test_granted(self): 69 avc = sepolgen.audit.AVCMessage(granted1) 70 avc.from_split_string(granted1.split()) 71 72 self.assertEqual(avc.scontext.user, "user_u") 73 self.assertEqual(avc.scontext.role, "system_r") 74 self.assertEqual(avc.scontext.type, "unconfined_t") 75 self.assertEqual(avc.scontext.level, "s0") 76 77 self.assertEqual(avc.tcontext.user, "user_u") 78 self.assertEqual(avc.tcontext.role, "object_r") 79 self.assertEqual(avc.tcontext.type, "user_home_t") 80 self.assertEqual(avc.tcontext.level, "s0") 81 82 self.assertEqual(avc.tclass, "file") 83 self.assertEqual(avc.accesses, ["getattr"]) 84 85 self.assertEqual(avc.denial, False) 86 87 88 def test_from_split_string(self): 89 # syslog message 90 avc = sepolgen.audit.AVCMessage(audit1) 91 recs = audit1.split() 92 avc.from_split_string(recs) 93 94 self.assertEqual(avc.header, "audit(1158064002.046:4):") 95 self.assertEqual(avc.scontext.user, "user_u") 96 self.assertEqual(avc.scontext.role, "system_r") 97 self.assertEqual(avc.scontext.type, "bluetooth_helper_t") 98 self.assertEqual(avc.scontext.level, "s0-s0:c0") 99 100 self.assertEqual(avc.tcontext.user, "system_u") 101 self.assertEqual(avc.tcontext.role, "object_r") 102 self.assertEqual(avc.tcontext.type, "xdm_tmp_t") 103 self.assertEqual(avc.tcontext.level, "s0") 104 105 self.assertEqual(avc.tclass, "file") 106 self.assertEqual(avc.accesses, ["read"]) 107 108 self.assertEqual(avc.comm, "bluez-pin") 109 110 111 self.assertEqual(avc.denial, True) 112 113 # audit daemon message 114 avc = sepolgen.audit.AVCMessage(audit2) 115 recs = audit2.split() 116 avc.from_split_string(recs) 117 118 self.assertEqual(avc.header, "audit(1158584779.745:708):") 119 self.assertEqual(avc.scontext.user, "user_u") 120 self.assertEqual(avc.scontext.role, "system_r") 121 self.assertEqual(avc.scontext.type, "vpnc_t") 122 self.assertEqual(avc.scontext.level, "s0") 123 124 self.assertEqual(avc.tcontext.user, "user_u") 125 self.assertEqual(avc.tcontext.role, "system_r") 126 self.assertEqual(avc.tcontext.type, "vpnc_t") 127 self.assertEqual(avc.tcontext.level, "s0") 128 129 self.assertEqual(avc.tclass, "capability") 130 self.assertEqual(avc.accesses, ["dac_read_search"]) 131 132 self.assertEqual(avc.comm, "sh") 133 134 self.assertEqual(avc.denial, True) 135 136 class TestPathMessage(unittest.TestCase): 137 def test_from_split_string(self): 138 path = sepolgen.audit.PathMessage(path1) 139 recs = path1.split() 140 path.from_split_string(recs) 141 self.assertEqual(path.path, "/usr/lib/sa/sa1") 142 143 # TODO - add tests for the other message types 144 145 146 # TODO - these tests need a lot of expansion and more examples of 147 # different types of log files 148 class TestAuditParser(unittest.TestCase): 149 def test_parse_string(self): 150 a = sepolgen.audit.AuditParser() 151 a.parse_string(log1) 152 self.assertEqual(len(a.avc_msgs), 11) 153 self.assertEqual(len(a.compute_sid_msgs), 0) 154 self.assertEqual(len(a.invalid_msgs), 0) 155 self.assertEqual(len(a.policy_load_msgs), 0) 156 self.assertEqual(len(a.path_msgs), 1) 157 158 def test_post_process(self): 159 a = sepolgen.audit.AuditParser() 160 a.parse_string(log2) 161 self.assertEqual(len(a.avc_msgs), 2) 162 self.assertEqual(a.avc_msgs[0].path, "/usr/lib/sa/sa1") 163 self.assertEqual(a.avc_msgs[1].path, "/usr/lib/sa/sa1") 164 165 def test_parse_file(self): 166 f = open("audit.txt") 167 a = sepolgen.audit.AuditParser() 168 a.parse_file(f) 169 f.close() 170 self.assertEqual(len(a.avc_msgs), 21) 171 self.assertEqual(len(a.compute_sid_msgs), 0) 172 self.assertEqual(len(a.invalid_msgs), 0) 173 self.assertEqual(len(a.policy_load_msgs), 0) 174 175 class TestGeneration(unittest.TestCase): 176 def test_generation(self): 177 parser = sepolgen.audit.AuditParser() 178 parser.parse_string(log1) 179 avs = parser.to_access() 180 181 self.assertEqual(len(avs), 1) 182 183 def test_genaration_granted(self): 184 parser = sepolgen.audit.AuditParser() 185 parser.parse_string(granted1) 186 avs = parser.to_access() 187 188 self.assertEqual(len(avs), 0) 189 190 avs = parser.to_access(only_denials=False) 191 192 self.assertEqual(len(avs), 1) 193 194