SHA256
1
0
forked from pool/rpmlint
rpmlint/CheckPolkitPrivs.py

129 lines
4.6 KiB
Python
Raw Normal View History

# vim:sw=4:et
#############################################################################
# File : CheckPolkitPrivs.py
# Package : rpmlint
# Author : Ludwig Nussel
# Purpose : Check for /etc/polkit-default-privs violations
#############################################################################
from Filter import *
import AbstractCheck
import Config
import re
import os
from xml.dom.minidom import parse
POLKIT_PRIVS_WHITELIST = Config.getOption('PolkitPrivsWhiteList', ()) # set of file names
POLKIT_PRIVS_FILES = Config.getOption('PolkitPrivsFiles', [ "/etc/polkit-default-privs.standard" ])
class PolkitCheck(AbstractCheck.AbstractCheck):
def __init__(self):
AbstractCheck.AbstractCheck.__init__(self, "CheckPolkitPrivs")
self.privs = {}
for file in POLKIT_PRIVS_FILES:
if os.path.exists(file):
self._parsefile(file)
def _parsefile(self,file):
for line in open(file):
line = line.split('#')[0].split('\n')[0]
if len(line):
line = re.split(r'\s+', line)
priv = line[0]
value = line[1]
self.privs[priv] = value
def check(self, pkg):
if pkg.isSource():
return
files = pkg.files()
permfiles = {}
# first pass, find additional files
for f in files:
if f in pkg.ghostFiles():
continue
if f.startswith("/etc/polkit-default-privs.d/"):
bn = f[28:]
if not bn in POLKIT_PRIVS_WHITELIST:
printError(pkg, "polkit-unauthorized-file", f)
bn = bn.split('.')[0]
if not bn in permfiles:
permfiles[bn] = 1
for f in permfiles:
f = pkg.dirName() + "/etc/polkit-default-privs.d/" + f
if os.path.exists(f+".restrictive"):
self._parsefile(f + ".restrictive")
elif os.path.exists(f+".standard"):
self._parsefile(f + ".standard")
elif os.path.exists(f+".relaxed"):
self._parsefile(f + ".relaxed")
else:
self._parsefile(f)
for f in files:
if f in pkg.ghostFiles():
continue
# catch xml exceptions
try:
if f.startswith("/usr/share/PolicyKit/policy/")\
or f.startswith("/usr/share/polkit-1/actions/"):
f = pkg.dirName() + f
xml = parse(f)
for a in xml.getElementsByTagName("action"):
action = a.getAttribute('id')
if not action in self.privs:
iserr = 0
foundno = 0
anyseen = 0
try:
defaults = a.getElementsByTagName("defaults")[0]
for i in defaults.childNodes:
if not i.nodeType == i.ELEMENT_NODE:
continue
if i.nodeName == 'allow_any':
anyseen = 1
if i.firstChild.data.find("auth_admin") != 0:
if i.firstChild.data == 'no':
foundno = 1
else:
iserr = 1
except:
iserr = 1
if iserr:
printError(pkg, 'polkit-unauthorized-privilege', action)
else:
printInfo(pkg, 'polkit-unauthorized-privilege', action)
if foundno or not anyseen:
printWarning(pkg, 'polkit-cant-acquire-privilege', action)
except:
continue
check=PolkitCheck()
if Config.info:
addDetails(
'polkit-unauthorized-file',
"""If the package is intended for inclusion in any SUSE product
please open a bug report to request review of the package by the
security team""",
'polkit-unauthorized-privilege',
"""If the package is intended for inclusion in any SUSE product
please open a bug report to request review of the package by the
security team""",
'polkit-cant-acquire-privilege',
"""Usability can be improved by allowing users to acquire privileges
via authentication. Use e.g. 'auth_admin' instead of 'no' and make
sure to define 'allow_any'.""")