PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 131
# Copyright 2014-2015, Tresys Technology, LLC # # SPDX-License-Identifier: LGPL-2.1-only # import logging import copy from collections import OrderedDict from contextlib import suppress from typing import cast, Dict, Iterable, NamedTuple, Optional, Union import pkg_resources from . import exception from .descriptors import PermissionMapDescriptor from .policyrep import AVRule, SELinuxPolicy, TERuletype INFOFLOW_DIRECTIONS = ("r", "w", "b", "n", "u") MIN_WEIGHT = 1 MAX_WEIGHT = 10 class RuleWeight(NamedTuple): """The read and write weights for a rule, given all of its permissions.""" read: int write: int # # Settings validation functions for Mapping descriptors # def validate_weight(weight: int) -> int: if not MIN_WEIGHT <= weight <= MAX_WEIGHT: raise ValueError("Permission weights must be 1-10: {0}".format(weight)) return weight def validate_direction(direction: str) -> str: if direction not in INFOFLOW_DIRECTIONS: raise ValueError("Invalid information flow direction: {0}".format(direction)) return direction # Internal data structure for permission map MapStruct = Dict[str, Dict[str, Dict[str, Union[bool, str, int]]]] class Mapping: """A mapping for a permission in the permission map.""" weight = PermissionMapDescriptor("weight", validate_weight) direction = PermissionMapDescriptor("direction", validate_direction) enabled = PermissionMapDescriptor("enabled", bool) class_: str perm: str def __init__(self, perm_map: MapStruct, classname: str, permission: str, create: bool = False) -> None: self._perm_map = perm_map self.class_ = classname self.perm = permission if create: if classname not in self._perm_map: self._perm_map[classname] = OrderedDict() self._perm_map[classname][permission] = {'direction': 'u', 'weight': 1, 'enabled': True} else: if classname not in self._perm_map: raise exception.UnmappedClass("{0} is not mapped.".format(classname)) if permission not in self._perm_map[classname]: raise exception.UnmappedPermission("{0}:{1} is not mapped.". format(classname, permission)) def __lt__(self, other) -> bool: if self.class_ == other.class_: return self.perm < other.perm return self.class_ < other.class_ class PermissionMap: """Permission Map for information flow analysis.""" def __init__(self, permmapfile: Optional[str] = None) -> None: """ Parameter: permmapfile The path to the permission map to load. """ self.log = logging.getLogger(__name__) self._permmap: MapStruct = OrderedDict() self._permmapfile: str if permmapfile: self.load(permmapfile) else: distro = pkg_resources.get_distribution("setools") # pylint: disable=no-member path = "{0}/setools/perm_map".format(distro.location) self.load(path) def __str__(self) -> str: return self._permmapfile def __deepcopy__(self, memo) -> 'PermissionMap': newobj = PermissionMap.__new__(PermissionMap) newobj.log = self.log newobj._permmap = copy.deepcopy(self._permmap) newobj._permmapfile = self._permmapfile memo[id(self)] = newobj return newobj def __iter__(self) -> Iterable[Mapping]: for cls in self.classes(): for mapping in self.perms(cls): yield mapping def load(self, permmapfile: str) -> None: """ Parameter: permmapfile The path to the permission map to load. """ self.log.info("Opening permission map \"{0}\"".format(permmapfile)) # state machine # 1 = read number of classes # 2 = read class name and number of perms # 3 = read perms with open(permmapfile, "r") as mapfile: total_perms = 0 class_count = 0 num_classes = 0 state = 1 self._permmap.clear() for line_num, line in enumerate(mapfile, start=1): entry = line.split() if len(entry) == 0 or entry[0][0] == '#': continue if state == 1: try: num_classes = int(entry[0]) except ValueError as ex: raise exception.PermissionMapParseError( "{0}:{1}:Invalid number of classes: {2}". format(permmapfile, line_num, entry[0])) from ex if num_classes < 1: raise exception.PermissionMapParseError( "{0}:{1}:Number of classes must be positive: {2}". format(permmapfile, line_num, entry[0])) state = 2 elif state == 2: if len(entry) != 3 or entry[0] != "class": raise exception.PermissionMapParseError( "{0}:{1}:Invalid class declaration: {2}". format(permmapfile, line_num, entry)) class_name = str(entry[1]) try: num_perms = int(entry[2]) except ValueError as ex: raise exception.PermissionMapParseError( "{0}:{1}:Invalid number of permissions: {2}". format(permmapfile, line_num, entry[2])) from ex if num_perms < 1: raise exception.PermissionMapParseError( "{0}:{1}:Number of permissions must be positive: {2}". format(permmapfile, line_num, entry[2])) class_count += 1 if class_count > num_classes: raise exception.PermissionMapParseError( "{0}:{1}:Extra class found: {2}". format(permmapfile, line_num, class_name)) self._permmap[class_name] = OrderedDict() perm_count = 0 state = 3 elif state == 3: perm_name = str(entry[0]) flow_direction = str(entry[1]) if flow_direction not in INFOFLOW_DIRECTIONS: raise exception.PermissionMapParseError( "{0}:{1}:Invalid information flow direction: {2}". format(permmapfile, line_num, entry[1])) try: weight = int(entry[2]) except ValueError as ex: raise exception.PermissionMapParseError( "{0}:{1}:Invalid permission weight: {2}". format(permmapfile, line_num, entry[2])) from ex if not MIN_WEIGHT <= weight <= MAX_WEIGHT: raise exception.PermissionMapParseError( "{0}:{1}:Permission weight must be {3}-{4}: {2}". format(permmapfile, line_num, entry[2], MIN_WEIGHT, MAX_WEIGHT)) self.log.debug("Read {0}:{1} {2} {3}".format( class_name, perm_name, flow_direction, weight)) if flow_direction == 'u': self.log.info("Permission {0}:{1} is unmapped.".format( class_name, perm_name)) mapping = Mapping(self._permmap, class_name, perm_name, create=True) mapping.direction = flow_direction mapping.weight = weight total_perms += 1 perm_count += 1 if perm_count >= num_perms: state = 2 self._permmapfile = permmapfile self.log.info("Successfully opened permission map \"{0}\"".format(permmapfile)) self.log.debug("Read {0} classes and {1} total permissions.".format( class_count, total_perms)) def save(self, permmapfile: str) -> None: """ Save the permission map to the specified path. Existing files will be overwritten. Parameter: permmapfile The path to write the permission map. """ with open(permmapfile, "w") as mapfile: self.log.info("Writing permission map to \"{0}\"".format(permmapfile)) mapfile.write("{0}\n\n".format(len(self._permmap))) for classname, perms in self._permmap.items(): mapfile.write("class {0} {1}\n".format(classname, len(perms))) for permname, settings in perms.items(): direction = cast(str, settings['direction']) weight = cast(int, settings['weight']) assert MIN_WEIGHT <= weight <= MAX_WEIGHT, \ "{0}:{1} weight is out of range ({2}). This is an SETools bug.".format( classname, permname, weight) assert direction in INFOFLOW_DIRECTIONS, \ "{0}:{1} flow direction ({2}) is invalid. This is an SETools bug.".format( classname, permname, direction) if direction == 'u': self.log.warning("Warning: permission {0} in class {1} is unmapped.".format( permname, classname)) mapfile.write("{0:>20} {1:>9} {2:>9}\n".format(permname, direction, weight)) mapfile.write("\n") self.log.info("Successfully wrote permission map to \"{0}\"".format(permmapfile)) def classes(self) -> Iterable[str]: """ Generate class names in the permission map. Yield: class An object class name. """ yield from self._permmap.keys() def perms(self, class_: str) -> Iterable[Mapping]: """ Generate permission mappings for the specified class. Parameter: class_ An object class name. Yield: Mapping A permission's complete map (weight, direction, enabled) """ try: for perm in self._permmap[class_].keys(): yield Mapping(self._permmap, class_, perm) except KeyError as ex: raise exception.UnmappedClass("{0} is not mapped.".format(class_)) from ex def mapping(self, class_: str, perm: str) -> Mapping: """Retrieve a specific permission's mapping.""" return Mapping(self._permmap, class_, perm) def exclude_class(self, class_: str) -> None: """ Exclude all permissions in an object class for calculating rule weights. Parameter: class_ The object class to exclude. Exceptions: UnmappedClass The specified object class is not mapped. """ for perm in self.perms(class_): perm.enabled = False def exclude_permission(self, class_: str, permission: str) -> None: """ Exclude a permission for calculating rule weights. Parameter: class_ The object class of the permission. permission The permission name to exclude. Exceptions: UnmappedClass The specified object class is not mapped. UnmappedPermission The specified permission is not mapped for the object class. """ Mapping(self._permmap, class_, permission).enabled = False def include_class(self, class_: str) -> None: """ Include all permissions in an object class for calculating rule weights. Parameter: class_ The object class to include. Exceptions: UnmappedClass The specified object class is not mapped. """ for perm in self.perms(class_): perm.enabled = True def include_permission(self, class_: str, permission: str) -> None: """ Include a permission for calculating rule weights. Parameter: class_ The object class of the permission. permission The permission name to include. Exceptions: UnmappedClass The specified object class is not mapped. UnmappedPermission The specified permission is not mapped for the object class. """ Mapping(self._permmap, class_, permission).enabled = True def map_policy(self, policy: SELinuxPolicy) -> None: """Create mappings for all classes and permissions in the specified policy.""" for class_ in policy.classes(): class_name = str(class_) if class_name not in self._permmap: self.log.debug("Adding unmapped class {0} from {1}".format(class_name, policy)) self._permmap[class_name] = OrderedDict() perms = class_.perms with suppress(exception.NoCommon): perms |= class_.common.perms for perm_name in perms: if perm_name not in self._permmap[class_name]: self.log.debug("Adding unmapped permission {0} in {1} from {2}". format(perm_name, class_name, policy)) Mapping(self._permmap, class_name, perm_name, create=True) def rule_weight(self, rule: AVRule) -> RuleWeight: """ Get the type enforcement rule's information flow read and write weights. Parameter: rule A type enforcement rule. Return: Tuple(read_weight, write_weight) read_weight The type enforcement rule's read weight. write_weight The type enforcement rule's write weight. """ write_weight = 0 read_weight = 0 class_name = str(rule.tclass) if rule.ruletype != TERuletype.allow: raise exception.RuleTypeError("{0} rules cannot be used for calculating a weight". format(rule.ruletype)) # iterate over the permissions and determine the # weight of the rule in each direction. The result # is the largest-weight permission in each direction for perm_name in rule.perms: mapping = Mapping(self._permmap, class_name, perm_name) if not mapping.enabled: continue if mapping.direction == "r": read_weight = max(read_weight, mapping.weight) elif mapping.direction == "w": write_weight = max(write_weight, mapping.weight) elif mapping.direction == "b": read_weight = max(read_weight, mapping.weight) write_weight = max(write_weight, mapping.weight) return RuleWeight(read_weight, write_weight) def set_direction(self, class_: str, permission: str, direction: str) -> None: """ Set the information flow direction of a permission. Parameter: class_ The object class of the permission. permission The permission name. direction The information flow direction the permission (r/w/b/n). Exceptions: UnmappedClass The specified object class is not mapped. UnmappedPermission The specified permission is not mapped for the object class. """ Mapping(self._permmap, class_, permission).direction = direction def set_weight(self, class_: str, permission: str, weight: int) -> None: """ Set the weight of a permission. Parameter: class_ The object class of the permission. permission The permission name. weight The weight of the permission (1-10). Exceptions: UnmappedClass The specified object class is not mapped. UnmappedPermission The specified permission is not mapped for the object class. """ Mapping(self._permmap, class_, permission).weight = weight