diff --git a/sedta b/sedta index ad79c44..fb040fd 100755 --- a/sedta +++ b/sedta @@ -25,42 +25,42 @@ import logging import setools -def print_transition(trans, entrypoints, setexec, dyntrans, setcur): - if trans: +def print_transition(trans): + if trans.transition: print("Domain transition rule(s):") - for t in trans: + for t in trans.transition: print(t) - if setexec: + if trans.setexec: print("\nSet execution context rule(s):") - for s in setexec: + for s in trans.setexec: print(s) - for name, entry, exe, type_trans in entrypoints: - print("\nEntrypoint {0}:".format(name)) + for entrypoint in trans.entrypoints: + print("\nEntrypoint {0}:".format(entrypoint.name)) print("\tDomain entrypoint rule(s):") - for e in entry: + for e in entrypoint.entrypoint: print("\t{0}".format(e)) print("\n\tFile execute rule(s):") - for e in exe: + for e in entrypoint.execute: print("\t{0}".format(e)) - if type_trans: + if entrypoint.type_transition: print("\n\tType transition rule(s):") - for t in type_trans: + for t in entrypoint.type_transition: print("\t{0}".format(t)) print() - if dyntrans: + if trans.dyntransition: print("Dynamic transition rule(s):") - for d in dyntrans: + for d in trans.dyntransition: print(d) print("\nSet current process context rule(s):") - for s in setcur: + for s in trans.setcurrent: print(s) print() @@ -123,11 +123,10 @@ try: for i, path in enumerate(paths, start=1): print("Domain transition path {0}:".format(i)) - for step, (src, tgt, trans, entrypoints, setexec, dyntrans, setcur) in \ - enumerate(path, start=1): + for stepnum, step in enumerate(path, start=1): - print("Step {0}: {1} -> {2}\n".format(step, src, tgt)) - print_transition(trans, entrypoints, setexec, dyntrans, setcur) + print("Step {0}: {1} -> {2}\n".format(stepnum, step.source, step.target)) + print_transition(step) if args.limit_trans and i >= args.limit_trans: break @@ -138,10 +137,9 @@ try: transitions = g.transitions(args.source) i = 0 - for i, (src, tgt, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(transitions, - start=1): - print("Transition {0}: {1} -> {2}\n".format(i, src, tgt)) - print_transition(trans, entrypoints, setexec, dyntrans, setcur) + for i, step in enumerate(transitions, start=1): + print("Transition {0}: {1} -> {2}\n".format(i, step.source, step.target)) + print_transition(step) if args.limit_trans and i >= args.limit_trans: break diff --git a/setools/dta.py b/setools/dta.py index 9c7541a..d0cc573 100644 --- a/setools/dta.py +++ b/setools/dta.py @@ -18,7 +18,7 @@ # import itertools import logging -from collections import defaultdict +from collections import defaultdict, namedtuple import networkx as nx from networkx.exception import NetworkXError, NetworkXNoPath @@ -27,6 +27,21 @@ from .infoflow import EdgeAttrList __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): @@ -207,12 +222,12 @@ class DomainTransitionAnalysis(object): else: real_source, real_target = source, target - yield real_source, real_target, \ - edge.transition, \ - self.__generate_entrypoints(edge), \ - edge.setexec, \ - edge.dyntransition, \ - edge.setcurrent + yield step_output(real_source, real_target, + edge.transition, + self.__generate_entrypoints(edge), + edge.setexec, + edge.dyntransition, + edge.setcurrent) except NetworkXError: # 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. """ 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): """ @@ -284,12 +299,12 @@ class DomainTransitionAnalysis(object): else: real_source, real_target = source, target - yield real_source, real_target, \ - edge.transition, \ - self.__generate_entrypoints(edge), \ - edge.setexec, \ - edge.dyntransition, \ - edge.setcurrent + yield step_output(real_source, real_target, + edge.transition, + self.__generate_entrypoints(edge), + edge.setexec, + edge.dyntransition, + edge.setcurrent) # # Graph building functions diff --git a/tests/dta.py b/tests/dta.py index 60e5744..7c07672 100644 --- a/tests/dta.py +++ b/tests/dta.py @@ -501,34 +501,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(1, len(paths)) for path in paths: - for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, expected_path[stepnum]) - self.assertEqual(t, expected_path[stepnum+1]) + for stepnum, step in enumerate(path): + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual(expected_path[stepnum], step.source) + self.assertEqual(expected_path[stepnum+1], step.target) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_301_all_shortest_paths(self): @@ -542,34 +542,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(1, len(paths)) for path in paths: - for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, expected_path[stepnum]) - self.assertEqual(t, expected_path[stepnum+1]) + for stepnum, step in enumerate(path): + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual(expected_path[stepnum], step.source) + self.assertEqual(expected_path[stepnum+1], step.target) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_302_shortest_path(self): @@ -583,34 +583,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(1, len(paths)) for path in paths: - for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, expected_path[stepnum]) - self.assertEqual(t, expected_path[stepnum+1]) + for stepnum, step in enumerate(path): + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual(expected_path[stepnum], step.source) + self.assertEqual(expected_path[stepnum+1], step.target) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_303_transitions(self): @@ -621,33 +621,33 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): transitions = list(self.a.transitions("start")) self.assertEqual(2, len(transitions)) - for s, t, trans, entrypoints, setexec, dyntrans, setcur in transitions: - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, "start") + for step in transitions: + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual("start", step.source) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_310_all_paths_reversed(self): @@ -661,34 +661,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(1, len(paths)) for path in paths: - for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, expected_path[stepnum+1]) - self.assertEqual(t, expected_path[stepnum]) + for stepnum, step in enumerate(path): + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual(step.source, expected_path[stepnum+1]) + self.assertEqual(step.target, expected_path[stepnum]) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_311_all_shortest_paths_reversed(self): @@ -702,34 +702,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(1, len(paths)) for path in paths: - for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, expected_path[stepnum+1]) - self.assertEqual(t, expected_path[stepnum]) + for stepnum, step in enumerate(path): + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual(step.source, expected_path[stepnum+1]) + self.assertEqual(step.target, expected_path[stepnum]) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_312_shortest_path_reversed(self): @@ -743,34 +743,34 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): self.assertEqual(1, len(paths)) for path in paths: - for stepnum, (s, t, trans, entrypoints, setexec, dyntrans, setcur) in enumerate(path): - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(s, expected_path[stepnum+1]) - self.assertEqual(t, expected_path[stepnum]) + for stepnum, step in enumerate(path): + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual(expected_path[stepnum+1], step.source) + self.assertEqual(expected_path[stepnum], step.target) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_313_transitions_reversed(self): @@ -781,33 +781,33 @@ class DomainTransitionAnalysisTest(mixins.ValidateRule, unittest.TestCase): transitions = list(self.a.transitions("bothtrans200")) self.assertEqual(1, len(transitions)) - for s, t, trans, entrypoints, setexec, dyntrans, setcur in transitions: - self.assertIsInstance(s, Type) - self.assertIsInstance(t, Type) - self.assertEqual(t, "bothtrans200") + for step in transitions: + self.assertIsInstance(step.source, Type) + self.assertIsInstance(step.target, Type) + self.assertEqual("bothtrans200", step.target) - for r in trans: + for r in step.transition: self.assertIn("transition", r.perms) - for name, entry, exe, type_trans in entrypoints: - self.assertIsInstance(name, Type) + for e in step.entrypoints: + self.assertIsInstance(e.name, Type) - for r in entry: + for r in e.entrypoint: self.assertIn("entrypoint", r.perms) - for r in exe: + for r in e.execute: self.assertIn("execute", r.perms) - for r in type_trans: + for r in e.type_transition: self.assertEqual("type_transition", r.ruletype) - for r in setexec: + for r in step.setexec: self.assertIn("setexec", r.perms) - for r in dyntrans: + for r in step.dyntransition: self.assertIn("dyntransition", r.perms) - for r in setcur: + for r in step.setcurrent: self.assertIn("setcurrent", r.perms) def test_900_set_exclude_invalid_type(self):