DomainTransitionAnalysis: convert to named tuples for output

Makes output compact and easier to use for callers. Also it is backwards
compatible.
This commit is contained in:
Chris PeBenito 2015-04-26 10:19:42 -04:00
parent 43f7c19114
commit d23bdd4895
3 changed files with 159 additions and 146 deletions

42
sedta
View File

@ -25,42 +25,42 @@ import logging
import setools import setools
def print_transition(trans, entrypoints, setexec, dyntrans, setcur): def print_transition(trans):
if trans: if trans.transition:
print("Domain transition rule(s):") print("Domain transition rule(s):")
for t in trans: for t in trans.transition:
print(t) print(t)
if setexec: if trans.setexec:
print("\nSet execution context rule(s):") print("\nSet execution context rule(s):")
for s in setexec: for s in trans.setexec:
print(s) print(s)
for name, entry, exe, type_trans in entrypoints: for entrypoint in trans.entrypoints:
print("\nEntrypoint {0}:".format(name)) print("\nEntrypoint {0}:".format(entrypoint.name))
print("\tDomain entrypoint rule(s):") print("\tDomain entrypoint rule(s):")
for e in entry: for e in entrypoint.entrypoint:
print("\t{0}".format(e)) print("\t{0}".format(e))
print("\n\tFile execute rule(s):") print("\n\tFile execute rule(s):")
for e in exe: for e in entrypoint.execute:
print("\t{0}".format(e)) print("\t{0}".format(e))
if type_trans: if entrypoint.type_transition:
print("\n\tType transition rule(s):") print("\n\tType transition rule(s):")
for t in type_trans: for t in entrypoint.type_transition:
print("\t{0}".format(t)) print("\t{0}".format(t))
print() print()
if dyntrans: if trans.dyntransition:
print("Dynamic transition rule(s):") print("Dynamic transition rule(s):")
for d in dyntrans: for d in trans.dyntransition:
print(d) print(d)
print("\nSet current process context rule(s):") print("\nSet current process context rule(s):")
for s in setcur: for s in trans.setcurrent:
print(s) print(s)
print() print()
@ -123,11 +123,10 @@ try:
for i, path in enumerate(paths, start=1): for i, path in enumerate(paths, start=1):
print("Domain transition path {0}:".format(i)) print("Domain transition path {0}:".format(i))
for step, (src, tgt, trans, entrypoints, setexec, dyntrans, setcur) in \ for stepnum, step in enumerate(path, start=1):
enumerate(path, start=1):
print("Step {0}: {1} -> {2}\n".format(step, src, tgt)) print("Step {0}: {1} -> {2}\n".format(stepnum, step.source, step.target))
print_transition(trans, entrypoints, setexec, dyntrans, setcur) print_transition(step)
if args.limit_trans and i >= args.limit_trans: if args.limit_trans and i >= args.limit_trans:
break break
@ -138,10 +137,9 @@ try:
transitions = g.transitions(args.source) transitions = g.transitions(args.source)
i = 0 i = 0
for i, (src, tgt, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(transitions, for i, step in enumerate(transitions, start=1):
start=1): print("Transition {0}: {1} -> {2}\n".format(i, step.source, step.target))
print("Transition {0}: {1} -> {2}\n".format(i, src, tgt)) print_transition(step)
print_transition(trans, entrypoints, setexec, dyntrans, setcur)
if args.limit_trans and i >= args.limit_trans: if args.limit_trans and i >= args.limit_trans:
break break

View File

@ -18,7 +18,7 @@
# #
import itertools import itertools
import logging import logging
from collections import defaultdict from collections import defaultdict, namedtuple
import networkx as nx import networkx as nx
from networkx.exception import NetworkXError, NetworkXNoPath from networkx.exception import NetworkXError, NetworkXNoPath
@ -27,6 +27,21 @@ from .infoflow import EdgeAttrList
__all__ = ['DomainTransitionAnalysis'] __all__ = ['DomainTransitionAnalysis']
# Return values for the analysis
# are in the following tuple formats:
step_output = namedtuple("step", ["source",
"target",
"transition",
"entrypoints",
"setexec",
"dyntransition",
"setcurrent"])
entrypoint_output = namedtuple("entrypoints", ["name",
"entrypoint",
"execute",
"type_transition"])
class DomainTransitionAnalysis(object): class DomainTransitionAnalysis(object):
@ -207,12 +222,12 @@ class DomainTransitionAnalysis(object):
else: else:
real_source, real_target = source, target real_source, real_target = source, target
yield real_source, real_target, \ yield step_output(real_source, real_target,
edge.transition, \ edge.transition,
self.__generate_entrypoints(edge), \ self.__generate_entrypoints(edge),
edge.setexec, \ edge.setexec,
edge.dyntransition, \ edge.dyntransition,
edge.setcurrent edge.setcurrent)
except NetworkXError: except NetworkXError:
# NetworkXError: the type is valid but not in graph, e.g. excluded # NetworkXError: the type is valid but not in graph, e.g. excluded
@ -249,7 +264,7 @@ class DomainTransitionAnalysis(object):
trans The list of type_transition rules. trans The list of type_transition rules.
""" """
for e in edge.entrypoint: for e in edge.entrypoint:
yield e, edge.entrypoint[e], edge.execute[e], edge.type_transition[e] yield entrypoint_output(e, edge.entrypoint[e], edge.execute[e], edge.type_transition[e])
def __generate_steps(self, path): def __generate_steps(self, path):
""" """
@ -284,12 +299,12 @@ class DomainTransitionAnalysis(object):
else: else:
real_source, real_target = source, target real_source, real_target = source, target
yield real_source, real_target, \ yield step_output(real_source, real_target,
edge.transition, \ edge.transition,
self.__generate_entrypoints(edge), \ self.__generate_entrypoints(edge),
edge.setexec, \ edge.setexec,
edge.dyntransition, \ edge.dyntransition,
edge.setcurrent edge.setcurrent)
# #
# Graph building functions # Graph building functions

View File

@ -501,34 +501,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(1, len(paths)) self.assertEqual(1, len(paths))
for path in paths: for path in paths:
for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): for stepnum, step in enumerate(path):
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, expected_path[stepnum]) self.assertEqual(expected_path[stepnum], step.source)
self.assertEqual(t, expected_path[stepnum+1]) self.assertEqual(expected_path[stepnum+1], step.target)
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_301_all_shortest_paths(self): def test_301_all_shortest_paths(self):
@ -542,34 +542,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(1, len(paths)) self.assertEqual(1, len(paths))
for path in paths: for path in paths:
for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): for stepnum, step in enumerate(path):
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, expected_path[stepnum]) self.assertEqual(expected_path[stepnum], step.source)
self.assertEqual(t, expected_path[stepnum+1]) self.assertEqual(expected_path[stepnum+1], step.target)
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_302_shortest_path(self): def test_302_shortest_path(self):
@ -583,34 +583,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(1, len(paths)) self.assertEqual(1, len(paths))
for path in paths: for path in paths:
for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): for stepnum, step in enumerate(path):
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, expected_path[stepnum]) self.assertEqual(expected_path[stepnum], step.source)
self.assertEqual(t, expected_path[stepnum+1]) self.assertEqual(expected_path[stepnum+1], step.target)
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_303_transitions(self): def test_303_transitions(self):
@ -621,33 +621,33 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
transitions = list(self.a.transitions("start")) transitions = list(self.a.transitions("start"))
self.assertEqual(2, len(transitions)) self.assertEqual(2, len(transitions))
for s, t, trans, entrypoints, setexec, dyntrans, setcur in transitions: for step in transitions:
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, "start") self.assertEqual("start", step.source)
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_310_all_paths_reversed(self): def test_310_all_paths_reversed(self):
@ -661,34 +661,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(1, len(paths)) self.assertEqual(1, len(paths))
for path in paths: for path in paths:
for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): for stepnum, step in enumerate(path):
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, expected_path[stepnum+1]) self.assertEqual(step.source, expected_path[stepnum+1])
self.assertEqual(t, expected_path[stepnum]) self.assertEqual(step.target, expected_path[stepnum])
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_311_all_shortest_paths_reversed(self): def test_311_all_shortest_paths_reversed(self):
@ -702,34 +702,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(1, len(paths)) self.assertEqual(1, len(paths))
for path in paths: for path in paths:
for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): for stepnum, step in enumerate(path):
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, expected_path[stepnum+1]) self.assertEqual(step.source, expected_path[stepnum+1])
self.assertEqual(t, expected_path[stepnum]) self.assertEqual(step.target, expected_path[stepnum])
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_312_shortest_path_reversed(self): def test_312_shortest_path_reversed(self):
@ -743,34 +743,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
self.assertEqual(1, len(paths)) self.assertEqual(1, len(paths))
for path in paths: for path in paths:
for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): for stepnum, step in enumerate(path):
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(s, expected_path[stepnum+1]) self.assertEqual(expected_path[stepnum+1], step.source)
self.assertEqual(t, expected_path[stepnum]) self.assertEqual(expected_path[stepnum], step.target)
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_313_transitions_reversed(self): def test_313_transitions_reversed(self):
@ -781,33 +781,33 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase):
transitions = list(self.a.transitions("bothtrans200")) transitions = list(self.a.transitions("bothtrans200"))
self.assertEqual(1, len(transitions)) self.assertEqual(1, len(transitions))
for s, t, trans, entrypoints, setexec, dyntrans, setcur in transitions: for step in transitions:
self.assertIsInstance(s, Type) self.assertIsInstance(step.source, Type)
self.assertIsInstance(t, Type) self.assertIsInstance(step.target, Type)
self.assertEqual(t, "bothtrans200") self.assertEqual("bothtrans200", step.target)
for r in trans: for r in step.transition:
self.assertIn("transition", r.perms) self.assertIn("transition", r.perms)
for name, entry, exe, type_trans in entrypoints: for e in step.entrypoints:
self.assertIsInstance(name, Type) self.assertIsInstance(e.name, Type)
for r in entry: for r in e.entrypoint:
self.assertIn("entrypoint", r.perms) self.assertIn("entrypoint", r.perms)
for r in exe: for r in e.execute:
self.assertIn("execute", r.perms) self.assertIn("execute", r.perms)
for r in type_trans: for r in e.type_transition:
self.assertEqual("type_transition", r.ruletype) self.assertEqual("type_transition", r.ruletype)
for r in setexec: for r in step.setexec:
self.assertIn("setexec", r.perms) self.assertIn("setexec", r.perms)
for r in dyntrans: for r in step.dyntransition:
self.assertIn("dyntransition", r.perms) self.assertIn("dyntransition", r.perms)
for r in setcur: for r in step.setcurrent:
self.assertIn("setcurrent", r.perms) self.assertIn("setcurrent", r.perms)
def test_900_set_exclude_invalid_type(self): def test_900_set_exclude_invalid_type(self):