From bccf27db464f7bc8160ece36578e48bb277a5360 Mon Sep 17 00:00:00 2001
From: CentOS Sources <bugs@centos.org>
Date: May 09 2023 05:30:58 +0000
Subject: import setools-4.4.1-1.el9


---

diff --git a/.gitignore b/.gitignore
index e4e76d4..62dc7e6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/4.4.0.tar.gz
+SOURCES/4.4.1.tar.gz
diff --git a/.setools.metadata b/.setools.metadata
index 7309268..3c74635 100644
--- a/.setools.metadata
+++ b/.setools.metadata
@@ -1 +1 @@
-aaaea87c58e6677d5b3674b7e8bb8503964f6873 SOURCES/4.4.0.tar.gz
+4a6c9cdfd2bfa1b4822951a6d3ffa67fbaefd827 SOURCES/4.4.1.tar.gz
diff --git a/SOURCES/0001-Make-NetworkX-optional.patch b/SOURCES/0001-Make-NetworkX-optional.patch
new file mode 100644
index 0000000..c573d45
--- /dev/null
+++ b/SOURCES/0001-Make-NetworkX-optional.patch
@@ -0,0 +1,91 @@
+From 716a1d9e1db6701c0b310dd7e10dc4a10656da0f Mon Sep 17 00:00:00 2001
+From: Chris PeBenito <chpebeni@linux.microsoft.com>
+Date: Tue, 14 Dec 2021 14:24:20 -0500
+Subject: [PATCH] Make NetworkX optional.
+Content-type: text/plain
+
+The CLI tools get installed to most distros, but sedta and seinfoflow are
+not typically used or separated into a different package. This will allow
+seinfo, sesearch, and sediff to function if NetworkX is missing, since they
+don't require it.
+
+Signed-off-by: Chris PeBenito <chpebeni@linux.microsoft.com>
+---
+ setools/dta.py      | 18 ++++++++++++++----
+ setools/infoflow.py | 17 +++++++++++++----
+ 2 files changed, 27 insertions(+), 8 deletions(-)
+
+diff --git a/setools/dta.py b/setools/dta.py
+index ce5a36463684..ded88ff4f615 100644
+--- a/setools/dta.py
++++ b/setools/dta.py
+@@ -10,8 +10,11 @@ from collections import defaultdict
+ from contextlib import suppress
+ from typing import DefaultDict, Iterable, List, NamedTuple, Optional, Union
+ 
+-import networkx as nx
+-from networkx.exception import NetworkXError, NetworkXNoPath, NodeNotFound
++try:
++    import networkx as nx
++    from networkx.exception import NetworkXError, NetworkXNoPath, NodeNotFound
++except ImportError:
++    logging.getLogger(__name__).debug("NetworkX failed to import.")
+ 
+ from .descriptors import EdgeAttrDict, EdgeAttrList
+ from .policyrep import AnyTERule, SELinuxPolicy, TERuletype, Type
+@@ -73,8 +76,15 @@ class DomainTransitionAnalysis:
+         self.reverse = reverse
+         self.rebuildgraph = True
+         self.rebuildsubgraph = True
+-        self.G = nx.DiGraph()
+-        self.subG = self.G.copy()
++
++        try:
++            self.G = nx.DiGraph()
++            self.subG = self.G.copy()
++        except NameError:
++            self.log.critical("NetworkX is not available.  This is "
++                              "requried for Domain Transition Analysis.")
++            self.log.critical("This is typically in the python3-networkx package.")
++            raise
+ 
+     @property
+     def reverse(self) -> bool:
+diff --git a/setools/infoflow.py b/setools/infoflow.py
+index 0ef240a9993f..4b94a0c2d6dd 100644
+--- a/setools/infoflow.py
++++ b/setools/infoflow.py
+@@ -7,8 +7,11 @@ import logging
+ from contextlib import suppress
+ from typing import cast, Iterable, List, Mapping, Optional, Union
+ 
+-import networkx as nx
+-from networkx.exception import NetworkXError, NetworkXNoPath, NodeNotFound
++try:
++    import networkx as nx
++    from networkx.exception import NetworkXError, NetworkXNoPath, NodeNotFound
++except ImportError:
++    logging.getLogger(__name__).debug("NetworkX failed to import.")
+ 
+ from .descriptors import EdgeAttrIntMax, EdgeAttrList
+ from .permmap import PermissionMap
+@@ -54,8 +57,14 @@ class InfoFlowAnalysis:
+         self.rebuildgraph = True
+         self.rebuildsubgraph = True
+ 
+-        self.G = nx.DiGraph()
+-        self.subG = self.G.copy()
++        try:
++            self.G = nx.DiGraph()
++            self.subG = self.G.copy()
++        except NameError:
++            self.log.critical("NetworkX is not available.  This is "
++                              "requried for Information Flow Analysis.")
++            self.log.critical("This is typically in the python3-networkx package.")
++            raise
+ 
+     @property
+     def min_weight(self) -> int:
+-- 
+2.39.1
+
diff --git a/SOURCES/0001-Make-seinfo-output-predictable.patch b/SOURCES/0001-Make-seinfo-output-predictable.patch
deleted file mode 100644
index aa650fe..0000000
--- a/SOURCES/0001-Make-seinfo-output-predictable.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 8ed316d6bfb65e5e9b57f3761ea8490022ab3a05 Mon Sep 17 00:00:00 2001
-From: Petr Lautrbach <plautrba@redhat.com>
-Date: Thu, 18 Nov 2021 13:59:08 +0100
-Subject: [PATCH] Make seinfo output predictable
-
-There are few places where frozenset is used. Given that frozenset is an unordered
-collection the output generated from this is unpredictable.
-
-The following command outputs are fixed using sorted() on frozensets:
-
-    seinfo --constrain
-    seinfo --common
-    seinfo -c -x
-    seinfo -r -x
-    seinfo -u -x
-
-Fixes: https://github.com/SELinuxProject/setools/issues/65
-
-Signed-off-by: Petr Lautrbach <plautrba@redhat.com>
----
- setools/policyrep/constraint.pxi | 2 +-
- setools/policyrep/objclass.pxi   | 4 ++--
- setools/policyrep/role.pxi       | 2 +-
- setools/policyrep/user.pxi       | 2 +-
- 4 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/setools/policyrep/constraint.pxi b/setools/policyrep/constraint.pxi
-index 01c63d87425b..0b4c5b9bcf6a 100644
---- a/setools/policyrep/constraint.pxi
-+++ b/setools/policyrep/constraint.pxi
-@@ -72,7 +72,7 @@ cdef class Constraint(BaseConstraint):
- 
-     def statement(self):
-         if len(self.perms) > 1:
--            perms = "{{ {0} }}".format(' '.join(self.perms))
-+            perms = "{{ {0} }}".format(' '.join(sorted(self.perms)))
-         else:
-             # convert to list since sets cannot be indexed
-             perms = list(self.perms)[0]
-diff --git a/setools/policyrep/objclass.pxi b/setools/policyrep/objclass.pxi
-index b7ec7b7de5c3..8ed2be5a9bed 100644
---- a/setools/policyrep/objclass.pxi
-+++ b/setools/policyrep/objclass.pxi
-@@ -75,7 +75,7 @@ cdef class Common(PolicySymbol):
-         return other in self.perms
- 
-     def statement(self):
--        return "common {0}\n{{\n\t{1}\n}}".format(self, '\n\t'.join(self.perms))
-+        return "common {0}\n{{\n\t{1}\n}}".format(self, '\n\t'.join(sorted(self.perms)))
- 
- 
- cdef class ObjClass(PolicySymbol):
-@@ -204,7 +204,7 @@ cdef class ObjClass(PolicySymbol):
- 
-         # a class that inherits may not have additional permissions
-         if len(self.perms) > 0:
--            stmt += "{{\n\t{0}\n}}".format('\n\t'.join(self.perms))
-+            stmt += "{{\n\t{0}\n}}".format('\n\t'.join(sorted(self.perms)))
- 
-         return stmt
- 
-diff --git a/setools/policyrep/role.pxi b/setools/policyrep/role.pxi
-index 9a0dd39f27d9..3af8a3f72a1f 100644
---- a/setools/policyrep/role.pxi
-+++ b/setools/policyrep/role.pxi
-@@ -58,7 +58,7 @@ cdef class Role(PolicySymbol):
-         if count == 1:
-             stmt += " types {0}".format(types[0])
-         else:
--            stmt += " types {{ {0} }}".format(' '.join(types))
-+            stmt += " types {{ {0} }}".format(' '.join(sorted(types)))
- 
-         stmt += ";"
-         return stmt
-diff --git a/setools/policyrep/user.pxi b/setools/policyrep/user.pxi
-index 9c82aa92eb72..e37af2939820 100644
---- a/setools/policyrep/user.pxi
-+++ b/setools/policyrep/user.pxi
-@@ -81,7 +81,7 @@ cdef class User(PolicySymbol):
-         if count == 1:
-             stmt += roles[0]
-         else:
--            stmt += "{{ {0} }}".format(' '.join(roles))
-+            stmt += "{{ {0} }}".format(' '.join(sorted(roles)))
- 
-         if self._level:
-             stmt += " level {0.mls_level} range {0.mls_range};".format(self)
--- 
-2.33.1
-
diff --git a/SOURCES/1002-Do-not-export-use-setools.InfoFlowAnalysis-and-setoo.patch b/SOURCES/1002-Do-not-export-use-setools.InfoFlowAnalysis-and-setoo.patch
deleted file mode 100644
index d270d21..0000000
--- a/SOURCES/1002-Do-not-export-use-setools.InfoFlowAnalysis-and-setoo.patch
+++ /dev/null
@@ -1,142 +0,0 @@
-From e47d19f4985098ca316eea4a383510d419ec6055 Mon Sep 17 00:00:00 2001
-From: Vit Mojzis <vmojzis@redhat.com>
-Date: Fri, 26 Apr 2019 15:27:25 +0200
-Subject: [PATCH 1/2] Do not export/use setools.InfoFlowAnalysis and
- setools.DomainTransitionAnalysis
-
-dta and infoflow modules require networkx which brings lot of dependencies.
-These dependencies are not necessary for setools module itself as it's
-used in policycoreutils.
-
-Therefore it's better to use setools.infoflow.InfoFlowAnalysis and
-setools.dta.DomainTransitionAnalysis and let the package containing
-sedta and seinfoflow to require python3-networkx
----
- sedta                       | 5 +++--
- seinfoflow                  | 4 ++--
- setools/__init__.py         | 4 ----
- setoolsgui/apol/dta.py      | 2 +-
- setoolsgui/apol/infoflow.py | 2 +-
- tests/dta.py                | 2 +-
- tests/infoflow.py           | 2 +-
- 7 files changed, 9 insertions(+), 12 deletions(-)
-
-diff --git a/sedta b/sedta
-index 57070098fe10..51890ea8ea73 100755
---- a/sedta
-+++ b/sedta
-@@ -23,9 +23,10 @@ import logging
- import signal
- 
- import setools
-+import setools.dta
- 
- 
--def print_transition(trans: setools.DomainTransition) -> None:
-+def print_transition(trans: setools.dta.DomainTransition) -> None:
-     if trans.transition:
-         print("Domain transition rule(s):")
-         for t in trans.transition:
-@@ -114,7 +115,7 @@ else:
- 
- try:
-     p = setools.SELinuxPolicy(args.policy)
--    g = setools.DomainTransitionAnalysis(p, reverse=args.reverse, exclude=args.exclude)
-+    g = setools.dta.DomainTransitionAnalysis(p, reverse=args.reverse, exclude=args.exclude)
- 
-     if args.shortest_path or args.all_paths:
-         if args.shortest_path:
-diff --git a/seinfoflow b/seinfoflow
-index 0ddcfdc7c1fb..8321718b2640 100755
---- a/seinfoflow
-+++ b/seinfoflow
-@@ -17,7 +17,7 @@
- # along with SETools.  If not, see <http://www.gnu.org/licenses/>.
- #
- 
--import setools
-+import setools.infoflow
- import argparse
- import sys
- import logging
-@@ -102,7 +102,7 @@ elif args.booleans is not None:
- try:
-     p = setools.SELinuxPolicy(args.policy)
-     m = setools.PermissionMap(args.map)
--    g = setools.InfoFlowAnalysis(p, m, min_weight=args.min_weight, exclude=args.exclude,
-+    g = setools.infoflow.InfoFlowAnalysis(p, m, min_weight=args.min_weight, exclude=args.exclude,
-                                  booleans=booleans)
- 
-     if args.shortest_path or args.all_paths:
-diff --git a/setools/__init__.py b/setools/__init__.py
-index d72d343e7e79..642485b9018d 100644
---- a/setools/__init__.py
-+++ b/setools/__init__.py
-@@ -91,12 +91,8 @@ from .pcideviceconquery import PcideviceconQuery
- from .devicetreeconquery import DevicetreeconQuery
- 
- # Information Flow Analysis
--from .infoflow import InfoFlowAnalysis
- from .permmap import PermissionMap, RuleWeight, Mapping
- 
--# Domain Transition Analysis
--from .dta import DomainTransitionAnalysis, DomainEntrypoint, DomainTransition
--
- # Policy difference
- from .diff import PolicyDifference
- 
-diff --git a/setoolsgui/apol/dta.py b/setoolsgui/apol/dta.py
-index 62dbf04d9a5e..0ea000e790f0 100644
---- a/setoolsgui/apol/dta.py
-+++ b/setoolsgui/apol/dta.py
-@@ -24,7 +24,7 @@ from PyQt5.QtCore import pyqtSignal, Qt, QStringListModel, QThread
- from PyQt5.QtGui import QPalette, QTextCursor
- from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, \
-     QTreeWidgetItem
--from setools import DomainTransitionAnalysis
-+from setools.dta import DomainTransitionAnalysis
- 
- from ..logtosignal import LogHandlerToSignal
- from .analysistab import AnalysisSection, AnalysisTab
-diff --git a/setoolsgui/apol/infoflow.py b/setoolsgui/apol/infoflow.py
-index 28009aa2329c..92d350bf727c 100644
---- a/setoolsgui/apol/infoflow.py
-+++ b/setoolsgui/apol/infoflow.py
-@@ -26,7 +26,7 @@ from PyQt5.QtCore import pyqtSignal, Qt, QStringListModel, QThread
- from PyQt5.QtGui import QPalette, QTextCursor
- from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, \
-     QTreeWidgetItem
--from setools import InfoFlowAnalysis
-+from setools.infoflow import InfoFlowAnalysis
- from setools.exception import UnmappedClass, UnmappedPermission
- 
- from ..logtosignal import LogHandlerToSignal
-diff --git a/tests/dta.py b/tests/dta.py
-index a0cc9381469c..177e6fb0b961 100644
---- a/tests/dta.py
-+++ b/tests/dta.py
-@@ -18,7 +18,7 @@
- import os
- import unittest
- 
--from setools import DomainTransitionAnalysis
-+from setools.dta import DomainTransitionAnalysis
- from setools import TERuletype as TERT
- from setools.exception import InvalidType
- from setools.policyrep import Type
-diff --git a/tests/infoflow.py b/tests/infoflow.py
-index aa0e44a7e4f8..fca2848aeca5 100644
---- a/tests/infoflow.py
-+++ b/tests/infoflow.py
-@@ -18,7 +18,7 @@
- import os
- import unittest
- 
--from setools import InfoFlowAnalysis
-+from setools.infoflow import InfoFlowAnalysis
- from setools import TERuletype as TERT
- from setools.exception import InvalidType
- from setools.permmap import PermissionMap
--- 
-2.30.0
-
diff --git a/SPECS/setools.spec b/SPECS/setools.spec
index d7854c9..5b1c660 100644
--- a/SPECS/setools.spec
+++ b/SPECS/setools.spec
@@ -2,17 +2,16 @@
 %global selinux_ver 3.4-1
 
 Name:           setools
-Version:        4.4.0
-Release:        5%{?dist}
+Version:        4.4.1
+Release:        1%{?dist}
 Summary:        Policy analysis tools for SELinux
 
-License:        GPLv2
+License:        GPL-2.0-only and LGPL-2.1-only
 URL:            https://github.com/SELinuxProject/setools/wiki
 Source0:        https://github.com/SELinuxProject/setools/archive/%{version}.tar.gz
 Source1:        setools.pam
 Source2:        apol.desktop
-Patch0001:      0001-Make-seinfo-output-predictable.patch
-Patch1002:      1002-Do-not-export-use-setools.InfoFlowAnalysis-and-setoo.patch
+Patch0001:      0001-Make-NetworkX-optional.patch
 Patch1003:      1003-Require-networkx-on-package-level.patch
 Obsoletes:      setools < 4.0.0, setools-devel < 4.0.0
 BuildRequires:  flex,  bison
@@ -35,7 +34,7 @@ Python modules designed to facilitate SELinux policy analysis.
 
 %package     console
 Summary:     Policy analysis command-line tools for SELinux
-License:     GPLv2
+License:     GPL-2.0-only
 Requires:    python3-setools = %{version}-%{release}
 Requires:    libselinux >= %{selinux_ver}
 
@@ -52,7 +51,7 @@ This package includes the following console tools:
 
 %package     console-analyses
 Summary:     Policy analysis command-line tools for SELinux
-License:     GPLv2
+License:     GPL-2.0-only
 Requires:    python3-setools = %{version}-%{release}
 Requires:    libselinux >= %{selinux_ver}
 Requires:    python3-networkx
@@ -68,7 +67,8 @@ This package includes the following console tools:
 
 
 %package     -n python3-setools
-Summary:     Policy analysis tools for SELinux  
+Summary:     Policy analysis tools for SELinux
+License:     LGPL-2.1-only
 Obsoletes:   setools-libs < 4.0.0
 %{?python_provide:%python_provide python3-setools}
 Requires:    python3-setuptools
@@ -80,6 +80,7 @@ Python 3 modules designed to facilitate SELinux policy analysis.
 
 %package     gui
 Summary:     Policy analysis graphical tools for SELinux
+License:     GPL-2.0-only
 Requires:    python3-setools = %{version}-%{release}
 Requires:    python3-qt5
 Requires:    python3-networkx
@@ -109,6 +110,7 @@ Python modules designed to facilitate SELinux policy analysis.
 %files
 
 %files console
+%license COPYING.GPL
 %{_bindir}/sechecker
 %{_bindir}/sediff
 %{_bindir}/seinfo
@@ -122,6 +124,7 @@ Python modules designed to facilitate SELinux policy analysis.
 %{_mandir}/ru/man1/sesearch*
 
 %files console-analyses
+%license COPYING.GPL
 %{_bindir}/sedta
 %{_bindir}/seinfoflow
 %{_mandir}/man1/sedta*
@@ -130,17 +133,21 @@ Python modules designed to facilitate SELinux policy analysis.
 %{_mandir}/ru/man1/seinfoflow*
 
 %files -n python3-setools
-%license COPYING COPYING.GPL COPYING.LGPL
+%license COPYING COPYING.LGPL
 %{python3_sitearch}/setools
 %{python3_sitearch}/setools-*
 
 %files gui
+%license COPYING.GPL
 %{_bindir}/apol
 %{python3_sitearch}/setoolsgui
 %{_mandir}/man1/apol*
 %{_mandir}/ru/man1/apol*
 
 %changelog
+* Mon Feb  6 2023 Petr Lautrbach <lautrbach@redhat.com> - 4.4.1-1
+- SETools 4.4.1 release
+
 * Fri Jun 10 2022 Petr Lautrbach <plautrba@redhat.com> - 4.4.0-5
 - Update required userspace versions to 3.4
 - Drop unnecessary Recommends