mirror of
https://github.com/SELinuxProject/setools
synced 2025-01-28 10:32:47 +00:00
Add logging.
Not comprehensive yet. Only planning to do setools pkg (not policyrep), with the exception being the SELinuxPolicy class in policyrep. Avoids performance-critical paths. Use only info and debug so in normal cases the user only sees messages if they ask for it (e.g. -v).
This commit is contained in:
parent
97c80f22a5
commit
de716ba6a5
8
sedta
8
sedta
@ -20,6 +20,7 @@
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
import argparse
|
||||
import logging
|
||||
|
||||
import setools
|
||||
|
||||
@ -76,6 +77,8 @@ parser.add_argument("-s", "--source", help="Source type of the analysis.",
|
||||
parser.add_argument("-t", "--target", help="Target type of the analysis.", default="")
|
||||
parser.add_argument("--stats", action="store_true",
|
||||
help="Display statistics at the end of the analysis.")
|
||||
parser.add_argument("-v", "--verbose", action="store_true",
|
||||
help="Print extra informational messages")
|
||||
parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
|
||||
|
||||
alg = parser.add_argument_group("Analysis algorithm")
|
||||
@ -97,6 +100,11 @@ if not args.target and (args.shortest_path or args.all_paths):
|
||||
if args.target and not (args.shortest_path or args.all_paths):
|
||||
parser.error("An algorithm must be specified to determine a path.")
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
elif args.verbose:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
p = setools.SELinuxPolicy(args.policy)
|
||||
g = setools.dta.DomainTransitionAnalysis(p, reverse=args.reverse, exclude=args.exclude)
|
||||
|
8
seinfo
8
seinfo
@ -21,6 +21,7 @@ from __future__ import print_function
|
||||
import setools
|
||||
import argparse
|
||||
import sys
|
||||
import logging
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="SELinux policy information tool.")
|
||||
@ -30,6 +31,8 @@ parser.add_argument("-x", "--expand", action="store_true",
|
||||
help="Print additional information about the specified components.")
|
||||
parser.add_argument("--flat", help="Print without item count nor indentation.",
|
||||
dest="flat", default=False, action="store_true")
|
||||
parser.add_argument("-v", "--verbose", action="store_true",
|
||||
help="Print extra informational messages")
|
||||
parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
|
||||
|
||||
queries = parser.add_argument_group("Component Queries")
|
||||
@ -74,6 +77,11 @@ queries.add_argument("--all", help="Print all of the above.",
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
elif args.verbose:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
p = setools.SELinuxPolicy(args.policy)
|
||||
components = []
|
||||
|
@ -21,6 +21,7 @@ from __future__ import print_function
|
||||
import setools
|
||||
import argparse
|
||||
import sys
|
||||
import logging
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="SELinux policy information flow analysis tool.",
|
||||
@ -28,6 +29,8 @@ parser = argparse.ArgumentParser(
|
||||
parser.add_argument("--version", action="version", version=setools.__version__)
|
||||
parser.add_argument("--stats", action="store_true",
|
||||
help="Display statistics at the end of the analysis.")
|
||||
parser.add_argument("-v", "--verbose", action="store_true",
|
||||
help="Print extra informational messages")
|
||||
parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
|
||||
|
||||
settings = parser.add_argument_group("Analysis settings")
|
||||
@ -65,6 +68,11 @@ if args.target and not (args.shortest_path or args.all_paths):
|
||||
if args.limit_flows < 0:
|
||||
parser.error("Limit on information flows cannot be negative.")
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
elif args.verbose:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
p = setools.SELinuxPolicy(args.policy)
|
||||
g = setools.infoflow.InfoFlowAnalysis(
|
||||
|
8
sesearch
8
sesearch
@ -21,12 +21,15 @@ from __future__ import print_function
|
||||
import setools
|
||||
import argparse
|
||||
import sys
|
||||
import logging
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="SELinux policy rule search tool.",
|
||||
epilog="TE/MLS rule searches cannot be mixed with RBAC rule searches.")
|
||||
parser.add_argument("--version", action="version", version=setools.__version__)
|
||||
parser.add_argument("policy", help="Path to the SELinux policy to search.")
|
||||
parser.add_argument("-v", "--verbose", action="store_true",
|
||||
help="Print extra informational messages")
|
||||
parser.add_argument("--debug", action="store_true", dest="debug", help="Enable debugging.")
|
||||
|
||||
rtypes = parser.add_argument_group("TE Rule Types")
|
||||
@ -104,6 +107,11 @@ if not args.tertypes and not args.mlsrtypes and not args.rbacrtypes:
|
||||
if (args.tertypes or args.mlsrtypes) and args.rbacrtypes:
|
||||
parser.error("TE/MLS rule searches cannot be mixed with RBAC rule searches.")
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
elif args.verbose:
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
try:
|
||||
p = setools.SELinuxPolicy(args.policy)
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import itertools
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
|
||||
import networkx as nx
|
||||
@ -31,6 +32,8 @@ class DomainTransitionAnalysis(object):
|
||||
Parameter:
|
||||
policy The policy to analyze.
|
||||
"""
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
self.policy = policy
|
||||
self.set_exclude(exclude)
|
||||
self.set_reverse(reverse)
|
||||
@ -339,6 +342,8 @@ class DomainTransitionAnalysis(object):
|
||||
def _build_graph(self):
|
||||
self.G.clear()
|
||||
|
||||
self.log.info("Building graph...")
|
||||
|
||||
# hash tables keyed on domain type
|
||||
setexec = defaultdict(list)
|
||||
setcurrent = defaultdict(list)
|
||||
@ -509,6 +514,10 @@ class DomainTransitionAnalysis(object):
|
||||
if self.rebuildgraph:
|
||||
self._build_graph()
|
||||
|
||||
self.log.info("Building subgraph.")
|
||||
self.log.debug("Excluding {0}".format(self.exclude))
|
||||
self.log.debug("Reverse {0}".format(self.reverse))
|
||||
|
||||
# delete excluded domains from subgraph
|
||||
nodes = [n for n in self.G.nodes() if n not in self.exclude]
|
||||
# subgraph created this way to get copies of the edge
|
||||
|
@ -17,6 +17,7 @@
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import itertools
|
||||
import logging
|
||||
|
||||
import networkx as nx
|
||||
|
||||
@ -38,6 +39,7 @@ class InfoFlowAnalysis(object):
|
||||
exclude The types excluded from the information flow analysis.
|
||||
(default is none)
|
||||
"""
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
self.policy = policy
|
||||
|
||||
@ -285,6 +287,8 @@ class InfoFlowAnalysis(object):
|
||||
def _build_graph(self):
|
||||
self.G.clear()
|
||||
|
||||
self.log.info("Building graph...")
|
||||
|
||||
self.perm_map.map_policy(self.policy)
|
||||
|
||||
for r in self.policy.terules():
|
||||
@ -310,6 +314,10 @@ class InfoFlowAnalysis(object):
|
||||
if self.rebuildgraph:
|
||||
self._build_graph()
|
||||
|
||||
self.log.info("Building subgraph.")
|
||||
self.log.debug("Excluding {0}".format(self.exclude))
|
||||
self.log.debug("Min weight {0}".format(self.minweight))
|
||||
|
||||
# delete excluded types from subgraph
|
||||
nodes = [n for n in self.G.nodes() if n not in self.exclude]
|
||||
self.subG = self.G.subgraph(nodes)
|
||||
|
@ -16,6 +16,8 @@
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
|
||||
from . import policyrep
|
||||
|
||||
|
||||
@ -50,6 +52,8 @@ class PermissionMap(object):
|
||||
Parameter:
|
||||
permmapfile The path to the permission map to load.
|
||||
"""
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
self.load(permmapfile)
|
||||
|
||||
def load(self, permmapfile):
|
||||
@ -57,6 +61,7 @@ class PermissionMap(object):
|
||||
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
|
||||
@ -236,6 +241,7 @@ class PermissionMap(object):
|
||||
class_name = str(c)
|
||||
|
||||
if class_name not in self.permmap:
|
||||
self.log.info("Adding unmapped class {0}".format(class_name))
|
||||
self.permmap[class_name] = dict()
|
||||
|
||||
perms = c.perms
|
||||
@ -247,6 +253,8 @@ class PermissionMap(object):
|
||||
|
||||
for perm_name in perms:
|
||||
if perm_name not in self.permmap[class_name]:
|
||||
self.log.info("Adding unmapped permission {0} in {1}".format(perm_name,
|
||||
class_name))
|
||||
self.permmap[class_name][perm_name] = {'direction': 'u',
|
||||
'weight': 1,
|
||||
'enabled': True}
|
||||
|
@ -20,6 +20,7 @@
|
||||
# The idea is that this is module provides convenient
|
||||
# abstractions and methods for accessing the policy
|
||||
# structures.
|
||||
import logging
|
||||
from itertools import chain
|
||||
|
||||
from . import qpol
|
||||
@ -72,6 +73,9 @@ class SELinuxPolicy(object):
|
||||
policyfile Path to a policy to open.
|
||||
"""
|
||||
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
self.log.info("Opening SELinux policy \"{0}\"".format(policyfile))
|
||||
|
||||
try:
|
||||
self.policy = qpol.qpol_policy_t(policyfile, 0)
|
||||
except SyntaxError as err:
|
||||
|
@ -16,6 +16,7 @@
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
import re
|
||||
|
||||
from .policyrep.rule import RuleUseError, RuleNotConditional
|
||||
@ -63,6 +64,7 @@ class TERuleQuery(mixins.MatchPermission, rulequery.RuleQuery):
|
||||
default_regex If true, regular expression matching will be
|
||||
used on the default type.
|
||||
"""
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
self.policy = policy
|
||||
|
||||
@ -76,6 +78,17 @@ class TERuleQuery(mixins.MatchPermission, rulequery.RuleQuery):
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching TE rules."""
|
||||
self.log.info("Generating results.")
|
||||
self.log.debug("Ruletypes: {0.ruletype}".format(self))
|
||||
self.log.debug("Source: {0.source}, indirect: {0.source_indirect}, "
|
||||
"regex: {0.source_regex}".format(self))
|
||||
self.log.debug("Target: {0.target}, indirect: {0.target_indirect}, "
|
||||
"regex: {0.target_regex}".format(self))
|
||||
self.log.debug("Class: {0.tclass}, regex: {0.tclass_regex}".format(self))
|
||||
self.log.debug("Perms: {0.perms}, eq: {0.perms_equal}".format(self))
|
||||
self.log.debug("Default: {0.default}, regex: {0.default_regex}".format(self))
|
||||
self.log.debug("Boolean: {0.boolean}, eq: {0.boolean_equal}, "
|
||||
"regex: {0.boolean_regex}".format(self))
|
||||
|
||||
for r in self.policy.terules():
|
||||
#
|
||||
|
@ -16,6 +16,7 @@
|
||||
# License along with SETools. If not, see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
import logging
|
||||
import re
|
||||
|
||||
from . import compquery
|
||||
@ -62,6 +63,7 @@ class UserQuery(compquery.ComponentQuery):
|
||||
range_proper If true, use proper superset/subset operations.
|
||||
No effect if not using set operations.
|
||||
"""
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
|
||||
self.policy = policy
|
||||
self.set_name(name, regex=name_regex)
|
||||
@ -72,6 +74,13 @@ class UserQuery(compquery.ComponentQuery):
|
||||
|
||||
def results(self):
|
||||
"""Generator which yields all matching users."""
|
||||
self.log.info("Generating results.")
|
||||
self.log.debug("Name: {0.name}, regex: {0.name_regex}".format(self))
|
||||
self.log.debug("Roles: {0.roles}, regex: {0.roles_regex}, eq: {0.roles_equal}".format(self))
|
||||
self.log.debug("Level: {0.level}, dom: {0.level_dom}, domby: {0.level_domby}, "
|
||||
"incomp: {0.level_incomp}".format(self))
|
||||
self.log.debug("Range: {0.range_}, subset: {0.range_subset}, overlap: {0.range_overlap}, "
|
||||
"superset: {0.range_superset}, proper: {0.range_proper}".format(self))
|
||||
|
||||
for u in self.policy.users():
|
||||
if self.name and not self._match_regex(
|
||||
|
Loading…
Reference in New Issue
Block a user