2015-01-18 14:55:15 +01:00
# ----------------------------------------------------------------------
# Copyright (C) 2013 Kshitij Gupta <kgupta8592@gmail.com>
# Copyright (C) 2015 Christian Boltz <apparmor@cboltz.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# ----------------------------------------------------------------------
import unittest
from apparmor . logparser import ReadLog
2019-05-02 01:07:25 +02:00
from common_test import AATest , setup_all_loops # , setup_aa
from apparmor . common import AppArmorException
class TestParseEvent ( AATest ) :
tests = [ ]
2015-01-18 14:55:15 +01:00
def setUp ( self ) :
2019-05-04 00:22:46 +02:00
self . parser = ReadLog ( ' ' , ' ' , ' ' )
2015-01-18 14:55:15 +01:00
def test_parse_event_audit_1 ( self ) :
event = ' type=AVC msg=audit(1345027352.096:499): apparmor= " ALLOWED " operation= " rename_dest " parent=6974 profile= " /usr/sbin/httpd2-prefork//vhost_foo " name=2F686F6D652F7777772F666F6F2E6261722E696E2F68747470646F63732F61707061726D6F722F696D616765732F746573742F696D61676520312E6A7067 pid=20143 comm= " httpd2-prefork " requested_mask= " wc " denied_mask= " wc " fsuid=30 ouid=30 '
parsed_event = self . parser . parse_event ( event )
self . assertEqual ( parsed_event [ ' name ' ] , ' /home/www/foo.bar.in/httpdocs/apparmor/images/test/image 1.jpg ' )
self . assertEqual ( parsed_event [ ' profile ' ] , ' /usr/sbin/httpd2-prefork//vhost_foo ' )
self . assertEqual ( parsed_event [ ' aamode ' ] , ' PERMITTING ' )
2015-04-16 01:50:35 +02:00
self . assertEqual ( parsed_event [ ' request_mask ' ] , ' wc ' )
2015-01-18 14:55:15 +01:00
2015-10-03 20:18:54 +02:00
self . assertIsNotNone ( ReadLog . RE_LOG_ALL . search ( event ) )
2015-01-18 14:55:15 +01:00
def test_parse_event_audit_2 ( self ) :
event = ' type=AVC msg=audit(1322614918.292:4376): apparmor= " ALLOWED " operation= " file_perm " parent=16001 profile=666F6F20626172 name= " /home/foo/.bash_history " pid=17011 comm= " bash " requested_mask= " rw " denied_mask= " rw " fsuid=0 ouid=1000 '
parsed_event = self . parser . parse_event ( event )
self . assertEqual ( parsed_event [ ' name ' ] , ' /home/foo/.bash_history ' )
self . assertEqual ( parsed_event [ ' profile ' ] , ' foo bar ' )
self . assertEqual ( parsed_event [ ' aamode ' ] , ' PERMITTING ' )
2015-04-16 01:50:35 +02:00
self . assertEqual ( parsed_event [ ' request_mask ' ] , ' rw ' )
2015-01-18 14:55:15 +01:00
2015-10-03 20:18:54 +02:00
self . assertIsNotNone ( ReadLog . RE_LOG_ALL . search ( event ) )
2015-01-18 14:55:15 +01:00
def test_parse_event_syslog_1 ( self ) :
# from https://bugs.launchpad.net/apparmor/+bug/1399027
event = ' 2014-06-09T20:37:28.975070+02:00 geeko kernel: [21028.143765] type=1400 audit(1402339048.973:1421): apparmor= " ALLOWED " operation= " open " profile= " /home/cb/linuxtag/apparmor/scripts/hello " name= " /dev/tty " pid=14335 comm= " hello " requested_mask= " rw " denied_mask= " rw " fsuid=1000 ouid=0 '
parsed_event = self . parser . parse_event ( event )
self . assertEqual ( parsed_event [ ' name ' ] , ' /dev/tty ' )
self . assertEqual ( parsed_event [ ' profile ' ] , ' /home/cb/linuxtag/apparmor/scripts/hello ' )
self . assertEqual ( parsed_event [ ' aamode ' ] , ' PERMITTING ' )
2015-04-16 01:50:35 +02:00
self . assertEqual ( parsed_event [ ' request_mask ' ] , ' rw ' )
2015-01-18 14:55:15 +01:00
2015-10-03 20:18:54 +02:00
self . assertIsNotNone ( ReadLog . RE_LOG_ALL . search ( event ) )
2015-01-18 14:55:15 +01:00
def test_parse_event_syslog_2 ( self ) :
# from https://bugs.launchpad.net/apparmor/+bug/1399027
event = ' Dec 7 13:18:59 rosa kernel: audit: type=1400 audit(1417954745.397:82): apparmor= " ALLOWED " operation= " open " profile= " /home/simi/bin/aa-test " name= " /usr/bin/ " pid=3231 comm= " ls " requested_mask= " r " denied_mask= " r " fsuid=1000 ouid=0 '
parsed_event = self . parser . parse_event ( event )
self . assertEqual ( parsed_event [ ' name ' ] , ' /usr/bin/ ' )
self . assertEqual ( parsed_event [ ' profile ' ] , ' /home/simi/bin/aa-test ' )
self . assertEqual ( parsed_event [ ' aamode ' ] , ' PERMITTING ' )
2015-04-16 01:50:35 +02:00
self . assertEqual ( parsed_event [ ' request_mask ' ] , ' r ' )
2015-01-18 14:55:15 +01:00
2015-10-03 20:18:54 +02:00
self . assertIsNotNone ( ReadLog . RE_LOG_ALL . search ( event ) )
2015-01-18 14:55:15 +01:00
2015-03-03 22:17:05 +01:00
def test_parse_disconnected_path ( self ) :
# from https://bugzilla.opensuse.org/show_bug.cgi?id=918787
event = ' type=AVC msg=audit(1424425690.883:716630): apparmor= " ALLOWED " operation= " file_mmap " info= " Failed name lookup - disconnected path " error=-13 profile= " /sbin/klogd " name= " var/run/nscd/passwd " pid=25333 comm= " id " requested_mask= " r " denied_mask= " r " fsuid=1002 ouid=0 '
parsed_event = self . parser . parse_event ( event )
self . assertEqual ( parsed_event , {
' aamode ' : ' ERROR ' , # aamode for disconnected paths overridden aamode in parse_event()
' active_hat ' : None ,
' attr ' : None ,
2015-04-16 01:50:35 +02:00
' denied_mask ' : ' r ' ,
2015-03-03 22:17:05 +01:00
' error_code ' : 13 ,
2017-12-13 20:16:29 +01:00
' fsuid ' : 1002 ,
2015-03-03 22:17:05 +01:00
' info ' : ' Failed name lookup - disconnected path ' ,
' magic_token ' : 0 ,
' name ' : ' var/run/nscd/passwd ' ,
' name2 ' : None ,
' operation ' : ' file_mmap ' ,
2017-12-13 20:16:29 +01:00
' ouid ' : 0 ,
2015-03-03 22:17:05 +01:00
' parent ' : 0 ,
' pid ' : 25333 ,
' profile ' : ' /sbin/klogd ' ,
2015-04-16 01:50:35 +02:00
' request_mask ' : ' r ' ,
2015-03-03 22:17:05 +01:00
' resource ' : ' Failed name lookup - disconnected path ' ,
' task ' : 0 ,
2016-11-19 10:55:03 +01:00
' time ' : 1424425690 ,
' family ' : None ,
' protocol ' : None ,
' sock_type ' : None ,
2015-03-03 22:17:05 +01:00
} )
2015-10-03 20:18:54 +02:00
self . assertIsNotNone ( ReadLog . RE_LOG_ALL . search ( event ) )
2015-03-03 22:17:05 +01:00
2019-05-02 01:07:25 +02:00
class TestParseEventForTreeInvalid ( AATest ) :
tests = [
( ' type=AVC msg=audit(1556742870.707:3614): apparmor= " ALLOWED " operation= " open " profile= " /bin/hello " name= " /dev/tty " pid=12856 comm= " hello " requested_mask= " wr " denied_mask= " foo " fsuid=1000 ouid=0 ' , AppArmorException ) , # invalid file permissions "foo"
( ' type=AVC msg=audit(1556742870.707:3614): apparmor= " ALLOWED " operation= " open " profile= " /bin/hello " name= " /dev/tty " pid=12856 comm= " hello " requested_mask= " wr " denied_mask= " wr::w " fsuid=1000 ouid=0 ' , AppArmorException ) , # "wr::w" mixes owner and other
]
def _fake_profile_exists ( self , program ) :
return True
def _run_test ( self , params , expected ) :
2019-05-04 00:22:46 +02:00
self . parser = ReadLog ( ' ' , ' ' , ' ' )
2019-05-02 01:07:25 +02:00
self . parser . profile_exists = self . _fake_profile_exists # inject fake function that always returns True - much easier than handing over a ProfileList object to __init__
parsed_event = self . parser . parse_event ( params )
with self . assertRaises ( expected ) :
self . parser . parse_event_for_tree ( parsed_event )
2015-01-18 14:55:15 +01:00
2019-05-02 01:07:25 +02:00
setup_all_loops ( __name__ )
2015-01-18 14:55:15 +01:00
if __name__ == " __main__ " :
2018-04-08 20:18:30 +02:00
unittest . main ( verbosity = 1 )