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