seinfoflow/sedta: Add graphical output files.
Add the -o option to output graphical results for domain transition analysis and information flow analysis. Signed-off-by: Chris PeBenito <pebenito@ieee.org>
This commit is contained in:
parent
9a5ab901b1
commit
ecdc7f460c
|
@ -54,6 +54,7 @@ jobs:
|
|||
gettext \
|
||||
libaudit-dev \
|
||||
libbz2-dev \
|
||||
libgraphviz-dev \
|
||||
libpcre3-dev \
|
||||
xvfb \
|
||||
x11-xserver-utils
|
||||
|
|
|
@ -15,6 +15,7 @@ To run SETools command line tools, the following packages are required:
|
|||
|
||||
* Python 3.10+
|
||||
* NetworkX 2.6+
|
||||
* pygraphviz
|
||||
* setuptools
|
||||
* libselinux
|
||||
* libsepol 3.2+
|
||||
|
|
|
@ -45,6 +45,8 @@ Perform a reverse domain transition analysis. The domain transitions will be an
|
|||
the parent domains, instead of finding the child domains.
|
||||
.IP "-l LIMIT_TRANS"
|
||||
Specify the maximum number of domain transitions to output. The default is unlimited.
|
||||
.IP "-o OUTPUT_PATH"
|
||||
Generate a graphical representation of the analysis in PNG format at the specified path.
|
||||
.IP EXCLUDE
|
||||
A space-separated list of types to exclude from the analysis.
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ the policy, a limit of 5 or more may be extremely expensive.
|
|||
Specify the minimum permission weight to consider for the analysis (1-10). The default is 3.
|
||||
.IP "-l LIMIT_FLOWS"
|
||||
Specify the maximum number of information flows to output. The default is unlimited.
|
||||
.IP "-o OUTPUT_PATH"
|
||||
Generate a graphical representation of the analysis in PNG format at the specified path.
|
||||
.IP EXCLUDE
|
||||
A space-separated list of types to exclude from the analysis.
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ pretty = true
|
|||
|
||||
[[tool.mypy.overrides]]
|
||||
module = ['networkx.*',
|
||||
'pygraphviz.*',
|
||||
'pytestqt.*']
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
|
48
sedta
48
sedta
|
@ -10,6 +10,7 @@ import logging
|
|||
import signal
|
||||
import warnings
|
||||
|
||||
import networkx as nx
|
||||
import setools
|
||||
|
||||
|
||||
|
@ -40,6 +41,7 @@ opts.add_argument("-r", "--reverse", action="store_true", default=False,
|
|||
help="Perform a reverse DTA.")
|
||||
opts.add_argument("-l", "--limit_trans", default=0, type=int,
|
||||
help="Limit to the specified number of transitions. Default is unlimited.")
|
||||
opts.add_argument("-o", "--output_file", help="Output file for graphical results, PNG format.")
|
||||
opts.add_argument("exclude", help="List of excluded types in the analysis.", nargs="*")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
@ -82,21 +84,25 @@ try:
|
|||
g.mode = setools.DomainTransitionAnalysis.Mode.AllPaths
|
||||
g.depth_limit = args.all_paths
|
||||
|
||||
for pathnum, path in enumerate(g.results(), start=1): # type: ignore
|
||||
print(f"Domain transition path {pathnum}:")
|
||||
if args.output_file:
|
||||
pgv = nx.nx_agraph.to_agraph(g.graphical_results())
|
||||
pgv.draw(path=args.output_file, prog="dot", format="png")
|
||||
else:
|
||||
for pathnum, path in enumerate(g.results(), start=1): # type: ignore
|
||||
print(f"Domain transition path {pathnum}:")
|
||||
|
||||
for stepnum, step in enumerate(path, start=1):
|
||||
if args.full:
|
||||
print(f"Step {stepnum}: {step:full}\n")
|
||||
else:
|
||||
print(f"Step {stepnum}: {step}")
|
||||
for stepnum, step in enumerate(path, start=1):
|
||||
if args.full:
|
||||
print(f"Step {stepnum}: {step:full}\n")
|
||||
else:
|
||||
print(f"Step {stepnum}: {step}")
|
||||
|
||||
if args.limit_trans and pathnum >= args.limit_trans:
|
||||
break
|
||||
if args.limit_trans and pathnum >= args.limit_trans:
|
||||
break
|
||||
|
||||
print()
|
||||
print()
|
||||
|
||||
print(f"\n{pathnum} domain transition path(s) found.")
|
||||
print(f"\n{pathnum} domain transition path(s) found.")
|
||||
|
||||
else: # single transition
|
||||
if args.reverse:
|
||||
|
@ -106,16 +112,20 @@ try:
|
|||
g.mode = setools.DomainTransitionAnalysis.Mode.TransitionsOut
|
||||
g.source = args.source
|
||||
|
||||
for pathnum, step in enumerate(g.results(), start=1): # type: ignore
|
||||
if args.full:
|
||||
print(f"Transition {pathnum}: {step:full}\n")
|
||||
else:
|
||||
print(f"Transition {pathnum}: {step}")
|
||||
if args.output_file:
|
||||
pgv = nx.nx_agraph.to_agraph(g.graphical_results())
|
||||
pgv.draw(path=args.output_file, prog="dot", format="png")
|
||||
else:
|
||||
for pathnum, step in enumerate(g.results(), start=1): # type: ignore
|
||||
if args.full:
|
||||
print(f"Transition {pathnum}: {step:full}\n")
|
||||
else:
|
||||
print(f"Transition {pathnum}: {step}")
|
||||
|
||||
if args.limit_trans and pathnum >= args.limit_trans:
|
||||
break
|
||||
if args.limit_trans and pathnum >= args.limit_trans:
|
||||
break
|
||||
|
||||
print(f"\n{pathnum} domain transition(s) found.")
|
||||
print(f"\n{pathnum} domain transition(s) found.")
|
||||
|
||||
if args.stats:
|
||||
print("\nGraph statistics:")
|
||||
|
|
49
seinfoflow
49
seinfoflow
|
@ -4,7 +4,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
|
||||
import setools
|
||||
import argparse
|
||||
import sys
|
||||
import logging
|
||||
|
@ -12,6 +11,9 @@ import signal
|
|||
import warnings
|
||||
from typing import Dict, Optional
|
||||
|
||||
import networkx as nx
|
||||
import setools
|
||||
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
|
@ -53,6 +55,7 @@ opts.add_argument("-l", "--limit_flows", default=0, type=int,
|
|||
opts.add_argument("-b", "--booleans", default=None,
|
||||
help="Specify the boolean values to use."
|
||||
" Options are default, or \"foo:true,bar:false...\"")
|
||||
opts.add_argument("-o", "--output_file", help="Output file for graphical results, PNG format.")
|
||||
opts.add_argument("exclude", nargs="*",
|
||||
help="List of excluded types in the analysis.")
|
||||
|
||||
|
@ -117,18 +120,22 @@ try:
|
|||
g.mode = setools.InfoFlowAnalysis.Mode.AllPaths
|
||||
g.depth_limit = args.all_paths
|
||||
|
||||
for flownum, flow in enumerate(g.results(), start=1): # type: ignore
|
||||
print(f"Flow {flownum}:")
|
||||
for stepnum, step in enumerate(flow, start=1):
|
||||
if args.full:
|
||||
print(f" Step {stepnum}: {step:full}\n")
|
||||
else:
|
||||
print(f" Step {stepnum}: {step}")
|
||||
if args.output_file:
|
||||
pgv = nx.nx_agraph.to_agraph(g.graphical_results())
|
||||
pgv.draw(path=args.output_file, prog="dot", format="png")
|
||||
else:
|
||||
for flownum, flow in enumerate(g.results(), start=1): # type: ignore
|
||||
print(f"Flow {flownum}:")
|
||||
for stepnum, step in enumerate(flow, start=1):
|
||||
if args.full:
|
||||
print(f" Step {stepnum}: {step:full}\n")
|
||||
else:
|
||||
print(f" Step {stepnum}: {step}")
|
||||
|
||||
if args.limit_flows and flownum >= args.limit_flows:
|
||||
break
|
||||
if args.limit_flows and flownum >= args.limit_flows:
|
||||
break
|
||||
|
||||
print()
|
||||
print(f"\n{flownum} information flow(s) found.")
|
||||
|
||||
else: # single step, direct info flow
|
||||
if args.reverse:
|
||||
|
@ -138,16 +145,20 @@ try:
|
|||
g.mode = setools.InfoFlowAnalysis.Mode.FlowsOut
|
||||
g.source = args.source
|
||||
|
||||
for flownum, step in enumerate(g.results(), start=1): # type: ignore
|
||||
if args.full:
|
||||
print(f"Flow {flownum}: {step:full}\n")
|
||||
else:
|
||||
print(f"Flow {flownum}: {step}")
|
||||
if args.output_file:
|
||||
pgv = nx.nx_agraph.to_agraph(g.graphical_results())
|
||||
pgv.draw(path=args.output_file, prog="dot", format="png")
|
||||
else:
|
||||
for flownum, step in enumerate(g.results(), start=1): # type: ignore
|
||||
if args.full:
|
||||
print(f"Flow {flownum}: {step:full}\n")
|
||||
else:
|
||||
print(f"Flow {flownum}: {step}")
|
||||
|
||||
if args.limit_flows and flownum >= args.limit_flows:
|
||||
break
|
||||
if args.limit_flows and flownum >= args.limit_flows:
|
||||
break
|
||||
|
||||
print(f"\n{flownum} information flow(s) found.")
|
||||
print(f"\n{flownum} information flow(s) found.")
|
||||
|
||||
if args.stats:
|
||||
print("\nGraph statistics:")
|
||||
|
|
2
setup.py
2
setup.py
|
@ -99,7 +99,7 @@ setup(name='setools',
|
|||
setup_requires=['setuptools', 'Cython>=0.29.14'],
|
||||
install_requires=['setuptools'],
|
||||
extras_require={
|
||||
"analysis": "networkx>=2.6",
|
||||
"analysis": ["networkx>=2.6", "pygraphviz"],
|
||||
"test": "tox"
|
||||
}
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue