mirror of
https://github.com/SELinuxProject/refpolicy
synced 2025-01-03 05:22:39 +00:00
Add tool for validating contexts in appconfig files.
Initial implementation only covers files with full contexts. Signed-off-by: Chris PeBenito <pebenito@ieee.org>
This commit is contained in:
parent
09bdfcda4f
commit
0fd1e06fc7
11
.github/workflows/build-userspace.yml
vendored
11
.github/workflows/build-userspace.yml
vendored
@ -11,6 +11,10 @@ on:
|
||||
description: "Userspace version (a git commit ID, tag, or branch)"
|
||||
required: false
|
||||
type: string
|
||||
python-version:
|
||||
description: "Python version to use"
|
||||
required: true
|
||||
type: string
|
||||
outputs:
|
||||
source-id:
|
||||
description: "Userspace source artifact ID"
|
||||
@ -34,6 +38,11 @@ jobs:
|
||||
ref: "${{ inputs.version }}"
|
||||
path: "${{ env.SELINUX_SRC }}"
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "${{ inputs.python-version }}"
|
||||
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
@ -62,7 +71,7 @@ jobs:
|
||||
# Drop sandbox to break libcap-ng dependence
|
||||
sed -i -e 's/ sandbox//' policycoreutils/Makefile
|
||||
# Compile and install SELinux toolchain
|
||||
make OPT_SUBDIRS=semodule-utils install
|
||||
make OPT_SUBDIRS=semodule-utils install install-pywrap
|
||||
# set output directory on successful/pre-existing compile
|
||||
echo "DESTDIR=\"${DESTDIR}\"" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
|
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@ -24,6 +24,7 @@ jobs:
|
||||
needs: lint_branch_policy
|
||||
with:
|
||||
version: "3.2"
|
||||
python-version: "3.10"
|
||||
|
||||
build_setools:
|
||||
uses: ./.github/workflows/build-setools.yml
|
||||
|
51
Makefile
51
Makefile
@ -54,28 +54,33 @@ python_path := $(TEST_TOOLCHAIN)$(python_path_plat):$(TEST_TOOLCHAIN)$(python_pa
|
||||
else
|
||||
python_path := $(TEST_TOOLCHAIN)$(python_path_plat):$(TEST_TOOLCHAIN)$(python_path_pure)
|
||||
endif
|
||||
tc_usrbindir := env LD_LIBRARY_PATH="$(TEST_TOOLCHAIN)/lib:$(TEST_TOOLCHAIN)/usr/lib" PYTHONPATH="$(python_path)" $(TEST_TOOLCHAIN)$(BINDIR)
|
||||
tc_usrsbindir := env LD_LIBRARY_PATH="$(TEST_TOOLCHAIN)/lib:$(TEST_TOOLCHAIN)/usr/lib" PYTHONPATH="$(python_path)" $(TEST_TOOLCHAIN)$(SBINDIR)
|
||||
tc_sbindir := env LD_LIBRARY_PATH="$(TEST_TOOLCHAIN)/lib:$(TEST_TOOLCHAIN)/usr/lib" PYTHONPATH="$(python_path)" $(TEST_TOOLCHAIN)/sbin
|
||||
tc_env := env LD_LIBRARY_PATH="$(TEST_TOOLCHAIN)/lib:$(TEST_TOOLCHAIN)/usr/lib" PYTHONPATH="$(python_path)"
|
||||
tc_usrbindir := $(TEST_TOOLCHAIN)$(BINDIR)
|
||||
tc_usrsbindir := $(TEST_TOOLCHAIN)$(SBINDIR)
|
||||
tc_sbindir := $(TEST_TOOLCHAIN)/sbin
|
||||
else
|
||||
tc_env :=
|
||||
tc_usrbindir := $(BINDIR)
|
||||
tc_usrsbindir := $(SBINDIR)
|
||||
tc_sbindir := /sbin
|
||||
endif
|
||||
CHECKPOLICY ?= $(tc_usrbindir)/checkpolicy
|
||||
CHECKMODULE ?= $(tc_usrbindir)/checkmodule
|
||||
SEMODULE ?= $(tc_usrsbindir)/semodule
|
||||
SEMOD_PKG ?= $(tc_usrbindir)/semodule_package
|
||||
SEMOD_LNK ?= $(tc_usrbindir)/semodule_link
|
||||
SEMOD_EXP ?= $(tc_usrbindir)/semodule_expand
|
||||
LOADPOLICY ?= $(tc_usrsbindir)/load_policy
|
||||
CHECKPOLICY ?= $(tc_env) $(tc_usrbindir)/checkpolicy
|
||||
CHECKMODULE ?= $(tc_env) $(tc_usrbindir)/checkmodule
|
||||
SEMODULE ?= $(tc_env) $(tc_usrsbindir)/semodule
|
||||
SEMOD_PKG ?= $(tc_env) $(tc_usrbindir)/semodule_package
|
||||
SEMOD_LNK ?= $(tc_env) $(tc_usrbindir)/semodule_link
|
||||
SEMOD_EXP ?= $(tc_env) $(tc_usrbindir)/semodule_expand
|
||||
LOADPOLICY ?= $(tc_env) $(tc_usrsbindir)/load_policy
|
||||
# chkcon is not directly run by makefiles; the path is used by the validate-appconfig
|
||||
# tool. The tc_env is added below in the validateappconfig var
|
||||
CHKCON ?= $(tc_usrbindir)/chkcon
|
||||
ifdef TEST_TOOLCHAIN
|
||||
SEPOLGEN_IFGEN ?= $(tc_usrbindir)/sepolgen-ifgen --attr-helper $(TEST_TOOLCHAIN)$(BINDIR)/sepolgen-ifgen-attr-helper
|
||||
SEPOLGEN_IFGEN ?= $(tc_env) $(tc_usrbindir)/sepolgen-ifgen --attr-helper $(TEST_TOOLCHAIN)$(BINDIR)/sepolgen-ifgen-attr-helper
|
||||
else
|
||||
SEPOLGEN_IFGEN ?= $(tc_usrbindir)/sepolgen-ifgen
|
||||
SEPOLGEN_IFGEN ?= $(tc_env) $(tc_usrbindir)/sepolgen-ifgen
|
||||
endif
|
||||
SETFILES ?= $(tc_sbindir)/setfiles
|
||||
SEFCONTEXT_COMPILE ?= $(tc_usrsbindir)/sefcontext_compile
|
||||
SETFILES ?= $(tc_env) $(tc_sbindir)/setfiles
|
||||
SEFCONTEXT_COMPILE ?= $(tc_env) $(tc_usrsbindir)/sefcontext_compile
|
||||
XMLLINT ?= $(BINDIR)/xmllint
|
||||
SECHECK ?= $(BINDIR)/sechecker
|
||||
|
||||
@ -123,6 +128,7 @@ m4terminate := $(support)/fatal_error.m4
|
||||
# so policycoreutils updates are not required (RHEL4)
|
||||
genhomedircon := $(PYTHON) $(support)/genhomedircon.py
|
||||
gentemplates := $(support)/gentemplates.sh
|
||||
validateappconfig := $(tc_env) $(PYTHON) $(support)/validate-appconfig.py -c $(CHKCON)
|
||||
|
||||
# documentation paths
|
||||
docs := doc
|
||||
@ -338,6 +344,23 @@ off_mods += $(filter-out $(cmdline_off) $(cmdline_base) $(cmdline_mods), $(mod_c
|
||||
# add modules not in modules.conf to the off list
|
||||
off_mods += $(filter-out $(base_mods) $(mod_mods) $(off_mods),$(notdir $(detected_mods)))
|
||||
|
||||
# enable appconfig validation based on enabled modules
|
||||
ifneq "$(filter container.te,$(base_mods) $(mod_mods))" ""
|
||||
validateappconfig += -l
|
||||
endif
|
||||
|
||||
ifneq "$(filter postgresql.te,$(base_mods) $(mod_mods))" ""
|
||||
validateappconfig += -s
|
||||
endif
|
||||
|
||||
ifneq "$(filter virt.te,$(base_mods) $(mod_mods))" ""
|
||||
validateappconfig += -v
|
||||
endif
|
||||
|
||||
ifneq "$(filter xserver.te,$(base_mods) $(mod_mods))" ""
|
||||
validateappconfig += -x
|
||||
endif
|
||||
|
||||
# filesystems to be used in labeling targets
|
||||
filesystems = $(shell mount | grep -v "context=" | $(GREP) -v '\((|.*,)bind(,.*|)\)' | $(AWK) '/(ext[234]|btrfs| xfs| jfs).*rw/{print $$3}';)
|
||||
fs_names := "btrfs ext2 ext3 ext4 xfs jfs"
|
||||
|
@ -216,14 +216,16 @@ $(builtappconf)/customizable_types: $(base_conf)
|
||||
|
||||
########################################
|
||||
#
|
||||
# Validate linking and expanding of modules
|
||||
# Validate linking and expanding of modules, file_contexts, and appconfig
|
||||
#
|
||||
validate: $(base_pkg) $(mod_pkgs) $(tmpdir)/all_mods.fc
|
||||
@echo "Validating policy linking."
|
||||
validate: $(base_pkg) $(mod_pkgs) $(tmpdir)/all_mods.fc $(builtappfiles)
|
||||
@echo "Validating $(NAME) linking."
|
||||
$(verbose) $(SEMOD_LNK) -o $(tmpdir)/test.lnk $(base_pkg) $(mod_pkgs)
|
||||
$(verbose) $(SEMOD_EXP) $(tmpdir)/test.lnk $(tmpdir)/policy.bin
|
||||
@echo "Validating policy file contexts."
|
||||
@echo "Validating $(NAME) file contexts."
|
||||
$(verbose) $(SETFILES) -q -c $(tmpdir)/policy.bin $(tmpdir)/all_mods.fc
|
||||
@echo "Validating $(NAME) appconfig."
|
||||
$(verbose) $(validateappconfig) $(builtappconf) $(tmpdir)/policy.bin
|
||||
@echo "Success."
|
||||
|
||||
########################################
|
||||
|
@ -241,11 +241,13 @@ $(fcpath): $(fc) $(loadpath) $(userpath)/system.users
|
||||
|
||||
########################################
|
||||
#
|
||||
# Validate file contexts
|
||||
# Validate file contexts and appconfig
|
||||
#
|
||||
validate: $(fc) $(polver)
|
||||
validate: $(fc) $(polver) $(builtappfiles)
|
||||
@echo "Validating $(NAME) file_contexts."
|
||||
$(verbose) $(SETFILES) -q -c $(polver) $(fc)
|
||||
@echo "Validating $(NAME) appconfig."
|
||||
$(verbose) $(validateappconfig) $(builtappconf) $(polver)
|
||||
@echo "Success."
|
||||
|
||||
########################################
|
||||
|
331
support/validate-appconfig.py
Executable file
331
support/validate-appconfig.py
Executable file
@ -0,0 +1,331 @@
|
||||
#!/usr/bin/python3
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
"""Validate refpolicy userpace configuration files (appconfig) have valid contexts."""
|
||||
|
||||
import argparse
|
||||
from contextlib import suppress
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import typing
|
||||
import warnings
|
||||
from xml.dom.minidom import Node
|
||||
|
||||
try:
|
||||
from defusedxml import minidom
|
||||
except ImportError:
|
||||
from xml.dom import minidom
|
||||
|
||||
import selinux as libselinux
|
||||
|
||||
DBUS_CONTEXTS: typing.Final[str] = "dbus_contexts"
|
||||
MEDIA_CONTEXTS: typing.Final[str] = "media"
|
||||
SINGLE_LINE_CONTEXTS_FILES: typing.Final[tuple[str, ...]] = ("initrc_context",
|
||||
"removable_context",
|
||||
"userhelper_context")
|
||||
LXC_CONTEXTS: typing.Final[str] = "lxc_contexts"
|
||||
SEPGSQL_CONTEXTS: typing.Final[str] = "sepgsql_contexts"
|
||||
VIRT_CONTEXTS_FILES: typing.Final[tuple[str, ...]] = ("virtual_domain_context",
|
||||
"virtual_image_context")
|
||||
XSERVER_CONTEXTS: typing.Final[str] = "x_contexts"
|
||||
|
||||
CHKCON_PATHS: typing.Final[tuple[Path, ...]] = (Path("/usr/local/bin"),
|
||||
Path("/usr/local/sbin"),
|
||||
Path("/usr/bin"),
|
||||
Path("/bin"),
|
||||
Path("/usr/sbin"),
|
||||
Path("/sbin"))
|
||||
|
||||
|
||||
class ContextValidator:
|
||||
|
||||
"""Validate contexts using security_check_context or chkcon"""
|
||||
|
||||
def __init__(self, /, policy_path: str | None = None, *,
|
||||
chkcon_path: str | None = None) -> None:
|
||||
|
||||
self.log = logging.getLogger(self.__class__.__name__)
|
||||
self.policy_path = policy_path
|
||||
self.selinux_enabled = libselinux.is_selinux_enabled() == 1
|
||||
self.chkcon_path: Path | str | None = self._find_chkcon(chkcon_path)
|
||||
self.log.debug(f"{self.__class__.__name__}: "
|
||||
f"{self.policy_path=}, "
|
||||
f"{self.selinux_enabled=}, "
|
||||
f"{self.chkcon_path=}")
|
||||
|
||||
def _find_chkcon(self, /, path: Path | str | None) -> Path | str | None:
|
||||
if path:
|
||||
self.log.debug(f"Checking access on provided chkcon path {path}")
|
||||
if os.access(path, os.X_OK):
|
||||
return path
|
||||
|
||||
for p in CHKCON_PATHS:
|
||||
path = p / "chkcon"
|
||||
self.log.debug(f"Trying chkcon path {path}")
|
||||
if os.access(path, os.X_OK):
|
||||
return path
|
||||
|
||||
self.log.warning("chkcon not found, trying to find with \"which\"")
|
||||
result = subprocess.run(["which", "chkcon"],
|
||||
check=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
return result.stdout.decode().strip() if result.returncode == 0 else None
|
||||
|
||||
def _chkcon_check_context(self, context: str, /) -> bool:
|
||||
assert self.chkcon_path
|
||||
assert self.policy_path
|
||||
result = subprocess.run([self.chkcon_path, self.policy_path, context],
|
||||
check=False,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
return result.returncode == 0
|
||||
|
||||
def validate_context(self, context: str, /) -> bool:
|
||||
"""Verify that the specified context is valid in the policy."""
|
||||
if self.chkcon_path and self.policy_path:
|
||||
self.log.debug(f"Validating context {context} with chkcon")
|
||||
return self._chkcon_check_context(context)
|
||||
|
||||
if self.selinux_enabled:
|
||||
self.log.debug(f"Validating context {context} with security_check_context")
|
||||
return libselinux.security_check_context(context) == 0
|
||||
|
||||
self.log.critical(f"Warning: Context validation not done for {context}")
|
||||
return True
|
||||
|
||||
|
||||
def validate_dbus_contexts(validator: ContextValidator, file_path: Path, /) -> bool:
|
||||
"""
|
||||
Validate the contexts in the specified dbus_contexts file.
|
||||
|
||||
A minimum/empty dbus_contexts file is as follows:
|
||||
|
||||
<busconfig>
|
||||
<selinux>
|
||||
</selinux>
|
||||
</busconfig>
|
||||
|
||||
An example dbus_contexts with dbus service labeling:
|
||||
|
||||
<busconfig>
|
||||
<selinux>
|
||||
<associate own="org.selinux.semanage" context="system_u:system_r:selinux_dbus_t:s0" />
|
||||
<associate own="org.selinux.Restorecond" context="system_u:system_r:restorecond_t:s0" />
|
||||
</selinux>
|
||||
</busconfig>
|
||||
"""
|
||||
|
||||
# Parse the XML file
|
||||
logging.info(f"Using {minidom.__name__} for parsing {file_path}.")
|
||||
dom: typing.Final[minidom.Document] = minidom.parse(str(file_path))
|
||||
|
||||
# Ensure <busconfig> is the top-level tag
|
||||
top_level_elements: list[minidom.Element] = [node for node in dom.childNodes
|
||||
if node.nodeType == Node.ELEMENT_NODE]
|
||||
|
||||
if len(top_level_elements) != 1 or top_level_elements[0].tagName != "busconfig":
|
||||
raise ValueError("The top-level tag must be <busconfig>.")
|
||||
|
||||
busconfig = top_level_elements[0]
|
||||
|
||||
# Not validating that <selinux> is the only tag under <busconfig> as other
|
||||
# tags can work, such as <policy>.
|
||||
selinux_elements: list[minidom.Element] = [node for node in busconfig.childNodes
|
||||
if node.nodeType == Node.ELEMENT_NODE
|
||||
and node.tagName == "selinux"]
|
||||
|
||||
# Ensure there is only one <selinux> element
|
||||
if len(selinux_elements) != 1:
|
||||
raise ValueError(
|
||||
f"Invalid number of <selinux> elements found under <busconfig>: {selinux_elements}.")
|
||||
|
||||
# Check if all child nodes are <associate> elements
|
||||
valid: bool = True
|
||||
for child in selinux_elements[0].childNodes:
|
||||
if child.nodeType != Node.ELEMENT_NODE:
|
||||
continue
|
||||
|
||||
if child.tagName != "associate":
|
||||
print(f"Invalid element found under <selinux>: {child.toxml()}")
|
||||
valid = False
|
||||
continue
|
||||
|
||||
# Validate that each <associate> element has only "own" and "context" attributes
|
||||
attributes: minidom.NamedNodeMap = child.attributes
|
||||
if set(attributes.keys()) != {"own", "context"}:
|
||||
print(f"Invalid associate element: {child.toxml()}")
|
||||
valid = False
|
||||
continue
|
||||
|
||||
# Validate the context attribute
|
||||
own: str = attributes["own"].value
|
||||
context: str = attributes["context"].value
|
||||
if not validator.validate_context(context):
|
||||
print(f"Invalid context for service {own}: {context}")
|
||||
valid = False
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
def validate_lxc_contexts(validator: ContextValidator, fullpath: Path, /) -> bool:
|
||||
"""Validate the lxc_contexts file."""
|
||||
valid: bool = True
|
||||
with open(fullpath, "r", encoding="utf-8") as file:
|
||||
logging.info(f"Validating {fullpath}")
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
items = line.split()
|
||||
with suppress(IndexError):
|
||||
if not items:
|
||||
continue
|
||||
|
||||
context = items[2].strip("\"")
|
||||
if not validator.validate_context(context):
|
||||
print(f"Invalid context in {fullpath}: {line}")
|
||||
valid = False
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
def validate_single_line_context_files(validator: ContextValidator,
|
||||
filenames: list[Path], /) -> bool:
|
||||
"""
|
||||
Validate the contexts in the files with single context per line. This
|
||||
is primarily for files tha have a single context, such as initrc_context,
|
||||
but can also be used for virtual_image_context, which can have multiple
|
||||
lines of a single context.
|
||||
"""
|
||||
valid: bool = True
|
||||
for filename in filenames:
|
||||
with open(filename, "r", encoding="utf-8") as file:
|
||||
logging.info(f"Validating {filename}")
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
|
||||
if not validator.validate_context(line):
|
||||
print(f"Invalid context in {filename}: {line}")
|
||||
valid = False
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
def validate_media_contexts(validator: ContextValidator, fullpath: Path, /) -> bool:
|
||||
"""Validate the contexts in the media file."""
|
||||
valid: bool = True
|
||||
with open(fullpath, "r", encoding="utf-8") as file:
|
||||
logging.info(f"Validating {fullpath}")
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
with suppress(IndexError):
|
||||
if not validator.validate_context(line.split()[1]):
|
||||
print(f"Invalid context in {fullpath}: {line}")
|
||||
valid = False
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
def validate_three_field_contexts(validator: ContextValidator, filepaths: list[Path], /,
|
||||
comment_char: str = "#") -> bool:
|
||||
"""
|
||||
Validate the contexts of a file that has three fields per line, with
|
||||
the third field being the context. Examples are sepgsql_contexts and
|
||||
x_contexts.
|
||||
"""
|
||||
valid: bool = True
|
||||
|
||||
for fullpath in filepaths:
|
||||
with open(fullpath, "r", encoding="utf-8") as file:
|
||||
logging.info(f"Validating {fullpath}")
|
||||
for line in file:
|
||||
line = line.strip()
|
||||
items = line.split()
|
||||
with suppress(IndexError):
|
||||
if not items or items[0].startswith(comment_char):
|
||||
continue
|
||||
|
||||
if not validator.validate_context(items[2]):
|
||||
print(f"Invalid context in {fullpath}: {line}")
|
||||
valid = False
|
||||
|
||||
return valid
|
||||
|
||||
|
||||
def validate_appconfig_files(conf_dir: str, /, *,
|
||||
policy_path: str | None = None,
|
||||
chkcon_path: str | None = None,
|
||||
lxc: bool = True,
|
||||
sepgsql: bool = True,
|
||||
virt: bool = True,
|
||||
xserver: bool = True) -> bool:
|
||||
|
||||
"""Validate the various appconfig userspace config files."""
|
||||
validator: typing.Final[ContextValidator] = ContextValidator(policy_path=policy_path,
|
||||
chkcon_path=chkcon_path)
|
||||
base_path: typing.Final[Path] = Path(conf_dir)
|
||||
|
||||
single_line_contexts = [base_path / p for p in SINGLE_LINE_CONTEXTS_FILES]
|
||||
if virt:
|
||||
single_line_contexts.extend(base_path / p for p in VIRT_CONTEXTS_FILES)
|
||||
|
||||
key_value_contexts = list[Path]()
|
||||
if sepgsql:
|
||||
key_value_contexts.append(base_path / SEPGSQL_CONTEXTS)
|
||||
if xserver:
|
||||
key_value_contexts.append(base_path / XSERVER_CONTEXTS)
|
||||
|
||||
return all((validate_dbus_contexts(validator, base_path / DBUS_CONTEXTS),
|
||||
validate_single_line_context_files(validator, single_line_contexts),
|
||||
validate_media_contexts(validator, base_path / MEDIA_CONTEXTS),
|
||||
validate_three_field_contexts(validator, key_value_contexts),
|
||||
validate_lxc_contexts(validator, base_path / LXC_CONTEXTS) if lxc else True))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Validate userspace app config.",
|
||||
epilog="If no policy is specified, the running policy (if any) is used.")
|
||||
parser.add_argument("APPCONFIG_DIR", type=str,
|
||||
help="Path to the appconfig dir to validate")
|
||||
parser.add_argument("POLICY_PATH", nargs="?", type=str,
|
||||
help="Path to binary policy file (optional)")
|
||||
parser.add_argument("-c", "--chkcon", type=str,
|
||||
help="Path to chkcon executable.")
|
||||
parser.add_argument("-l", "--lxc", action="store_true", help="Check lxc_contexts.")
|
||||
parser.add_argument("-s", "--sepgsql", action="store_true", help="Check sepgsql_contexts.")
|
||||
parser.add_argument("-v", "--virt", action="store_true", help="Check virtual_*_context.")
|
||||
parser.add_argument("-x", "--xserver", action="store_true", help="Check x_contexts.")
|
||||
parser.add_argument("--debug", action="store_true", dest="debug",
|
||||
help="Enable debugging.")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.debug:
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(asctime)s|%(levelname)s|%(name)s|%(message)s')
|
||||
if not sys.warnoptions:
|
||||
warnings.simplefilter("default")
|
||||
else:
|
||||
logging.basicConfig(level=logging.WARNING, format='%(message)s')
|
||||
if not sys.warnoptions:
|
||||
warnings.simplefilter("ignore")
|
||||
|
||||
try:
|
||||
# Validate the <associate> elements under <selinux>
|
||||
sys.exit(0 if validate_appconfig_files(args.APPCONFIG_DIR,
|
||||
policy_path=args.POLICY_PATH,
|
||||
chkcon_path=args.chkcon,
|
||||
lxc=args.lxc,
|
||||
sepgsql=args.sepgsql,
|
||||
virt=args.virt,
|
||||
xserver=args.xserver) else 1)
|
||||
|
||||
except Exception as err:
|
||||
if args.debug:
|
||||
raise
|
||||
|
||||
print(err)
|
||||
sys.exit(1)
|
Loading…
Reference in New Issue
Block a user