mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-04-29 02:06:07 +00:00

Improve config file error opening management and improve main code block. Execute this python script during CI to avoid regressions Signed-off-by: Hervé Beraud <hberaud@redhat.com>
153 lines
4.0 KiB
Python
Executable File
153 lines
4.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import sys
|
|
|
|
blocks = []
|
|
denies = []
|
|
|
|
#
|
|
# blocks is an array of paths under which we want to block by
|
|
# default.
|
|
#
|
|
# blocks[0] = ['path' = '/sys', 'children' = [A,B] ]
|
|
# blocks[1] = ['path' = '/proc/sys', 'children' = [ E ] ]
|
|
# A = [ 'path' = 'fs', children = [C] ]
|
|
# C = [ 'path' = 'cgroup', children = [F] ]
|
|
# B = [ 'path' = 'class', children = [D] ]
|
|
# D = [ 'path' = 'net', children = [F] ]
|
|
# E = [ 'path' = 'shm*' ]
|
|
# F = [ 'path' = '**' ]
|
|
|
|
|
|
def add_block(path):
|
|
for b in blocks:
|
|
if b['path'] == path:
|
|
# duplicate
|
|
return
|
|
blocks.append({'path': path.strip(), 'children': []})
|
|
|
|
# @prev is an array of dicts which containing 'path' and
|
|
# 'children'. @path is a string. We are looking for an entry
|
|
# in @prev which contains @path, and will return its
|
|
# children array.
|
|
def child_get(prev, path):
|
|
for p in prev:
|
|
if p['path'] == path:
|
|
return p['children']
|
|
return None
|
|
|
|
|
|
def add_allow(path):
|
|
# find which block we belong to
|
|
found = None
|
|
for b in blocks:
|
|
l = len(b['path'])
|
|
if len(path) <= l:
|
|
continue
|
|
# TODO - should we find the longest match?
|
|
if path[0:l] == b['path']:
|
|
found = b
|
|
break
|
|
if found is None:
|
|
print("allow with no previous block at %s" % path)
|
|
sys.exit(1)
|
|
p = path[l:].strip()
|
|
while p[:1] == "/":
|
|
p = p[1:]
|
|
prev = b['children']
|
|
for s in p.split('/'):
|
|
n = {'path': s.strip(), 'children': []}
|
|
tmp = child_get(prev, n['path'])
|
|
if tmp is not None:
|
|
prev = tmp
|
|
else:
|
|
prev.append(n)
|
|
prev = n['children']
|
|
|
|
|
|
def collect_chars(children, ref, index):
|
|
r = ""
|
|
for c in children:
|
|
if index >= len(c['path']):
|
|
continue
|
|
if ref[0:index] != c['path'][0:index]:
|
|
continue
|
|
if c['path'][index] not in r:
|
|
r = r + c['path'][index]
|
|
return r
|
|
|
|
|
|
def append_deny(s):
|
|
s = "%s wklx," % s
|
|
if s not in denies:
|
|
denies.append(s)
|
|
|
|
|
|
def gen_denies(pathsofar, children):
|
|
for c in children:
|
|
for char in range(len(c['path'])):
|
|
if char == len(c['path'])-1 and c['path'][char] == '*':
|
|
continue
|
|
if char == len(c['path'])-2:
|
|
if c['path'][char:char+2] == '**':
|
|
continue
|
|
x = collect_chars(children, c['path'], char)
|
|
newdeny = "deny %s/%s[^%s]*{,/**}" % (pathsofar,
|
|
c['path'][0:char], x)
|
|
append_deny(newdeny)
|
|
if c['path'] != '**' and c['path'][len(c['path'])-1] != '*':
|
|
newdeny = "deny %s/%s?*{,/**}" % (pathsofar, c['path'])
|
|
append_deny(newdeny)
|
|
elif c['path'] != '**':
|
|
newdeny = "deny %s/%s/**" % (pathsofar, c['path'])
|
|
append_deny(newdeny)
|
|
if len(c['children']) != 0:
|
|
newpath = "%s/%s" % (pathsofar, c['path'])
|
|
gen_denies(newpath, c['children'])
|
|
|
|
|
|
def main():
|
|
config = "config"
|
|
if len(sys.argv) > 1:
|
|
config = sys.argv[1]
|
|
|
|
lines = None
|
|
try:
|
|
with open(config) as f:
|
|
lines = f.readlines()
|
|
except FileNotFoundError as err:
|
|
print("Config file not found")
|
|
print(err)
|
|
sys.exit(1)
|
|
|
|
for line in lines:
|
|
line.strip()
|
|
if line.startswith('#'):
|
|
continue
|
|
try:
|
|
(cmd, path) = line.split(' ')
|
|
except: # blank line
|
|
continue
|
|
if cmd == "block":
|
|
add_block(path)
|
|
elif cmd == "allow":
|
|
add_allow(path)
|
|
else:
|
|
print("Unknown command: %s" % cmd)
|
|
sys.exit(1)
|
|
for block in blocks:
|
|
gen_denies(block['path'], block['children'])
|
|
|
|
denies.sort()
|
|
|
|
genby = " # generated by: lxc-generate-aa-rules.py"
|
|
for a in sys.argv[1:]:
|
|
genby += " %s" % a
|
|
print(genby)
|
|
for d in denies:
|
|
print(" %s" % d)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|