Hello community,
here is the log from the commit of package polkit-default-privs for
openSUSE:Factory checked in at 2020-03-14 09:53:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/polkit-default-privs (Old)
and /work/SRC/openSUSE:Factory/.polkit-default-privs.new.3160 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "polkit-default-privs"
Sat Mar 14 09:53:47 2020 rev:181 rq:783415 version:1550+20200310.cdde967
Changes:
--------
---
/work/SRC/openSUSE:Factory/polkit-default-privs/polkit-default-privs.changes
2020-03-01 21:26:30.192372336 +0100
+++
/work/SRC/openSUSE:Factory/.polkit-default-privs.new.3160/polkit-default-privs.changes
2020-03-14 09:53:48.503042662 +0100
@@ -1,0 +2,7 @@
+Tue Mar 10 13:37:13 UTC 2020 - [email protected]
+
+- Update to version 1550+20200310.cdde967:
+ * profiles: whitelist new timeshift pkexec actions (bsc#1165436)
+ * polkit profile: remove trailing '###' lines
+
+-------------------------------------------------------------------
Old:
----
polkit-default-privs-1550+20200213.f716f0a.tar.xz
New:
----
polkit-default-privs-1550+20200310.cdde967.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ polkit-default-privs.spec ++++++
--- /var/tmp/diff_new_pack.qLldGz/_old 2020-03-14 09:53:49.075043082 +0100
+++ /var/tmp/diff_new_pack.qLldGz/_new 2020-03-14 09:53:49.075043082 +0100
@@ -1,7 +1,7 @@
#
# spec file for package polkit-default-privs
#
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -23,7 +23,7 @@
%endif
Name: polkit-default-privs
-Version: 1550+20200213.f716f0a
+Version: 1550+20200310.cdde967
Release: 0
Summary: SUSE PolicyKit default permissions
License: GPL-2.0-or-later
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.qLldGz/_old 2020-03-14 09:53:49.099043099 +0100
+++ /var/tmp/diff_new_pack.qLldGz/_new 2020-03-14 09:53:49.103043103 +0100
@@ -1,4 +1,4 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://github.com/openSUSE/polkit-default-privs.git</param>
- <param
name="changesrevision">f716f0a6a93490b9230f8d76647767fc100879b8</param></service></servicedata>
\ No newline at end of file
+ <param
name="changesrevision">cdde967ac428c1be56a32f4c83fb99877b11a57e</param></service></servicedata>
\ No newline at end of file
++++++ polkit-default-privs-1550+20200213.f716f0a.tar.xz ->
polkit-default-privs-1550+20200310.cdde967.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/polkit-default-privs-1550+20200213.f716f0a/profiles/polkit-default-privs.easy
new/polkit-default-privs-1550+20200310.cdde967/profiles/polkit-default-privs.easy
---
old/polkit-default-privs-1550+20200213.f716f0a/profiles/polkit-default-privs.easy
2020-02-13 13:15:26.000000000 +0100
+++
new/polkit-default-privs-1550+20200310.cdde967/profiles/polkit-default-privs.easy
2020-03-10 14:13:36.000000000 +0100
@@ -1051,4 +1051,6 @@
# calamares run as root in X11 (bsc#1143147)
com.github.calamares.calamares.pkexec.run no:no:auth_admin
-###
+# backup tool that needs root privilege escalation via pkexec (bsc#1165436)
+in.teejeetech.pkexec.timeshift-gtk auth_admin:auth_admin:auth_admin
+in.teejeetech.pkexec.timeshift auth_admin:auth_admin:auth_admin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/polkit-default-privs-1550+20200213.f716f0a/profiles/polkit-default-privs.restrictive
new/polkit-default-privs-1550+20200310.cdde967/profiles/polkit-default-privs.restrictive
---
old/polkit-default-privs-1550+20200213.f716f0a/profiles/polkit-default-privs.restrictive
2020-02-13 13:15:26.000000000 +0100
+++
new/polkit-default-privs-1550+20200310.cdde967/profiles/polkit-default-privs.restrictive
2020-03-10 14:13:36.000000000 +0100
@@ -989,4 +989,6 @@
# calamares run as root in X11 (bsc#1143147)
com.github.calamares.calamares.pkexec.run no:no:auth_admin
-###
+# backup tool that needs root privilege escalation via pkexec (bsc#1165436)
+in.teejeetech.pkexec.timeshift-gtk auth_admin:auth_admin:auth_admin
+in.teejeetech.pkexec.timeshift auth_admin:auth_admin:auth_admin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/polkit-default-privs-1550+20200213.f716f0a/profiles/polkit-default-privs.standard
new/polkit-default-privs-1550+20200310.cdde967/profiles/polkit-default-privs.standard
---
old/polkit-default-privs-1550+20200213.f716f0a/profiles/polkit-default-privs.standard
2020-02-13 13:15:26.000000000 +0100
+++
new/polkit-default-privs-1550+20200310.cdde967/profiles/polkit-default-privs.standard
2020-03-10 14:13:36.000000000 +0100
@@ -1052,4 +1052,6 @@
# calamares run as root in X11 (bsc#1143147)
com.github.calamares.calamares.pkexec.run no:no:auth_admin
-###
+# backup tool that needs root privilege escalation via pkexec (bsc#1165436)
+in.teejeetech.pkexec.timeshift-gtk auth_admin:auth_admin:auth_admin
+in.teejeetech.pkexec.timeshift auth_admin:auth_admin:auth_admin
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/polkit-default-privs-1550+20200213.f716f0a/tools/add_polkit_action.py
new/polkit-default-privs-1550+20200310.cdde967/tools/add_polkit_action.py
--- old/polkit-default-privs-1550+20200213.f716f0a/tools/add_polkit_action.py
1970-01-01 01:00:00.000000000 +0100
+++ new/polkit-default-privs-1550+20200310.cdde967/tools/add_polkit_action.py
2020-03-10 14:13:36.000000000 +0100
@@ -0,0 +1,265 @@
+#!/usr/bin/python3
+
+# vim: ts=4 et sw=4 sts=4 :
+
+import os, sys
+import argparse
+from pathlib import Path
+
+def printerr(*args, **kwargs):
+ kwargs["file"] = sys.stderr
+ print(*args, **kwargs)
+
+epilog = """Example invocation:
+
+# add a single new rule introducing a new group of actions
+{} \\
+ --new-group "bsc#1165436:backup tool that performs privilege escalation to
root" \\
+ --action in.teejeetech.pkexec.timeshift \\
+ --easy auth_admin:auth_admin:auth_admin_keep \\
+ --standard auth_admin \\
+ --restrictive auth_admin
+""".format(__file__)
+
+class PolkitActionHandler:
+
+ # existing default profiles in increasing order of security
+ PROFILES = ("easy", "standard", "restrictive")
+ # existing authentication type settings in increasing order of security
+ AUTH_TYPES = ("yes", "auth_self_keep", "auth_self", "auth_admin_keep",
"auth_admin", "no")
+ AUTH_CATEGORIES = ("any-user", "inactive-session", "active-session")
+
+ def __init__(self):
+
+ self.m_profile_dir = Path(__file__).parent.with_name("profiles")
+
+ self.m_parser = argparse.ArgumentParser(
+ description = "Adds a new action with associated authentication
settings to the polkit profiles managed by polkit-default-privs",
+ formatter_class = argparse.RawTextHelpFormatter,
+ epilog = epilog
+ )
+
+ self.m_parser.add_argument(
+ "--new-group",
+ metavar = "bsc#<bug>:<comment>",
+ type = self.parseGroupArg,
+ help = "Introduces a new group block of related polkit actions.
Requires a bug reference and comment string"
+ )
+
+ self.m_parser.add_argument(
+ "--action",
+ help = "the canonical action name to add like
'in.teejeetech.pkexec.timeshift'",
+ required = True,
+ type = self.parseAction
+ )
+
+ for profile in self.PROFILES:
+
+ self.m_parser.add_argument(
+ "--" + profile,
+ metavar = ':'.join(self.AUTH_CATEGORIES),
+ type = self.parseAuthTuple,
+ help = "Specifies the settings for the --action in this
profile. If all three fields are equal you may also specify only a single field
without colons.",
+ required = True
+ )
+
+ def parseAuthTuple(self, s):
+ s = s.lower()
+ if s in self.AUTH_TYPES:
+ # the same auth type for all three fields
+ # expand to three full fields for easier usage later on
+ return [s] * 3
+
+ parts = s.split(':')
+
+ if len(parts) != 3:
+ raise argparse.ArgumentTypeError("invalid number of ':' separated
fields")
+
+ ret = []
+
+ for part in parts:
+ part = part.lower()
+ if part not in self.AUTH_TYPES:
+ raise argparse.ArgumentTypeError("bad authentication type
'{}'".format(part))
+
+ ret.append(part)
+
+ return ret
+
+ def parseGroupArg(self, s):
+
+ parts = s.split(':', 1)
+
+ if len(parts) != 2:
+ raise argparse.ArgumentTypeError("missing ':' separator")
+
+ bug, comment = parts
+
+ parts = bug.split('#')
+
+ if len(parts) != 2:
+ raise argparse.ArgumentTypeError("missing '#' separator in bug
reference")
+
+ prefix, nr = parts
+ prefix = prefix.lower()
+
+ allowed_prefixes = ("bsc", "boo")
+
+ if prefix not in allowed_prefixes:
+ raise argparse.ArgumentTypeError("invalid bug prefix, expected any
of {}".format(allowed_prefixes))
+
+ try:
+ nr = int(nr)
+ except ValueError:
+ raise argparse.ArgumentTypeError("invalid bug number
{}".format(nr))
+
+ if len(comment.split("\n")) != 1:
+ raise argparse.ArgumentTypeError("newline in comment encountered")
+
+ return (prefix, nr), comment
+
+ def parseAction(self, s):
+
+ # make sure there's no whitespace
+ if len(s.split()) != 1:
+ raise argparse.ArgumentTypeError("whitespace in action name")
+
+ # should have at least one separator
+ if len(s.split('.')) < 2:
+ raise argparse.ArgumentTypeError("too few elements in action name")
+
+ return s
+
+ def getProfilePath(self, which):
+ base = "polkit-default-privs.{}".format(which)
+ return self.m_profile_dir / base
+
+ def run(self):
+
+ self.m_args = self.m_parser.parse_args()
+ # tuple of auth types matching the profiles
+ self.m_auth_types = tuple( getattr(self.m_args, profile) for profile
in self.PROFILES )
+
+ if not self.sanityCheck():
+ printerr("Not adding new action since sanity check(s) failed")
+ sys.exit(2)
+
+ self.addAction()
+
+ def sanityCheck(self):
+ """Perform a couple of sanity checks for the newly added actions. This
+ is somewhat redundant to the linter in the security-tools repository
+ but these checks can this way be applied right away and they're not
+ too complex to make."""
+
+ ret = self.findDuplicateActions()
+ ret &= self.checkProfileAuthTypeOrder()
+ ret &= self.checkBugNr()
+
+ return ret
+
+ def findDuplicateActions(self):
+
+ ret = True
+
+ for profile in self.PROFILES:
+
+ path = self.getProfilePath(profile)
+
+ with open(path) as fd:
+
+ nr = 0
+ for line in fd.readlines():
+ nr += 1
+ line = line.strip()
+ if not line or line.startswith('#'):
+ continue
+
+ action = line.split()[0]
+ if action == self.m_args.action:
+ printerr("ERROR: action to be added already exists in
{}:{}".format(
+ path, nr
+ ))
+ ret = False
+
+
+ return ret
+
+ def checkProfileAuthTypeOrder(self):
+ """Checks that authentication types are not getting weaker in stronger
+ profiles."""
+
+ ret = True
+ strongest = [ self.AUTH_TYPES[0] ] * 3
+
+ for profile, auth_types in zip( self.PROFILES, self.m_auth_types ):
+ for nr, old, new in zip( range(len(strongest)), strongest,
auth_types ):
+
+ if self.AUTH_TYPES.index(old) > self.AUTH_TYPES.index(new):
+ printerr("ERROR: Auth type for {} in profile {} is weaker
than in profile {}".format(
+ self.AUTH_CATEGORIES[nr],
+ profile,
+ self.PROFILES[ self.PROFILES.index(profile) - 1]
+ ))
+ ret = False
+
+ strongest = auth_types
+
+ return ret
+
+ def checkBugNr(self):
+ """Attempts to verify that a specified bug number really exists."""
+
+ import subprocess
+ import shutil
+
+ if not self.m_args.new_group:
+ return True
+
+ bug = self.m_args.new_group[0]
+ nr = bug[1]
+
+ insect = shutil.which("insect")
+
+ if not insect:
+ # cannot check bug validity without some bugzilla CLI, assume it's
+ # fine
+ return True
+
+ try:
+ # don't suppress output, might be a helpful pointer to see the
+ # actual bug summary once more on success
+ subprocess.check_call(
+ [insect, "info", "-1", str(nr)],
+ shell = False,
+ close_fds = True
+ )
+ except subprocess.CalledProcessError:
+ printerr("ERROR: bug {}#{} doesn't seem to exist".format(*bug))
+ return False
+
+ return True
+
+ def addAction(self):
+
+ for profile, auth_settings in zip(self.PROFILES, self.m_auth_types):
+
+ path = self.getProfilePath(profile)
+
+ with open(path, 'a') as fd:
+
+ if self.m_args.new_group:
+ bug, comment = self.m_args.new_group
+ fd.write("\n")
+ fd.write("# {} ({}#{})\n".format(
+ comment, *bug
+ ))
+
+ fd.write("{} {}\n".format(
+ self.m_args.action,
+ ':'.join(auth_settings)
+ ))
+
+
+main = PolkitActionHandler()
+main.run()