mirror of
https://github.com/SELinuxProject/setools
synced 2025-03-11 07:18:15 +00:00
Implement CommonTest and ObjClassTest.
Also fix bugs uncovered by testing.
This commit is contained in:
parent
7cb5762b4f
commit
6de35b81f7
@ -376,7 +376,7 @@ int qpol_policy_get_class_by_name(const qpol_policy_t * policy, const char *name
|
||||
if (internal_datum == NULL) {
|
||||
*obj_class = NULL;
|
||||
ERR(policy, "could not find class %s", name);
|
||||
errno = ENOENT;
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
|
||||
@ -541,7 +541,7 @@ int qpol_policy_get_common_by_name(const qpol_policy_t * policy, const char *nam
|
||||
if (internal_datum == NULL) {
|
||||
*common = NULL;
|
||||
ERR(policy, "could not find common %s", name);
|
||||
errno = ENOENT;
|
||||
errno = EINVAL;
|
||||
return STATUS_ERR;
|
||||
}
|
||||
*common = (qpol_common_t *) internal_datum;
|
||||
|
@ -56,7 +56,7 @@ class Common(symbol.PolicySymbol):
|
||||
"""A common permission set."""
|
||||
|
||||
def __contains__(self, other):
|
||||
return (other in self.perms)
|
||||
return other in self.perms
|
||||
|
||||
@property
|
||||
def perms(self):
|
||||
@ -71,6 +71,15 @@ class ObjClass(Common):
|
||||
|
||||
"""An object class."""
|
||||
|
||||
def __contains__(self, other):
|
||||
try:
|
||||
if other in self.common.perms:
|
||||
return True
|
||||
except exception.NoCommon:
|
||||
pass
|
||||
|
||||
return other in self.perms
|
||||
|
||||
@property
|
||||
def common(self):
|
||||
"""
|
||||
|
@ -1942,16 +1942,24 @@ typedef struct qpol_context {} qpol_context_t;
|
||||
/* qpol class */
|
||||
typedef struct qpol_class {} qpol_class_t;
|
||||
%extend qpol_class {
|
||||
%exception qpol_class {
|
||||
$action
|
||||
if (!result) {
|
||||
if (errno == EINVAL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid class.");
|
||||
} else {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
qpol_class(qpol_policy_t *p, const char *name) {
|
||||
const qpol_class_t *c;
|
||||
BEGIN_EXCEPTION
|
||||
if (qpol_policy_get_class_by_name(p, name, &c)) {
|
||||
SWIG_exception(SWIG_RuntimeError, "Class does not exist");
|
||||
}
|
||||
END_EXCEPTION
|
||||
fail:
|
||||
qpol_policy_get_class_by_name(p, name, &c);
|
||||
return (qpol_class_t*)c;
|
||||
};
|
||||
|
||||
~qpol_class() {
|
||||
/* no op */
|
||||
return;
|
||||
@ -2041,16 +2049,24 @@ typedef struct qpol_class {} qpol_class_t;
|
||||
/* qpol common */
|
||||
typedef struct qpol_common {} qpol_common_t;
|
||||
%extend qpol_common {
|
||||
%exception qpol_common {
|
||||
$action
|
||||
if (!result) {
|
||||
if (errno == EINVAL) {
|
||||
PyErr_SetString(PyExc_ValueError, "Invalid common.");
|
||||
} else {
|
||||
PyErr_SetFromErrno(PyExc_OSError);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
qpol_common(qpol_policy_t *p, const char *name) {
|
||||
const qpol_common_t *c;
|
||||
BEGIN_EXCEPTION
|
||||
if (qpol_policy_get_common_by_name(p, name, &c)) {
|
||||
SWIG_exception(SWIG_RuntimeError, "Common does not exist");
|
||||
}
|
||||
END_EXCEPTION
|
||||
fail:
|
||||
qpol_policy_get_common_by_name(p, name, &c);
|
||||
return (qpol_common_t*)c;
|
||||
};
|
||||
|
||||
~qpol_common() {
|
||||
/* no op */
|
||||
return;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#
|
||||
from . import mls
|
||||
from . import mlsrule
|
||||
from . import objclass
|
||||
from . import polcap
|
||||
from . import rbacrule
|
||||
from . import role
|
||||
|
149
tests/policyrep/objclass.conf
Normal file
149
tests/policyrep/objclass.conf
Normal file
@ -0,0 +1,149 @@
|
||||
class infoflow
|
||||
class infoflow2
|
||||
class infoflow3
|
||||
class infoflow4
|
||||
class infoflow5
|
||||
class infoflow6
|
||||
class infoflow7
|
||||
class infoflow8
|
||||
class infoflow9
|
||||
class infoflow10
|
||||
|
||||
sid kernel
|
||||
sid security
|
||||
|
||||
common infoflow
|
||||
{
|
||||
low_w
|
||||
med_w
|
||||
hi_w
|
||||
low_r
|
||||
med_r
|
||||
hi_r
|
||||
}
|
||||
|
||||
common com_a
|
||||
{
|
||||
hi_w
|
||||
hi_r
|
||||
super_r
|
||||
super_w
|
||||
}
|
||||
|
||||
common com_b
|
||||
{
|
||||
send
|
||||
recv
|
||||
}
|
||||
|
||||
common com_c
|
||||
{
|
||||
getattr
|
||||
setattr
|
||||
read
|
||||
write
|
||||
}
|
||||
|
||||
class infoflow
|
||||
inherits infoflow
|
||||
|
||||
class infoflow2
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow3
|
||||
{
|
||||
null
|
||||
}
|
||||
|
||||
class infoflow4
|
||||
inherits infoflow
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
super_none
|
||||
super_both
|
||||
super_unmapped
|
||||
}
|
||||
|
||||
class infoflow5
|
||||
inherits com_a
|
||||
|
||||
class infoflow6
|
||||
inherits com_b
|
||||
|
||||
class infoflow7
|
||||
inherits infoflow
|
||||
{
|
||||
unmapped
|
||||
}
|
||||
|
||||
class infoflow8
|
||||
{
|
||||
super_w
|
||||
super_r
|
||||
}
|
||||
|
||||
class infoflow9
|
||||
inherits com_c
|
||||
|
||||
class infoflow10
|
||||
{
|
||||
read
|
||||
write
|
||||
}
|
||||
|
||||
sensitivity low_s;
|
||||
sensitivity medium_s alias med;
|
||||
sensitivity high_s;
|
||||
|
||||
dominance { low_s med high_s }
|
||||
|
||||
category here;
|
||||
category there;
|
||||
category elsewhere alias lost;
|
||||
|
||||
#level decl
|
||||
level low_s:here.there;
|
||||
level med:here, elsewhere;
|
||||
level high_s:here.lost;
|
||||
|
||||
#some constraints
|
||||
mlsconstrain infoflow hi_r ((l1 dom l2) or (t1 == mls_exempt));
|
||||
|
||||
attribute mls_exempt;
|
||||
|
||||
type system;
|
||||
role system;
|
||||
role system types system;
|
||||
|
||||
#users
|
||||
user system roles system level med range low_s - high_s:here.lost;
|
||||
|
||||
#normal constraints
|
||||
constrain infoflow hi_w (u1 == u2);
|
||||
|
||||
#isids
|
||||
sid kernel system:system:system:medium_s:here
|
||||
sid security system:system:system:high_s:lost
|
||||
|
||||
#fs_use
|
||||
fs_use_trans devpts system:object_r:system:low_s;
|
||||
fs_use_xattr ext3 system:object_r:system:low_s;
|
||||
fs_use_task pipefs system:object_r:system:low_s;
|
||||
|
||||
#genfscon
|
||||
genfscon proc / system:object_r:system:med
|
||||
genfscon proc /sys system:object_r:system:low_s
|
||||
genfscon selinuxfs / system:object_r:system:high_s:here.there
|
||||
|
||||
portcon tcp 80 system:object_r:system:low_s
|
||||
|
||||
netifcon eth0 system:object_r:system:low_s system:object_r:system:low_s
|
||||
|
||||
nodecon 127.0.0.1 255.255.255.255 system:object_r:system:low_s:here
|
||||
nodecon ::1 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff system:object_r:system:low_s:here
|
||||
|
175
tests/policyrep/objclass.py
Normal file
175
tests/policyrep/objclass.py
Normal file
@ -0,0 +1,175 @@
|
||||
# Copyright 2015, Tresys Technology, LLC
|
||||
#
|
||||
# This file is part of SETools.
|
||||
#
|
||||
# SETools is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# SETools 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with SETools. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest.mock import Mock
|
||||
except ImportError:
|
||||
from mock import Mock
|
||||
|
||||
from setools import SELinuxPolicy
|
||||
from setools.policyrep import qpol
|
||||
from setools.policyrep.exception import InvalidCommon, InvalidClass
|
||||
from setools.policyrep.objclass import common_factory, class_factory
|
||||
|
||||
|
||||
class CommonTest(unittest.TestCase):
|
||||
|
||||
@staticmethod
|
||||
def mock_common(name, perms):
|
||||
policy = Mock(qpol.qpol_policy_t)
|
||||
com = Mock(qpol.qpol_common_t)
|
||||
com.name.return_value = name
|
||||
com.perm_iter = lambda x: iter(perms)
|
||||
return common_factory(policy, com)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/policyrep/objclass.conf")
|
||||
|
||||
def test_001_lookup(self):
|
||||
"""Common: factory policy lookup."""
|
||||
com = common_factory(self.p.policy, "com_a")
|
||||
self.assertEqual("com_a", com.qpol_symbol.name(self.p.policy))
|
||||
|
||||
def test_002_lookup_invalid(self):
|
||||
"""Common: factory policy invalid lookup."""
|
||||
with self.assertRaises(InvalidCommon):
|
||||
common_factory(self.p.policy, "INVALID")
|
||||
|
||||
def test_003_lookup_object(self):
|
||||
"""Common: factory policy lookup of Common object."""
|
||||
com1 = common_factory(self.p.policy, "com_b")
|
||||
com2 = common_factory(self.p.policy, com1)
|
||||
self.assertIs(com2, com1)
|
||||
|
||||
def test_010_string(self):
|
||||
"""Common: string representation"""
|
||||
com = self.mock_common("test10", ["perm1", "perm2"])
|
||||
self.assertEquals("test10", str(com))
|
||||
|
||||
def test_020_perms(self):
|
||||
"""Common: permissions"""
|
||||
com = self.mock_common("test20", ["perm1", "perm2"])
|
||||
self.assertEquals(set(["perm1", "perm2"]), com.perms)
|
||||
|
||||
def test_030_statment(self):
|
||||
"""Common: statement."""
|
||||
com = self.mock_common("test30", ["perm1", "perm2"])
|
||||
self.assertRegexpMatches(com.statement(), "("
|
||||
"common test30\n{\n\tperm1\n\tperm2\n}"
|
||||
"|"
|
||||
"common test30\n{\n\tperm2\n\tperm1\n}"
|
||||
")")
|
||||
|
||||
def test_040_contains(self):
|
||||
"""Common: contains"""
|
||||
com = self.mock_common("test40", ["perm1", "perm2"])
|
||||
self.assertIn("perm1", com)
|
||||
self.assertNotIn("perm3", com)
|
||||
|
||||
|
||||
class ObjClassTest(unittest.TestCase):
|
||||
|
||||
@staticmethod
|
||||
def mock_class(name, perms, com_perms=[]):
|
||||
policy = Mock(qpol.qpol_policy_t)
|
||||
|
||||
cls = Mock(qpol.qpol_class_t)
|
||||
cls.name.return_value = name
|
||||
cls.perm_iter = lambda x: iter(perms)
|
||||
|
||||
if com_perms:
|
||||
com = Mock(qpol.qpol_common_t)
|
||||
com.name.return_value = name+"_common"
|
||||
com.perm_iter = lambda x: iter(com_perms)
|
||||
cls.common.return_value = com
|
||||
else:
|
||||
cls.common.side_effect = ValueError
|
||||
|
||||
return class_factory(policy, cls)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.p = SELinuxPolicy("tests/policyrep/objclass.conf")
|
||||
|
||||
def test_001_lookup(self):
|
||||
"""ObjClass: factory policy lookup."""
|
||||
cls = class_factory(self.p.policy, "infoflow")
|
||||
self.assertEqual("infoflow", cls.qpol_symbol.name(self.p.policy))
|
||||
|
||||
def test_002_lookup_invalid(self):
|
||||
"""ObjClass: factory policy invalid lookup."""
|
||||
with self.assertRaises(InvalidClass):
|
||||
class_factory(self.p.policy, "INVALID")
|
||||
|
||||
def test_003_lookup_object(self):
|
||||
"""ObjClass: factory policy lookup of ObjClass object."""
|
||||
cls1 = class_factory(self.p.policy, "infoflow4")
|
||||
cls2 = class_factory(self.p.policy, cls1)
|
||||
self.assertIs(cls2, cls1)
|
||||
|
||||
def test_010_string(self):
|
||||
"""ObjClass: string representation"""
|
||||
cls = self.mock_class("test10", ["perm1", "perm2"])
|
||||
self.assertEquals("test10", str(cls))
|
||||
|
||||
def test_020_perms(self):
|
||||
"""ObjClass: permissions"""
|
||||
cls = self.mock_class("test20", ["perm1", "perm2"], com_perms=["perm3", "perm4"])
|
||||
self.assertEquals(set(["perm1", "perm2"]), cls.perms)
|
||||
|
||||
def test_030_statment(self):
|
||||
"""ObjClass: statement, no common."""
|
||||
cls = self.mock_class("test30", ["perm1", "perm2"])
|
||||
self.assertRegexpMatches(cls.statement(), "("
|
||||
"class test30\n{\n\tperm1\n\tperm2\n}"
|
||||
"|"
|
||||
"class test30\n{\n\tperm2\n\tperm1\n}"
|
||||
")")
|
||||
|
||||
def test_031_statment(self):
|
||||
"""ObjClass: statement, with common."""
|
||||
cls = self.mock_class("test31", ["perm1", "perm2"], com_perms=["perm3", "perm4"])
|
||||
self.assertRegexpMatches(cls.statement(), "("
|
||||
"class test31\ninherits test31_common\n{\n\tperm1\n\tperm2\n}"
|
||||
"|"
|
||||
"class test31\ninherits test31_common\n{\n\tperm2\n\tperm1\n}"
|
||||
")")
|
||||
|
||||
def test_032_statment(self):
|
||||
"""ObjClass: statement, with common, no class perms."""
|
||||
cls = self.mock_class("test32", [], com_perms=["perm3", "perm4"])
|
||||
self.assertRegexpMatches(cls.statement(), "("
|
||||
"class test32\ninherits test32_common"
|
||||
"|"
|
||||
"class test32\ninherits test32_common"
|
||||
")")
|
||||
|
||||
def test_040_contains(self):
|
||||
"""ObjClass: contains"""
|
||||
cls = self.mock_class("test40", ["perm1", "perm2"])
|
||||
self.assertIn("perm1", cls)
|
||||
self.assertNotIn("perm3", cls)
|
||||
|
||||
def test_041_contains_common(self):
|
||||
"""ObjClass: contains, with common"""
|
||||
cls = self.mock_class("test41", ["perm1", "perm2"], com_perms=["perm3", "perm4"])
|
||||
self.assertIn("perm1", cls)
|
||||
self.assertIn("perm3", cls)
|
||||
self.assertNotIn("perm5", cls)
|
Loading…
Reference in New Issue
Block a user