Home | History | Annotate | Download | only in policyrep
      1 # Copyright 2014, 2016, 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 exception
     22 from . import qpol
     23 from . import symbol
     24 from . import context
     25 
     26 
     27 def validate_ruletype(t):
     28     """Validate fs_use_* rule types."""
     29     if t not in ["fs_use_xattr", "fs_use_trans", "fs_use_task"]:
     30         raise exception.InvalidFSUseType("{0} is not a valid fs_use_* type.".format(t))
     31 
     32     return t
     33 
     34 
     35 def fs_use_factory(policy, name):
     36     """Factory function for creating fs_use_* objects."""
     37 
     38     if not isinstance(name, qpol.qpol_fs_use_t):
     39         raise TypeError("fs_use_* cannot be looked-up.")
     40 
     41     return FSUse(policy, name)
     42 
     43 
     44 def genfscon_factory(policy, name):
     45     """Factory function for creating genfscon objects."""
     46 
     47     if not isinstance(name, qpol.qpol_genfscon_t):
     48         raise TypeError("Genfscons cannot be looked-up.")
     49 
     50     return Genfscon(policy, name)
     51 
     52 
     53 class FSContext(symbol.PolicySymbol):
     54 
     55     """Base class for in-policy labeling rules."""
     56 
     57     def __str__(self):
     58         raise NotImplementedError
     59 
     60     @property
     61     def fs(self):
     62         """The filesystem type for this statement."""
     63         return self.qpol_symbol.name(self.policy)
     64 
     65     @property
     66     def context(self):
     67         """The context for this statement."""
     68         return context.context_factory(self.policy, self.qpol_symbol.context(self.policy))
     69 
     70     def statement(self):
     71         return str(self)
     72 
     73 
     74 class GenfsFiletype(int):
     75 
     76     """
     77     A genfscon file type.
     78 
     79     The possible values are equivalent to file type
     80     values in the stat module, e.g. S_IFBLK, but
     81     overrides the string representation with the
     82     corresponding genfscon file type string
     83     (-b, -c, etc.)  If the genfscon has no specific
     84     file type, this is 0, (empty string).
     85     """
     86 
     87     _filetype_to_text = {
     88         0: "",
     89         stat.S_IFBLK: "-b",
     90         stat.S_IFCHR: "-c",
     91         stat.S_IFDIR: "-d",
     92         stat.S_IFIFO: "-p",
     93         stat.S_IFREG: "--",
     94         stat.S_IFLNK: "-l",
     95         stat.S_IFSOCK: "-s"}
     96 
     97     def __str__(self):
     98         return self._filetype_to_text[self]
     99 
    100 
    101 class Genfscon(FSContext):
    102 
    103     """A genfscon statement."""
    104 
    105     def __str__(self):
    106         return "genfscon {0.fs} {0.path} {0.filetype} {0.context}".format(self)
    107 
    108     def __hash__(self):
    109         return hash("genfscon|{0.fs}|{0.path}|{0.filetype}".format(self))
    110 
    111     def __eq__(self, other):
    112         # Libqpol allocates new C objects in the
    113         # genfscons iterator, so pointer comparison
    114         # in the PolicySymbol object doesn't work.
    115         try:
    116             return (self.fs == other.fs and
    117                     self.path == other.path and
    118                     self.filetype == other.filetype and
    119                     self.context == other.context)
    120         except AttributeError:
    121             return str(self) == str(other)
    122 
    123     @property
    124     def filetype(self):
    125         """The file type (e.g. stat.S_IFBLK) for this genfscon statement."""
    126         return GenfsFiletype(self.qpol_symbol.object_class(self.policy))
    127 
    128     @property
    129     def path(self):
    130         """The path for this genfscon statement."""
    131         return self.qpol_symbol.path(self.policy)
    132 
    133 
    134 class FSUse(FSContext):
    135 
    136     """A fs_use_* statement."""
    137 
    138     # there are more rule types, but modern SELinux
    139     # only supports these three.
    140     _ruletype_to_text = {
    141         qpol.QPOL_FS_USE_XATTR: 'fs_use_xattr',
    142         qpol.QPOL_FS_USE_TRANS: 'fs_use_trans',
    143         qpol.QPOL_FS_USE_TASK: 'fs_use_task'}
    144 
    145     def __str__(self):
    146         return "{0.ruletype} {0.fs} {0.context};".format(self)
    147 
    148     def __hash__(self):
    149         return hash("{0.ruletype}|{0.fs}".format(self))
    150 
    151     @property
    152     def ruletype(self):
    153         """The rule type for this fs_use_* statement."""
    154         return self._ruletype_to_text[self.qpol_symbol.behavior(self.policy)]
    155