1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
# Copyright 2014, 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 Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with SETools. If not, see
# <http://www.gnu.org/licenses/>.
#
import stat
from . import exception
from . import qpol
from . import symbol
from . import context
def validate_ruletype(types):
"""Validate fs_use_* rule types."""
for t in types:
if t not in ["fs_use_xattr", "fs_use_trans", "fs_use_task"]:
raise exception.InvalidConstraintType("{0} is not a valid fs_use_* type.".format(t))
def fs_use_factory(policy, name):
"""Factory function for creating fs_use_* objects."""
if not isinstance(name, qpol.qpol_fs_use_t):
raise TypeError("fs_use_* cannot be looked-up.")
return FSUse(policy, name)
def genfscon_factory(policy, name):
"""Factory function for creating genfscon objects."""
if not isinstance(name, qpol.qpol_genfscon_t):
raise TypeError("Genfscons cannot be looked-up.")
return Genfscon(policy, name)
class FSContext(symbol.PolicySymbol):
"""Base class for in-policy labeling rules."""
def __str__(self):
raise NotImplementedError
@property
def fs(self):
"""The filesystem type for this statement."""
return self.qpol_symbol.name(self.policy)
@property
def context(self):
"""The context for this statement."""
return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))
def statement(self):
return str(self)
class Genfscon(FSContext):
"""A genfscon statement."""
_filetype_to_text = {
0: "",
stat.S_IFBLK: "-b",
stat.S_IFCHR: "-c",
stat.S_IFDIR: "-d",
stat.S_IFIFO: "-p",
stat.S_IFREG: "--",
stat.S_IFLNK: "-l",
stat.S_IFSOCK: "-s"}
def __str__(self):
return "genfscon {0.fs} {0.path} {1} {0.context}".format(
self, self._filetype_to_text[self.filetype])
def __eq__(self, other):
# Libqpol allocates new C objects in the
# genfscons iterator, so pointer comparison
# in the PolicySymbol object doesn't work.
try:
return (self.fs == other.fs and
self.path == other.path and
self.filetype == other.filetype and
self.context == other.context)
except AttributeError:
return str(self) == str(other)
@property
def filetype(self):
"""The file type (e.g. stat.S_IFBLK) for this genfscon statement."""
return self.qpol_symbol.object_class(self.policy)
@property
def path(self):
"""The path for this genfscon statement."""
return self.qpol_symbol.path(self.policy)
class FSUse(FSContext):
"""A fs_use_* statement."""
# there are more rule types, but modern SELinux
# only supports these three.
_ruletype_to_text = {
qpol.QPOL_FS_USE_XATTR: 'fs_use_xattr',
qpol.QPOL_FS_USE_TRANS: 'fs_use_trans',
qpol.QPOL_FS_USE_TASK: 'fs_use_task'}
def __str__(self):
return "{0.ruletype} {0.fs} {0.context};".format(self)
@property
def ruletype(self):
"""The rule type for this fs_use_* statement."""
return self._ruletype_to_text[self.qpol_symbol.behavior(self.policy)]
|