Home | History | Annotate | Download | only in diff
      1 # Copyright 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 from collections import namedtuple
     20 
     21 from .context import ContextWrapper
     22 from .descriptors import DiffResultDescriptor
     23 from .difference import Difference, Wrapper
     24 
     25 
     26 modified_netifcon_record = namedtuple("modified_netifcon", ["rule",
     27                                                             "added_context",
     28                                                             "removed_context",
     29                                                             "added_packet",
     30                                                             "removed_packet"])
     31 
     32 
     33 class NetifconsDifference(Difference):
     34 
     35     """Determine the difference in netifcons between two policies."""
     36 
     37     added_netifcons = DiffResultDescriptor("diff_netifcons")
     38     removed_netifcons = DiffResultDescriptor("diff_netifcons")
     39     modified_netifcons = DiffResultDescriptor("diff_netifcons")
     40 
     41     def diff_netifcons(self):
     42         """Generate the difference in netifcons between the policies."""
     43 
     44         self.log.info("Generating netifcon differences from {0.left_policy} to {0.right_policy}".
     45                       format(self))
     46 
     47         self.added_netifcons, self.removed_netifcons, matched_netifcons = self._set_diff(
     48             (NetifconWrapper(n) for n in self.left_policy.netifcons()),
     49             (NetifconWrapper(n) for n in self.right_policy.netifcons()))
     50 
     51         self.modified_netifcons = []
     52 
     53         for left_netifcon, right_netifcon in matched_netifcons:
     54             # Criteria for modified netifcons
     55             # 1. change to context
     56             # 2. change to packet context
     57             if ContextWrapper(left_netifcon.context) != ContextWrapper(right_netifcon.context):
     58                 removed_context = left_netifcon.context
     59                 added_context = right_netifcon.context
     60             else:
     61                 removed_context = None
     62                 added_context = None
     63 
     64             if ContextWrapper(left_netifcon.packet) != ContextWrapper(right_netifcon.packet):
     65                 removed_packet = left_netifcon.packet
     66                 added_packet = right_netifcon.packet
     67             else:
     68                 removed_packet = None
     69                 added_packet = None
     70 
     71             if removed_context or removed_packet:
     72                 self.modified_netifcons.append(modified_netifcon_record(
     73                     left_netifcon, added_context, removed_context, added_packet, removed_packet))
     74 
     75     #
     76     # Internal functions
     77     #
     78     def _reset_diff(self):
     79         """Reset diff results on policy changes."""
     80         self.log.debug("Resetting netifcon differences")
     81         self.added_netifcons = None
     82         self.removed_netifcons = None
     83         self.modified_netifcons = None
     84 
     85 
     86 class NetifconWrapper(Wrapper):
     87 
     88     """Wrap netifcon statements for diff purposes."""
     89 
     90     def __init__(self, ocon):
     91         self.origin = ocon
     92         self.netif = ocon.netif
     93         self.key = hash(ocon)
     94 
     95     def __hash__(self):
     96         return self.key
     97 
     98     def __lt__(self, other):
     99         return self.netif < other.netif
    100 
    101     def __eq__(self, other):
    102         return self.netif == other.netif
    103