2018-10-21 20:39:51 +02:00
#! /usr/bin/python3
# ------------------------------------------------------------------
#
2024-10-27 22:19:06 +01:00
# Copyright (C) 2018-2024 Christian Boltz <apparmor@cboltz.de>
2018-10-21 20:39:51 +02:00
#
# 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 published by the Free Software Foundation.
#
# ------------------------------------------------------------------
2020-05-23 00:02:49 +02:00
import os
import shutil
2022-08-07 20:32:07 -04:00
import unittest
2024-10-27 22:19:06 +01:00
from copy import deepcopy
2018-10-21 20:39:51 +02:00
2022-08-07 20:32:07 -04:00
import apparmor . aa
2018-10-21 20:39:51 +02:00
from apparmor . common import AppArmorBug , AppArmorException
from apparmor . profile_list import ProfileList
2021-04-05 13:21:36 +02:00
from apparmor . profile_storage import ProfileStorage
2023-10-11 20:39:37 +02:00
from apparmor . aare import AARE
2020-05-09 20:01:20 +02:00
from apparmor . rule . abi import AbiRule
2020-05-24 15:00:42 +02:00
from apparmor . rule . alias import AliasRule
2020-12-25 17:42:31 +01:00
from apparmor . rule . boolean import BooleanRule
2020-05-04 21:12:15 +02:00
from apparmor . rule . include import IncludeRule
2020-05-21 23:21:11 +02:00
from apparmor . rule . variable import VariableRule
2022-08-07 20:32:07 -04:00
from common_test import AATest , setup_aa , setup_all_loops , write_file
2018-10-21 20:39:51 +02:00
2022-08-07 12:26:24 -04:00
2020-05-04 21:56:04 +02:00
class TestAdd_profile ( AATest ) :
2018-10-21 20:39:51 +02:00
def AASetup ( self ) :
self . pl = ProfileList ( )
2021-04-05 13:21:36 +02:00
self . dummy_profile = ProfileStorage ( ' TEST DUMMY ' , ' AATest_no_file ' , ' TEST ' )
2018-10-21 20:39:51 +02:00
def testEmpty ( self ) :
self . assertEqual ( self . pl . profile_names , { } )
self . assertEqual ( self . pl . attachments , { } )
2023-02-19 16:26:14 -05:00
self . assertEqual ( str ( self . pl ) , " \n " . join ( [ ' ' , ' <ProfileList> ' , ' ' , ' </ProfileList> ' , ' ' ] ) )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profile_1 ( self ) :
2024-10-20 16:29:08 +02:00
self . assertFalse ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2024-10-20 16:29:08 +02:00
self . assertTrue ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2018-10-21 20:39:51 +02:00
self . assertEqual ( self . pl . profile_names , { ' foo ' : ' /etc/apparmor.d/bin.foo ' } )
2023-10-11 20:39:37 +02:00
self . assertEqual ( self . pl . attachments , { ' /bin/foo ' : { ' f ' : ' /etc/apparmor.d/bin.foo ' , ' p ' : ' foo ' , ' re ' : AARE ( ' /bin/foo ' , True ) } } )
2020-05-08 22:37:45 +02:00
self . assertEqual ( self . pl . profiles_in_file ( ' /etc/apparmor.d/bin.foo ' ) , [ ' foo ' ] )
2023-02-19 16:26:14 -05:00
self . assertEqual ( str ( self . pl ) , ' \n <ProfileList> \n /etc/apparmor.d/bin.foo \n </ProfileList> \n ' )
2018-10-21 20:39:51 +02:00
2024-10-27 16:28:23 +01:00
# test __getitem__()
self . assertEqual ( self . pl [ ' foo ' ] , self . dummy_profile )
with self . assertRaises ( AppArmorBug ) :
self . pl [ ' does_not_exist ' ]
2020-05-04 21:56:04 +02:00
def testAdd_profile_2 ( self ) :
2024-10-20 16:29:08 +02:00
self . assertFalse ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , None , ' /bin/foo ' , self . dummy_profile )
2024-10-20 16:29:08 +02:00
self . assertFalse ( self . pl . profile_exists ( ' foo ' ) )
self . assertTrue ( self . pl . profile_exists ( ' /bin/foo ' ) )
2018-10-21 20:39:51 +02:00
self . assertEqual ( self . pl . profile_names , { } )
2023-10-11 20:39:37 +02:00
self . assertEqual ( self . pl . attachments , { ' /bin/foo ' : { ' f ' : ' /etc/apparmor.d/bin.foo ' , ' p ' : ' /bin/foo ' , ' re ' : AARE ( ' /bin/foo ' , True ) } } )
2020-05-08 22:37:45 +02:00
self . assertEqual ( self . pl . profiles_in_file ( ' /etc/apparmor.d/bin.foo ' ) , [ ' /bin/foo ' ] )
2023-02-19 16:26:14 -05:00
self . assertEqual ( str ( self . pl ) , ' \n <ProfileList> \n /etc/apparmor.d/bin.foo \n </ProfileList> \n ' )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profile_3 ( self ) :
2024-10-20 16:29:08 +02:00
self . assertFalse ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , None , self . dummy_profile )
2024-10-20 16:29:08 +02:00
self . assertTrue ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2018-10-21 20:39:51 +02:00
self . assertEqual ( self . pl . profile_names , { ' foo ' : ' /etc/apparmor.d/bin.foo ' } )
self . assertEqual ( self . pl . attachments , { } )
2020-05-08 22:37:45 +02:00
self . assertEqual ( self . pl . profiles_in_file ( ' /etc/apparmor.d/bin.foo ' ) , [ ' foo ' ] )
2023-02-19 16:26:14 -05:00
self . assertEqual ( str ( self . pl ) , ' \n <ProfileList> \n /etc/apparmor.d/bin.foo \n </ProfileList> \n ' )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profileError_1 ( self ) :
2024-10-20 16:29:08 +02:00
self . assertFalse ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorBug ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' ' , ' foo ' , ' /bin/foo ' , self . dummy_profile ) # no filename
2024-10-20 16:29:08 +02:00
self . assertFalse ( self . pl . profile_exists ( ' foo ' ) )
self . assertFalse ( self . pl . profile_exists ( ' /bin/foo ' ) )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profileError_2 ( self ) :
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorBug ) :
2022-06-18 16:14:45 -04:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , None , None , self . dummy_profile ) # neither attachment nor profile name
2018-10-21 20:39:51 +02:00
2020-05-08 22:37:45 +02:00
def testAdd_profileError_list_nonexisting_file ( self ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , None , self . dummy_profile )
2020-05-08 22:37:45 +02:00
with self . assertRaises ( AppArmorBug ) :
self . pl . profiles_in_file ( ' /etc/apparmor.d/not.found ' ) # different filename
2020-05-04 21:56:04 +02:00
def testAdd_profileError_twice_1 ( self ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorException ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profileError_twice_2 ( self ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorException ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , None , self . dummy_profile )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profileError_twice_3 ( self ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , None , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorException ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profileError_twice_4 ( self ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , None , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorException ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2018-10-21 20:39:51 +02:00
2020-05-04 21:56:04 +02:00
def testAdd_profileError_twice_5 ( self ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , None , self . dummy_profile )
2018-10-21 20:39:51 +02:00
with self . assertRaises ( AppArmorException ) :
2021-04-05 13:21:36 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
def testAdd_profileError_wrong_prof_type ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , ' wrong_type ' )
2018-10-21 20:39:51 +02:00
2024-10-27 22:19:06 +01:00
def testReplace_profile_1 ( self ) :
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
# test if replacement works (but without checking if the content of the actual profile really changed)
self . pl . replace_profile ( ' foo ' , self . dummy_profile )
with self . assertRaises ( AppArmorBug ) :
self . pl . replace_profile ( ' /bin/foo ' , self . dummy_profile )
def testReplace_profile_error_1 ( self ) :
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
dummy2 = deepcopy ( self . dummy_profile )
dummy2 [ ' attachment ' ] = ' changed '
with self . assertRaises ( AppArmorBug ) :
self . pl . replace_profile ( ' foo ' , dummy2 ) # changed attachment
def testReplace_profile_error_2 ( self ) :
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
with self . assertRaises ( AppArmorBug ) :
self . pl . replace_profile ( ' foo ' , [ ] ) # [] is wrong type
2022-08-07 12:26:24 -04:00
2018-10-21 20:39:51 +02:00
class TestFilename_from_profile_name ( AATest ) :
2022-06-18 14:30:49 -04:00
tests = (
2018-10-21 20:39:51 +02:00
( ' foo ' , ' /etc/apparmor.d/bin.foo ' ) ,
( ' /bin/foo ' , None ) ,
( ' bar ' , None ) ,
2022-08-07 12:26:24 -04:00
( ' /usr { , { /lib,/lib32,/lib64}/wine}/bin/wine { ,-preloader,server} { ,-staging-*,-vanilla-*} ' , ' /etc/apparmor.d/usr.bin.wine ' ) ,
( ' /usr/lib/wine/bin/wine-preloader-staging-foo ' , None ) , # no AARE matching for profile names
2022-06-18 14:30:49 -04:00
)
2018-10-21 20:39:51 +02:00
def AASetup ( self ) :
self . pl = ProfileList ( )
2021-04-05 13:21:36 +02:00
self . dummy_profile = ProfileStorage ( ' TEST DUMMY ' , ' AATest_no_file ' , ' TEST ' )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
2022-08-07 12:26:24 -04:00
self . pl . add_profile (
' /etc/apparmor.d/usr.bin.wine ' ,
' /usr { , { /lib,/lib32,/lib64}/wine}/bin/wine { ,-preloader,server} { ,-staging-*,-vanilla-*} ' ,
' /usr { , { /lib,/lib32,/lib64}/wine}/bin/wine { ,-preloader,server} { ,-staging-*,-vanilla-*} ' ,
self . dummy_profile )
2018-10-21 20:39:51 +02:00
def _run_test ( self , params , expected ) :
self . assertEqual ( self . pl . filename_from_profile_name ( params ) , expected )
2022-08-07 12:26:24 -04:00
2018-10-21 20:39:51 +02:00
class TestFilename_from_attachment ( AATest ) :
2022-06-18 14:30:49 -04:00
tests = (
2018-10-21 20:39:51 +02:00
( ' /bin/foo ' , ' /etc/apparmor.d/bin.foo ' ) ,
( ' /bin/baz ' , ' /etc/apparmor.d/bin.baz ' ) ,
( ' /bin/foobar ' , ' /etc/apparmor.d/bin.foobar ' ) ,
( ' @ {foo} ' , None ) , # XXX variables not supported yet (and @{foo} isn't defined in this test)
( ' /bin/404 ' , None ) ,
2022-08-07 12:26:24 -04:00
( ' /usr { , { /lib,/lib32,/lib64}/wine}/bin/wine { ,-preloader,server} { ,-staging-*,-vanilla-*} ' , ' /etc/apparmor.d/usr.bin.wine ' ) , # XXX should this really match, or should attachment matching only use AARE?
( ' /usr/lib/wine/bin/wine-preloader-staging-foo ' , ' /etc/apparmor.d/usr.bin.wine ' ) , # AARE match
2022-06-18 14:30:49 -04:00
)
2018-10-21 20:39:51 +02:00
def AASetup ( self ) :
self . pl = ProfileList ( )
2021-04-05 13:21:36 +02:00
self . dummy_profile = ProfileStorage ( ' TEST DUMMY ' , ' AATest_no_file ' , ' TEST ' )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
self . pl . add_profile ( ' /etc/apparmor.d/bin.baz ' , ' baz ' , ' /bin/ba* ' , self . dummy_profile )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foobar ' , ' foobar ' , ' /bin/foo { bar,baz} ' , self . dummy_profile )
2023-10-08 15:25:55 +02:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.asdf ' , None , ' /bin/asdf ' , self . dummy_profile )
2022-08-07 12:26:24 -04:00
self . pl . add_profile (
' /etc/apparmor.d/usr.bin.wine ' ,
2023-10-08 15:25:55 +02:00
' wine ' ,
2022-08-07 12:26:24 -04:00
' /usr { , { /lib,/lib32,/lib64}/wine}/bin/wine { ,-preloader,server} { ,-staging-*,-vanilla-*} ' ,
self . dummy_profile )
2018-10-21 20:39:51 +02:00
def _run_test ( self , params , expected ) :
self . assertEqual ( self . pl . filename_from_attachment ( params ) , expected )
def test_non_path_attachment ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . filename_from_attachment ( ' foo ' )
2024-05-17 13:53:42 +02:00
2023-10-08 15:25:55 +02:00
class TestProfile_from_attachment ( TestFilename_from_attachment ) :
# uses AASetup from TestFilename_from_attachment
tests = (
( ' /bin/foo ' , ' foo ' ) ,
( ' /bin/baz ' , ' baz ' ) ,
( ' /bin/foobar ' , ' foobar ' ) ,
( ' /bin/asdf ' , ' /bin/asdf ' ) ,
( ' @ {foo} ' , None ) , # XXX variables not supported yet (and @{foo} isn't defined in this test)
( ' /bin/404 ' , None ) ,
( ' /usr { , { /lib,/lib32,/lib64}/wine}/bin/wine { ,-preloader,server} { ,-staging-*,-vanilla-*} ' , ' wine ' ) , # XXX should this really match, or should attachment matching only use AARE?
( ' /usr/lib/wine/bin/wine-preloader-staging-foo ' , ' wine ' ) , # AARE match
)
def _run_test ( self , params , expected ) :
self . assertEqual ( self . pl . profile_from_attachment ( params ) , expected )
def test_non_path_attachment ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . profile_from_attachment ( ' foo ' )
2022-08-07 12:26:24 -04:00
2020-05-04 21:12:15 +02:00
class TestAdd_inc_ie ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
def testAdd_inc_ie_1 ( self ) :
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , IncludeRule ( ' tunables/global ' , False , True ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' include <tunables/global> ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' include <tunables/global> ' , ' ' ] )
def testAdd_inc_ie_2 ( self ) :
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , IncludeRule ( ' tunables/global ' , False , True ) )
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , IncludeRule ( ' tunables/dovecot ' , False , True ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' include <tunables/global> ' , ' include <tunables/dovecot> ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' include <tunables/global> ' , ' include <tunables/dovecot> ' , ' ' ] )
def testAdd_inc_ie_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , ' tunables/global ' ) # str instead of IncludeRule
2020-05-04 21:12:15 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2020-05-14 21:56:44 +02:00
def test_dedup_inc_ie_1 ( self ) :
2022-09-10 19:45:22 -04:00
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , IncludeRule . create_instance ( ' include <tunables/global> ' ) )
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , IncludeRule . create_instance ( ' #include if exists <tunables/global> # comment ' ) )
self . pl . add_inc_ie ( ' /etc/apparmor.d/bin.foo ' , IncludeRule . create_instance ( ' #include <tunables/global> ' ) )
2020-05-14 21:56:44 +02:00
deleted = self . pl . delete_preamble_duplicates ( ' /etc/apparmor.d/bin.foo ' )
self . assertEqual ( deleted , 2 )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' include <tunables/global> ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' include <tunables/global> ' , ' ' ] )
def test_dedup_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . delete_preamble_duplicates ( ' /file/not/found ' )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2022-08-07 12:26:24 -04:00
2020-05-09 20:01:20 +02:00
class TestAdd_abi ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
def testAdd_abi_1 ( self ) :
self . pl . add_abi ( ' /etc/apparmor.d/bin.foo ' , AbiRule ( ' abi/4.19 ' , False , True ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
2020-05-22 00:57:20 +02:00
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' abi <abi/4.19>, ' , ' ' ] )
2020-05-09 20:01:20 +02:00
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' abi <abi/4.19>, ' , ' ' ] )
def testAdd_abi_2 ( self ) :
self . pl . add_abi ( ' /etc/apparmor.d/bin.foo ' , AbiRule ( ' abi/4.19 ' , False , True ) )
self . pl . add_abi ( ' /etc/apparmor.d/bin.foo ' , AbiRule ( ' foo ' , False , False ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
2020-05-22 00:57:20 +02:00
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' abi <abi/4.19>, ' , ' abi " foo " , ' , ' ' ] )
2020-05-09 20:01:20 +02:00
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' abi <abi/4.19>, ' , ' abi " foo " , ' , ' ' ] )
def testAdd_abi_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_abi ( ' /etc/apparmor.d/bin.foo ' , ' abi/4.19 ' ) # str instead of AbiRule
2020-05-09 20:01:20 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2020-05-14 21:56:44 +02:00
def test_dedup_abi_1 ( self ) :
2022-09-10 19:45:22 -04:00
self . pl . add_abi ( ' /etc/apparmor.d/bin.foo ' , AbiRule . create_instance ( ' abi <abi/4.19>, ' ) )
self . pl . add_abi ( ' /etc/apparmor.d/bin.foo ' , AbiRule . create_instance ( ' abi <abi/4.19> , # comment ' ) )
2020-05-14 21:56:44 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
deleted = self . pl . delete_preamble_duplicates ( ' /etc/apparmor.d/bin.foo ' )
self . assertEqual ( deleted , 1 )
2020-05-22 00:57:20 +02:00
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' abi <abi/4.19>, ' , ' ' ] )
2020-05-14 21:56:44 +02:00
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' abi <abi/4.19>, ' , ' ' ] )
2022-08-07 12:26:24 -04:00
2020-05-10 13:01:38 +02:00
class TestAdd_alias ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
def testAdd_alias_1 ( self ) :
2020-05-24 15:00:42 +02:00
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /bar ' ) )
2020-05-10 13:01:38 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
2020-05-22 00:57:20 +02:00
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' ' ] )
2020-05-10 13:01:38 +02:00
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' ' ] )
def testAdd_alias_2 ( self ) :
2020-05-24 15:00:42 +02:00
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /bar ' ) )
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /xyz ' , ' /zyx ' ) )
2020-05-10 13:01:38 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
2020-05-22 00:57:20 +02:00
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' alias /xyz -> /zyx, ' , ' ' ] )
2020-05-10 13:01:38 +02:00
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' alias /xyz -> /zyx, ' , ' ' ] )
2020-05-24 15:00:42 +02:00
def testAdd_alias_two_targets ( self ) :
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /bar ' ) )
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /another_target ' ) )
2020-05-10 13:01:38 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
2020-05-24 15:00:42 +02:00
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' alias /foo -> /another_target, ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' alias /foo -> /another_target, ' , ' ' ] )
2020-05-10 13:01:38 +02:00
def testAdd_alias_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( None , ' /foo ' ) ) # alias None instead of str
2020-05-10 13:01:38 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
def testAdd_alias_error_2 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , None ) ) # target None instead of str
2020-05-10 13:01:38 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2020-12-25 18:48:27 +01:00
def testAdd_alias_error_3 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , ' alias /foo -> /bar, ' ) # str instead of AliasRule
2020-12-25 18:48:27 +01:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2020-05-24 15:00:42 +02:00
def test_dedup_alias_1 ( self ) :
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /bar ' ) )
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /another_target ' ) )
self . pl . add_alias ( ' /etc/apparmor.d/bin.foo ' , AliasRule ( ' /foo ' , ' /bar ' ) ) # duplicate
deleted = self . pl . delete_preamble_duplicates ( ' /etc/apparmor.d/bin.foo ' )
self . assertEqual ( deleted , 1 )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' alias /foo -> /another_target, ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' alias /foo -> /bar, ' , ' alias /foo -> /another_target, ' , ' ' ] )
2020-05-14 21:56:44 +02:00
2022-08-07 12:26:24 -04:00
2020-05-21 23:21:11 +02:00
class TestAdd_variable ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
def testAdd_variable_1 ( self ) :
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , VariableRule ( ' @ {foo} ' , ' = ' , { ' /foo ' } ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' @ {foo} = /foo ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' @ {foo} = /foo ' , ' ' ] )
def testAdd_variable_2 ( self ) :
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , VariableRule ( ' @ {foo} ' , ' = ' , { ' /foo ' } ) )
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , VariableRule ( ' @ {bar} ' , ' = ' , { ' /bar ' } ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' @ {foo} = /foo ' , ' @ {bar} = /bar ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' @ {foo} = /foo ' , ' @ {bar} = /bar ' , ' ' ] )
def testAdd_variable_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , ' @ {foo} ' ) # str instead of IncludeRule
2020-05-21 23:21:11 +02:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
def test_dedup_variable_1 ( self ) :
2022-09-10 19:45:22 -04:00
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , VariableRule . create_instance ( ' @ {foo} = /foo ' ) )
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , VariableRule . create_instance ( ' @ {foo} += /bar # comment ' ) )
self . pl . add_variable ( ' /etc/apparmor.d/bin.foo ' , VariableRule . create_instance ( ' @ {foo} += /bar /baz ' ) )
2020-05-21 23:21:11 +02:00
deleted = self . pl . delete_preamble_duplicates ( ' /etc/apparmor.d/bin.foo ' )
self . assertEqual ( deleted , 1 )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' @ {foo} = /foo ' , ' @ {foo} += /bar /baz ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' @ {foo} = /foo ' , ' @ {foo} += /bar /baz ' , ' ' ] )
def test_dedup_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . delete_preamble_duplicates ( ' /file/not/found ' )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2022-08-07 12:26:24 -04:00
2020-12-25 17:42:31 +01:00
class TestAdd_boolean ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
def testAdd_variable_1 ( self ) :
self . pl . add_boolean ( ' /etc/apparmor.d/bin.foo ' , BooleanRule ( ' $foo ' , ' true ' ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' $foo = true ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' $foo = true ' , ' ' ] )
def testAdd_variable_2 ( self ) :
self . pl . add_boolean ( ' /etc/apparmor.d/bin.foo ' , BooleanRule ( ' $foo ' , ' true ' ) )
self . pl . add_boolean ( ' /etc/apparmor.d/bin.foo ' , BooleanRule ( ' $bar ' , ' false ' ) )
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ' /etc/apparmor.d/bin.foo ' ] )
self . assertEqual ( self . pl . get_clean ( ' /etc/apparmor.d/bin.foo ' ) , [ ' $foo = true ' , ' $bar = false ' , ' ' ] )
self . assertEqual ( self . pl . get_raw ( ' /etc/apparmor.d/bin.foo ' ) , [ ' $foo = true ' , ' $bar = false ' , ' ' ] )
def testAdd_variable_error_1 ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 13:57:37 -04:00
self . pl . add_boolean ( ' /etc/apparmor.d/bin.foo ' , ' $foo ' ) # str instead of IncludeRule
2020-12-25 17:42:31 +01:00
self . assertEqual ( list ( self . pl . files . keys ( ) ) , [ ] )
2022-08-07 12:26:24 -04:00
2020-05-04 21:12:15 +02:00
class TestGet ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
def testGet_clean_error ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . get_clean ( ' /etc/apparmor.d/not.found ' )
def testGet_raw_error ( self ) :
with self . assertRaises ( AppArmorBug ) :
self . pl . get_raw ( ' /etc/apparmor.d/not.found ' )
2022-08-07 12:26:24 -04:00
2020-05-23 00:02:49 +02:00
class AaTest_get_all_merged_variables ( AATest ) :
2022-06-18 14:30:49 -04:00
tests = ( )
2020-05-23 00:02:49 +02:00
def AASetup ( self ) :
self . createTmpdir ( )
# copy the local profiles to the test directory
2023-02-19 16:26:14 -05:00
self . profile_dir = self . tmpdir + ' /profiles '
2020-05-23 00:02:49 +02:00
apparmor . aa . profile_dir = self . profile_dir
shutil . copytree ( ' ../../profiles/apparmor.d/ ' , self . profile_dir , symlinks = True )
def _load_profiles ( self ) :
apparmor . aa . reset_aa ( )
# load the profiles and abstractions
2020-06-01 15:54:34 +02:00
apparmor . aa . profile_dir = self . profile_dir
2020-05-23 00:02:49 +02:00
apparmor . aa . loadincludes ( )
apparmor . aa . read_profiles ( )
def test_unchanged ( self ) :
self . _load_profiles ( )
prof_filename = os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' )
2022-08-07 12:26:24 -04:00
vars = apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' ) ,
apparmor . aa . include_list_recursive ( apparmor . aa . active_profiles . files [ prof_filename ] , True ) )
2020-05-23 00:02:49 +02:00
self . assertEqual ( vars [ ' @ {TFTP_DIR} ' ] , { ' /var/tftp ' , ' /srv/tftp ' , ' /srv/tftpboot ' } )
self . assertEqual ( vars [ ' @ {HOME} ' ] , { ' @ {HOMEDIRS} /*/ ' , ' /root/ ' } )
def test_extended_home ( self ) :
write_file ( self . profile_dir , ' tunables/home.d/extend_home ' , ' @ {HOME} += /my/castle/ ' )
self . _load_profiles ( )
prof_filename = os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' )
2022-08-07 12:26:24 -04:00
vars = apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' ) ,
apparmor . aa . include_list_recursive ( apparmor . aa . active_profiles . files [ prof_filename ] , True ) )
2020-05-23 00:02:49 +02:00
self . assertEqual ( vars [ ' @ {TFTP_DIR} ' ] , { ' /var/tftp ' , ' /srv/tftp ' , ' /srv/tftpboot ' } )
self . assertEqual ( vars [ ' @ {HOME} ' ] , { ' @ {HOMEDIRS} /*/ ' , ' /root/ ' , ' /my/castle/ ' } )
def test_extended_home_2 ( self ) :
write_file ( self . profile_dir , ' tunables/home.d/extend_home ' , ' @ {HOME} += /my/castle/ ' )
write_file ( self . profile_dir , ' tunables/home.d/moving_around ' , ' @ {HOME} += /on/the/road/ ' )
self . _load_profiles ( )
prof_filename = os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' )
2022-08-07 12:26:24 -04:00
vars = apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' ) ,
apparmor . aa . include_list_recursive ( apparmor . aa . active_profiles . files [ prof_filename ] , True ) )
2020-05-23 00:02:49 +02:00
self . assertEqual ( vars [ ' @ {TFTP_DIR} ' ] , { ' /var/tftp ' , ' /srv/tftp ' , ' /srv/tftpboot ' } )
self . assertEqual ( vars [ ' @ {HOME} ' ] , { ' @ {HOMEDIRS} /*/ ' , ' /root/ ' , ' /my/castle/ ' , ' /on/the/road/ ' } )
def test_extend_home_in_mainfile ( self ) :
write_file ( self . profile_dir , ' tunables/home.d/extend_home ' , ' @ {HOME} += /my/castle/ ' )
write_file ( self . profile_dir , ' dummy_profile ' , ' include <tunables/global> \n @ {HOME} += /in/the/profile/ ' )
self . _load_profiles ( )
prof_filename = os . path . join ( self . profile_dir , ' dummy_profile ' )
2022-08-07 12:26:24 -04:00
vars = apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' dummy_profile ' ) ,
apparmor . aa . include_list_recursive ( apparmor . aa . active_profiles . files [ prof_filename ] , True ) )
2020-05-23 00:02:49 +02:00
self . assertEqual ( vars . get ( ' @ {TFTP_DIR} ' , None ) , None )
self . assertEqual ( vars [ ' @ {HOME} ' ] , { ' @ {HOMEDIRS} /*/ ' , ' /root/ ' , ' /my/castle/ ' , ' /in/the/profile/ ' } )
def test_redefine_home ( self ) :
write_file ( self . profile_dir , ' tunables/home.d/overwrite_home ' , ' @ {HOME} = /my/castle/ ' ) # note: =, not +=
self . _load_profiles ( )
prof_filename = os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' )
with self . assertRaises ( AppArmorException ) :
2022-08-07 12:26:24 -04:00
apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' ) ,
apparmor . aa . include_list_recursive ( apparmor . aa . active_profiles . files [ prof_filename ] , True ) )
2020-05-23 00:02:49 +02:00
def test_add_to_nonexisting ( self ) :
write_file ( self . profile_dir , ' tunables/home.d/no_such_var ' , ' @ {NO_SUCH_HOME} += /my/castle/ ' ) # add to non-existing variable
self . _load_profiles ( )
prof_filename = os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' )
with self . assertRaises ( AppArmorException ) :
2022-08-07 12:26:24 -04:00
apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' usr.sbin.dnsmasq ' ) ,
apparmor . aa . include_list_recursive ( apparmor . aa . active_profiles . files [ prof_filename ] , True ) )
2020-05-23 00:02:49 +02:00
2020-05-23 15:40:03 +02:00
def test_vars_from_nonexisting_profile ( self ) :
with self . assertRaises ( AppArmorBug ) :
2022-08-07 12:26:24 -04:00
apparmor . aa . active_profiles . get_all_merged_variables (
os . path . join ( self . profile_dir , ' file.not.found ' ) , list ( ) )
2020-05-23 15:40:03 +02:00
2021-04-05 14:21:44 +02:00
class TestGet_profile_and_childs ( AATest ) :
def AASetup ( self ) :
self . pl = ProfileList ( )
self . dummy_profile = ProfileStorage ( ' TEST DUMMY ' , ' AATest_no_file ' , ' TEST ' )
def testGet_profile_and_childs1 ( self ) :
2022-08-07 12:26:24 -04:00
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' bafoo ' , ' /bin/bafoo ' , self . dummy_profile )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo ' , ' /bin/foo ' , self . dummy_profile )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foobar ' , ' /bin/foobar ' , self . dummy_profile )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo//bar ' , ' /bin/foo//bar ' , self . dummy_profile )
self . pl . add_profile ( ' /etc/apparmor.d/bin.foo ' , ' foo//xy ' , ' /bin/foo//xy ' , self . dummy_profile )
2021-04-05 14:21:44 +02:00
expected = [ ' foo ' , ' foo//bar ' , ' foo//xy ' ]
self . assertEqual ( list ( self . pl . get_profile_and_childs ( ' foo ' ) ) , expected )
2024-11-01 20:18:23 +01:00
# while on it, also test get_all_profiles()
all_profiles = [ ' bafoo ' , ' foo ' , ' foobar ' , ' foo//bar ' , ' foo//xy ' ]
self . assertEqual ( list ( self . pl . get_all_profiles ( ) ) , all_profiles )
2018-10-21 20:39:51 +02:00
2020-05-23 00:02:49 +02:00
setup_aa ( apparmor . aa )
2018-10-21 20:39:51 +02:00
setup_all_loops ( __name__ )
if __name__ == ' __main__ ' :
unittest . main ( verbosity = 1 )