Output different header sets for kernel and userland from flask headers.
This commit is contained in:
parent
1852cdabce
commit
e9b0042f35
@ -1,3 +1,4 @@
|
|||||||
|
- Output different header sets for kernel and userland from flask headers.
|
||||||
- Marked the pax class as deprecated, changed it to userland so
|
- Marked the pax class as deprecated, changed it to userland so
|
||||||
it will be removed from the kernel.
|
it will be removed from the kernel.
|
||||||
- Stop including netfilter contexts by default.
|
- Stop including netfilter contexts by default.
|
||||||
|
@ -1,41 +1,51 @@
|
|||||||
|
PYTHON ?= python
|
||||||
|
|
||||||
# flask needs to know where to export the libselinux headers.
|
# flask needs to know where to export the libselinux headers.
|
||||||
LIBSEL ?= ../../libselinux
|
LIBSELINUX_D ?= ../../libselinux
|
||||||
|
|
||||||
# flask needs to know where to export the kernel headers.
|
# flask needs to know where to export the kernel headers.
|
||||||
LINUXDIR ?= ../../../linux-2.6
|
LINUX_D ?= ../../../linux-2.6
|
||||||
|
|
||||||
AWK = awk
|
ACCESS_VECTORS_F = access_vectors
|
||||||
|
INITIAL_SIDS_F = initial_sids
|
||||||
|
SECURITY_CLASSES_F = security_classes
|
||||||
|
|
||||||
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
|
USER_D = userspace
|
||||||
else if [ -x /bin/bash ]; then echo /bin/bash; \
|
KERN_D = kernel
|
||||||
else echo sh; fi ; fi)
|
|
||||||
|
|
||||||
FLASK_H_DEPEND = security_classes initial_sids
|
LIBSELINUX_INCLUDE_H = flask.h av_permissions.h
|
||||||
AV_H_DEPEND = access_vectors
|
LIBSELINUX_SOURCE_H = class_to_string.h av_inherit.h common_perm_to_string.h av_perm_to_string.h
|
||||||
|
|
||||||
FLASK_H_FILES = class_to_string.h flask.h initial_sid_to_string.h
|
FLASK_H = class_to_string.h flask.h initial_sid_to_string.h
|
||||||
AV_H_FILES = av_inherit.h common_perm_to_string.h av_perm_to_string.h av_permissions.h
|
ACCESS_VECTORS_H = av_inherit.h common_perm_to_string.h av_perm_to_string.h av_permissions.h
|
||||||
ALL_H_FILES = $(FLASK_H_FILES) $(AV_H_FILES)
|
ALL_H = $(FLASK_H) $(ACCESS_VECTORS_H)
|
||||||
|
|
||||||
all: $(ALL_H_FILES)
|
USER_H = $(addprefix $(USER_D)/, $(ALL_H))
|
||||||
|
KERN_H = $(addprefix $(KERN_D)/, $(ALL_H))
|
||||||
|
|
||||||
$(FLASK_H_FILES): $(FLASK_H_DEPEND)
|
FLASK_NOWARNINGS = --nowarnings
|
||||||
$(CONFIG_SHELL) mkflask.sh $(AWK) $(FLASK_H_DEPEND)
|
|
||||||
|
|
||||||
$(AV_H_FILES): $(AV_H_DEPEND)
|
all: $(USER_H) $(KERN_H)
|
||||||
$(CONFIG_SHELL) mkaccess_vector.sh $(AWK) $(AV_H_DEPEND)
|
|
||||||
|
$(USER_H):
|
||||||
|
mkdir -p $(USER_D)
|
||||||
|
$(PYTHON) flask.py -a $(ACCESS_VECTORS_F) -i $(INITIAL_SIDS_F) -s $(SECURITY_CLASSES_F) -o $(USER_D) -u $(FLASK_NOWARNINGS)
|
||||||
|
|
||||||
|
$(KERN_H):
|
||||||
|
mkdir -p $(KERN_D)
|
||||||
|
$(PYTHON) flask.py -a $(ACCESS_VECTORS_F) -i $(INITIAL_SIDS_F) -s $(SECURITY_CLASSES_F) -o $(KERN_D) -k $(FLASK_NOWARNINGS)
|
||||||
|
|
||||||
tolib: all
|
tolib: all
|
||||||
install -m 644 flask.h av_permissions.h $(LIBSEL)/include/selinux
|
install -m 644 $(addprefix $(USER_D)/, $(LIBSELINUX_INCLUDE_H)) $(LIBSELINUX_D)/include/selinux
|
||||||
install -m 644 class_to_string.h av_inherit.h common_perm_to_string.h av_perm_to_string.h $(LIBSEL)/src
|
install -m 644 $(addprefix $(USER_D)/, $(LIBSELINUX_SOURCE_H)) $(LIBSELINUX_D)/src
|
||||||
|
|
||||||
tokern: all
|
tokern: all
|
||||||
install -m 644 $(ALL_H_FILES) $(LINUXDIR)/security/selinux/include
|
install -m 644 $(KERN_H) $(LINUX_D)/security/selinux/include
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
|
|
||||||
relabel:
|
relabel:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(FLASK_H_FILES)
|
rm -fr userspace
|
||||||
rm -f $(AV_H_FILES)
|
rm -fr kernel
|
||||||
|
529
policy/flask/flask.py
Normal file
529
policy/flask/flask.py
Normal file
@ -0,0 +1,529 @@
|
|||||||
|
#!/usr/bin/python -E
|
||||||
|
#
|
||||||
|
# Author(s): Caleb Case <ccase@tresys.com>
|
||||||
|
#
|
||||||
|
# Adapted from the bash/awk scripts mkflask.sh and mkaccess_vector.sh
|
||||||
|
#
|
||||||
|
|
||||||
|
import getopt
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
class ParseError(Exception):
|
||||||
|
def __init__(self, type, file, line):
|
||||||
|
self.type = type
|
||||||
|
self.file = file
|
||||||
|
self.line = line
|
||||||
|
def __str__(self):
|
||||||
|
typeS = self.type
|
||||||
|
if type(self.type) is not str: typeS = Flask.CONSTANT_S[self.type]
|
||||||
|
return "Parse Error: Unexpected %s on line %d of %s." % (typeS, self.line, self.file)
|
||||||
|
|
||||||
|
class DuplicateError(Exception):
|
||||||
|
def __init__(self, type, file, line, symbol):
|
||||||
|
self.type = type
|
||||||
|
self.file = file
|
||||||
|
self.line = line
|
||||||
|
self.symbol = symbol
|
||||||
|
def __str__(self):
|
||||||
|
typeS = self.type
|
||||||
|
if type(self.type) is not str: typeS = Flask.CONSTANT_S[self.type]
|
||||||
|
return "Duplicate Error: Duplicate %s '%s' on line %d of %s." % (typeS, self.symbol, self.line, self.file)
|
||||||
|
|
||||||
|
class UndefinedError(Exception):
|
||||||
|
def __init__(self, type, file, line, symbol):
|
||||||
|
self.type = type
|
||||||
|
self.file = file
|
||||||
|
self.line = line
|
||||||
|
self.symbol = symbol
|
||||||
|
def __str__(self):
|
||||||
|
typeS = self.type
|
||||||
|
if type(self.type) is not str: typeS = Flask.CONSTANT_S[self.type]
|
||||||
|
return "Undefined Error: %s '%s' is not defined but used on line %d of %s." % (typeS, self.symbol, self.line, self.file)
|
||||||
|
|
||||||
|
class UnusedError(Exception):
|
||||||
|
def __init__(self, info):
|
||||||
|
self.info = info
|
||||||
|
def __str__(self):
|
||||||
|
return "Unused Error: %s" % self.info
|
||||||
|
|
||||||
|
class Flask:
|
||||||
|
'''
|
||||||
|
FLASK container class with utilities for parsing definition
|
||||||
|
files and creating c header files.
|
||||||
|
'''
|
||||||
|
|
||||||
|
#Constants used in definitions parsing.
|
||||||
|
WHITE = re.compile(r'^\s*$')
|
||||||
|
COMMENT = re.compile(r'^\s*#')
|
||||||
|
USERFLAG = re.compile(r'# userspace')
|
||||||
|
CLASS = re.compile(r'^class (?P<name>\w+)')
|
||||||
|
COMMON = re.compile(r'^common (?P<name>\w+)')
|
||||||
|
INHERITS = re.compile(r'^inherits (?P<name>\w+)')
|
||||||
|
OPENB = re.compile(r'^{')
|
||||||
|
VECTOR = re.compile(r'^\s*(?P<name>\w+)')
|
||||||
|
CLOSEB = re.compile(r'^}')
|
||||||
|
SID = re.compile(r'^sid (?P<name>\w+)')
|
||||||
|
EOF = "end of file"
|
||||||
|
|
||||||
|
#Constants used in header generation.
|
||||||
|
USERSPACE = 0
|
||||||
|
KERNEL = 1
|
||||||
|
|
||||||
|
CONSTANT_S = { \
|
||||||
|
#parsing constants
|
||||||
|
WHITE : "whitespace", \
|
||||||
|
COMMENT : "comment", \
|
||||||
|
USERFLAG : "userspace flag", \
|
||||||
|
CLASS : "class definition", \
|
||||||
|
COMMON : "common definition", \
|
||||||
|
INHERITS : "inherits definition", \
|
||||||
|
OPENB : "'{'", \
|
||||||
|
VECTOR : "access vector definition", \
|
||||||
|
CLOSEB : "'}'", \
|
||||||
|
SID : "security identifier", \
|
||||||
|
EOF : "end of file", \
|
||||||
|
#generation constants
|
||||||
|
USERSPACE : "userspace mode", \
|
||||||
|
KERNEL : "kernel mode", \
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, warn = True):
|
||||||
|
self.WARN = warn
|
||||||
|
self.autogen = "/* This file is automatically generated. Do not edit. */\n"
|
||||||
|
self.commons = []
|
||||||
|
self.common = {}
|
||||||
|
self.classes = []
|
||||||
|
self.vectors = []
|
||||||
|
self.vector = {}
|
||||||
|
self.userspace = {}
|
||||||
|
self.sids = []
|
||||||
|
self.inherits = {}
|
||||||
|
|
||||||
|
def warning(self, msg):
|
||||||
|
'''
|
||||||
|
Prints a warning message out to stderr if warnings are enabled.
|
||||||
|
'''
|
||||||
|
if self.WARN: sys.stderr.write("Warning: %s\n" % msg)
|
||||||
|
|
||||||
|
def parseClasses(self, path):
|
||||||
|
'''
|
||||||
|
Parses security class definitions from the given path.
|
||||||
|
'''
|
||||||
|
classes = []
|
||||||
|
input = open(path, 'r')
|
||||||
|
|
||||||
|
number = 0
|
||||||
|
for line in input:
|
||||||
|
number += 1
|
||||||
|
m = self.COMMENT.search(line)
|
||||||
|
if m: continue
|
||||||
|
|
||||||
|
m = self.WHITE.search(line)
|
||||||
|
if m: continue
|
||||||
|
|
||||||
|
m = self.CLASS.search(line)
|
||||||
|
if m:
|
||||||
|
g = m.groupdict()
|
||||||
|
c = g['name']
|
||||||
|
if c in classes: raise DuplicateError, (self.CLASS, path, number, c)
|
||||||
|
classes.append(c)
|
||||||
|
if self.USERFLAG.search(line):
|
||||||
|
self.userspace[c] = True
|
||||||
|
continue
|
||||||
|
|
||||||
|
raise ParseError, ("data. Was expecting either a comment, whitespace, or class definition. ", path, number)
|
||||||
|
|
||||||
|
self.classes = classes
|
||||||
|
return classes
|
||||||
|
|
||||||
|
def parseSids(self, path):
|
||||||
|
'''
|
||||||
|
Parses initial SID definitions from the given path.
|
||||||
|
'''
|
||||||
|
|
||||||
|
sids = []
|
||||||
|
input = open(path, 'r')
|
||||||
|
for line in input:
|
||||||
|
m = self.COMMENT.search(line)
|
||||||
|
if m: continue
|
||||||
|
|
||||||
|
m = self.WHITE.search(line)
|
||||||
|
if m: continue
|
||||||
|
|
||||||
|
m = self.SID.search(line)
|
||||||
|
if m:
|
||||||
|
g = m.groupdict()
|
||||||
|
s = g['name']
|
||||||
|
if s in sids: raise DuplicateError, (self.SID, path, number, s)
|
||||||
|
sids.append(s)
|
||||||
|
continue
|
||||||
|
|
||||||
|
raise ParseError, ("data. Was expecting either a comment, whitespace, or security identifier. ", path, number)
|
||||||
|
|
||||||
|
self.sids = sids
|
||||||
|
return sids
|
||||||
|
|
||||||
|
def parseVectors(self, path):
|
||||||
|
'''
|
||||||
|
Parses access vector definitions from the given path.
|
||||||
|
'''
|
||||||
|
vectors = []
|
||||||
|
vector = {}
|
||||||
|
commons = []
|
||||||
|
common = {}
|
||||||
|
inherits = {}
|
||||||
|
input = open(path, 'r')
|
||||||
|
|
||||||
|
# states
|
||||||
|
NONE = 0
|
||||||
|
COMMON = 1
|
||||||
|
CLASS = 2
|
||||||
|
INHERIT = 3
|
||||||
|
OPEN = 4
|
||||||
|
|
||||||
|
state = NONE
|
||||||
|
state2 = NONE
|
||||||
|
number = 0
|
||||||
|
for line in input:
|
||||||
|
number += 1
|
||||||
|
m = self.COMMENT.search(line)
|
||||||
|
if m: continue
|
||||||
|
|
||||||
|
m = self.WHITE.search(line)
|
||||||
|
if m:
|
||||||
|
if state == INHERIT:
|
||||||
|
state = NONE
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self.COMMON.search(line)
|
||||||
|
if m:
|
||||||
|
if state != NONE: raise ParseError, (self.COMMON, path, number)
|
||||||
|
g = m.groupdict()
|
||||||
|
c = g['name']
|
||||||
|
if c in commons: raise DuplicateError, (self.COMMON, path, number, c)
|
||||||
|
commons.append(c)
|
||||||
|
common[c] = []
|
||||||
|
state = COMMON
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self.CLASS.search(line)
|
||||||
|
if m:
|
||||||
|
if state != NONE: raise ParseError, (self.CLASS, number)
|
||||||
|
g = m.groupdict()
|
||||||
|
c = g['name']
|
||||||
|
if c in vectors: raise DuplicateError, (self.CLASS, path, number, c)
|
||||||
|
if c not in self.classes: raise UndefinedError, (self.CLASS, path, number, c)
|
||||||
|
vectors.append(c)
|
||||||
|
vector[c] = []
|
||||||
|
state = CLASS
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self.INHERITS.search(line)
|
||||||
|
if m:
|
||||||
|
if state != CLASS: raise ParseError, (self.INHERITS, number)
|
||||||
|
g = m.groupdict()
|
||||||
|
i = g['name']
|
||||||
|
if c in inherits: raise DuplicateError, (self.INHERITS, path, number, c)
|
||||||
|
if i not in common: raise UndefinedError, (self.COMMON, path, number, i)
|
||||||
|
inherits[c] = i
|
||||||
|
state = INHERIT
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self.OPENB.search(line)
|
||||||
|
if m:
|
||||||
|
if (state != CLASS \
|
||||||
|
and state != INHERIT \
|
||||||
|
and state != COMMON) \
|
||||||
|
or state2 != NONE:
|
||||||
|
raise ParseError, (self.OPENB, path, number)
|
||||||
|
state2 = OPEN
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self.VECTOR.search(line)
|
||||||
|
if m:
|
||||||
|
if state2 != OPEN: raise ParseError, (self.VECTOR, path, number)
|
||||||
|
g = m.groupdict()
|
||||||
|
v = g['name']
|
||||||
|
if state == CLASS or state == INHERIT:
|
||||||
|
if v in vector[c]: raise DuplicateError, (self.VECTOR, path, number, v)
|
||||||
|
vector[c].append(v)
|
||||||
|
elif state == COMMON:
|
||||||
|
if v in common[c]: raise DuplicateError, (self.VECTOR, path, number, v)
|
||||||
|
common[c].append(v)
|
||||||
|
continue
|
||||||
|
|
||||||
|
m = self.CLOSEB.search(line)
|
||||||
|
if m:
|
||||||
|
if state2 != OPEN: raise ParseError, (self.CLOSEB, path, number)
|
||||||
|
state = NONE
|
||||||
|
state2 = NONE
|
||||||
|
c = None
|
||||||
|
continue
|
||||||
|
|
||||||
|
raise ParseError, ("data", path, number)
|
||||||
|
|
||||||
|
if state != NONE and state2 != NONE: raise ParseError, (self.EOF, path, number)
|
||||||
|
|
||||||
|
cvdiff = set(self.classes) - set(vectors)
|
||||||
|
if cvdiff: raise UnusedError, "Not all security classes were used in access vectors: %s" % cvdiff # the inverse of this will be caught as an undefined class error
|
||||||
|
|
||||||
|
self.commons = commons
|
||||||
|
self.common = common
|
||||||
|
self.vectors = vectors
|
||||||
|
self.vector = vector
|
||||||
|
self.inherits = inherits
|
||||||
|
return vector
|
||||||
|
|
||||||
|
def createHeaders(self, path, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
Creates the C header files in the specified MODE and outputs
|
||||||
|
them to give PATH.
|
||||||
|
'''
|
||||||
|
headers = { \
|
||||||
|
'av_inherit.h' : self.createAvInheritH(mode), \
|
||||||
|
'av_perm_to_string.h' : self.createAvPermToStringH(mode), \
|
||||||
|
'av_permissions.h' : self.createAvPermissionsH(mode), \
|
||||||
|
'class_to_string.h' : self.createClassToStringH(mode), \
|
||||||
|
'common_perm_to_string.h' : self.createCommonPermToStringH(mode), \
|
||||||
|
'flask.h' : self.createFlaskH(mode), \
|
||||||
|
'initial_sid_to_string.h' : self.createInitialSidToStringH(mode) \
|
||||||
|
}
|
||||||
|
|
||||||
|
for key, value in headers.items():
|
||||||
|
of = open(os.path.join(path, key), 'w')
|
||||||
|
of.writelines(value)
|
||||||
|
of.close()
|
||||||
|
|
||||||
|
def createUL(self, count):
|
||||||
|
fields = [1, 2, 4, 8]
|
||||||
|
return "0x%08xUL" % (fields[count % 4] << 4 * (count / 4))
|
||||||
|
|
||||||
|
def createAvInheritH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
for c in self.vectors:
|
||||||
|
if self.inherits.has_key(c):
|
||||||
|
i = self.inherits[c]
|
||||||
|
count = len(self.common[i])
|
||||||
|
user = self.userspace.has_key(c)
|
||||||
|
if mode == self.KERNEL and user:
|
||||||
|
results.append(" S_(0, 0, 0)\n")
|
||||||
|
else:
|
||||||
|
results.append(" S_(SECCLASS_%s, %s, %s)\n" % (c.upper(), i, self.createUL(count)))
|
||||||
|
return results
|
||||||
|
|
||||||
|
def createAvPermToStringH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
for c in self.vectors:
|
||||||
|
for p in self.vector[c]:
|
||||||
|
user = self.userspace.has_key(c)
|
||||||
|
if (mode == self.KERNEL and not user) or (mode == self.USERSPACE):
|
||||||
|
results.append(" S_(SECCLASS_%s, %s__%s, \"%s\")\n" % (c.upper(), c.upper(), p.upper(), p))
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def createAvPermissionsH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
|
||||||
|
width = 57
|
||||||
|
count = 0
|
||||||
|
for common in self.commons:
|
||||||
|
count = 0
|
||||||
|
shift = 0
|
||||||
|
for p in self.common[common]:
|
||||||
|
columnA = "#define COMMON_%s__%s " % (common.upper(), p.upper())
|
||||||
|
columnA += "".join([" " for i in range(width - len(columnA))])
|
||||||
|
results.append("%s%s\n" % (columnA, self.createUL(count)))
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
width = 50 # broken for old tools whitespace
|
||||||
|
for c in self.vectors:
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
ps = []
|
||||||
|
if self.inherits.has_key(c):
|
||||||
|
ps += self.common[self.inherits[c]]
|
||||||
|
ps += self.vector[c]
|
||||||
|
for p in ps:
|
||||||
|
columnA = "#define %s__%s " % (c.upper(), p.upper())
|
||||||
|
columnA += "".join([" " for i in range(width - len(columnA))])
|
||||||
|
user = self.userspace.has_key(c)
|
||||||
|
if not (mode == self.KERNEL and user):
|
||||||
|
results.append("%s%s\n" % (columnA, self.createUL(count)))
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def createClassToStringH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
results.append("/*\n * Security object class definitions\n */\n")
|
||||||
|
results.append(" S_(NULL)\n")
|
||||||
|
for c in self.classes:
|
||||||
|
user = self.userspace.has_key(c)
|
||||||
|
if mode == self.KERNEL and user:
|
||||||
|
results.append(" S_(NULL)\n")
|
||||||
|
else:
|
||||||
|
results.append(" S_(\"%s\")\n" % c)
|
||||||
|
return results
|
||||||
|
|
||||||
|
def createCommonPermToStringH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
for common in self.commons:
|
||||||
|
results.append("TB_(common_%s_perm_to_string)\n" % common)
|
||||||
|
for p in self.common[common]:
|
||||||
|
results.append(" S_(\"%s\")\n" % p)
|
||||||
|
results.append("TE_(common_%s_perm_to_string)\n\n" % common)
|
||||||
|
return results
|
||||||
|
|
||||||
|
def createFlaskH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
results.append("#ifndef _SELINUX_FLASK_H_\n")
|
||||||
|
results.append("#define _SELINUX_FLASK_H_\n")
|
||||||
|
results.append("\n")
|
||||||
|
results.append("/*\n")
|
||||||
|
results.append(" * Security object class definitions\n")
|
||||||
|
results.append(" */\n")
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
width = 57
|
||||||
|
for c in self.classes:
|
||||||
|
count += 1
|
||||||
|
columnA = "#define SECCLASS_%s " % c.upper()
|
||||||
|
columnA += "".join([" " for i in range(width - len(columnA))])
|
||||||
|
user = self.userspace.has_key(c)
|
||||||
|
if not (mode == self.KERNEL and user):
|
||||||
|
results.append("%s%d\n" % (columnA, count))
|
||||||
|
|
||||||
|
results.append("\n")
|
||||||
|
results.append("/*\n")
|
||||||
|
results.append(" * Security identifier indices for initial entities\n")
|
||||||
|
results.append(" */\n")
|
||||||
|
|
||||||
|
count = 0
|
||||||
|
width = 56 # broken for old tools whitespace
|
||||||
|
for s in self.sids:
|
||||||
|
count += 1
|
||||||
|
columnA = "#define SECINITSID_%s " % s.upper()
|
||||||
|
columnA += "".join([" " for i in range(width - len(columnA))])
|
||||||
|
results.append("%s%d\n" % (columnA, count))
|
||||||
|
|
||||||
|
results.append("\n")
|
||||||
|
columnA = "#define SECINITSID_NUM "
|
||||||
|
columnA += "".join([" " for i in range(width - len(columnA))])
|
||||||
|
results.append("%s%d\n" % (columnA, count))
|
||||||
|
|
||||||
|
results.append("\n")
|
||||||
|
results.append("#endif\n")
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def createInitialSidToStringH(self, mode = USERSPACE):
|
||||||
|
'''
|
||||||
|
'''
|
||||||
|
results = []
|
||||||
|
results.append(self.autogen)
|
||||||
|
results.append("static char *initial_sid_to_string[] =\n")
|
||||||
|
results.append("{\n")
|
||||||
|
results.append(" \"null\",\n")
|
||||||
|
for s in self.sids:
|
||||||
|
results.append(" \"%s\",\n" % s)
|
||||||
|
results.append("};\n")
|
||||||
|
results.append("\n")
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
'''
|
||||||
|
Returns the usage string.
|
||||||
|
'''
|
||||||
|
usage = 'Usage: %s -a ACCESS_VECTORS -i INITIAL_SIDS -s SECURITY_CLASSES -o OUTPUT_DIRECTORY -k|-u [-w]\n' % os.path.basename(sys.argv[0])
|
||||||
|
usage += '\n'
|
||||||
|
usage += ' -a --access_vectors\taccess vector definitions\n'
|
||||||
|
usage += ' -i --initial_sids\tinitial sid definitions\n'
|
||||||
|
usage += ' -s --security_classes\tsecurity class definitions\n'
|
||||||
|
usage += ' -o --output\toutput directory for generated files\n'
|
||||||
|
usage += ' -k --kernel\toutput mode set to kernel (kernel headers contain empty blocks for all classes specified with # userspace in the security_classes file)\n'
|
||||||
|
usage += ' -u --user\toutput mode set to userspace\n'
|
||||||
|
usage += ' -w --nowarnings\tsupresses output of warning messages\n'
|
||||||
|
return usage
|
||||||
|
|
||||||
|
########## MAIN ##########
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
# Parse command line args
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], 'a:i:s:o:kuwh', ['access_vectors=', 'initial_sids=', 'security_classes=', 'output=', 'kernel', 'user', 'nowarnings', 'help'])
|
||||||
|
except getopt.GetoptError:
|
||||||
|
print(usage())
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
avec = None
|
||||||
|
isid = None
|
||||||
|
secc = None
|
||||||
|
outd = None
|
||||||
|
mode = None
|
||||||
|
warn = True
|
||||||
|
for o, a in opts:
|
||||||
|
if o in ('-h', '--help'):
|
||||||
|
print(usage())
|
||||||
|
sys.exit(0)
|
||||||
|
elif o in ('-a', '--access_vectors'):
|
||||||
|
avec = a
|
||||||
|
elif o in ('-i', '--initial_sids'):
|
||||||
|
isid = a
|
||||||
|
elif o in ('-s', '--security_classes'):
|
||||||
|
secc = a
|
||||||
|
elif o in ('-o', '--output'):
|
||||||
|
outd = a
|
||||||
|
elif o in ('-k', '--kernel'):
|
||||||
|
if mode != None:
|
||||||
|
print(usage())
|
||||||
|
sys.exit(2)
|
||||||
|
mode = Flask.KERNEL
|
||||||
|
elif o in ('-u', '--user'):
|
||||||
|
if mode != None:
|
||||||
|
print(usage())
|
||||||
|
sys.exit(2)
|
||||||
|
mode = Flask.USERSPACE
|
||||||
|
elif o in ('-w', '--nowarnings'):
|
||||||
|
warn = False
|
||||||
|
else:
|
||||||
|
print(usage())
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
if avec == None or \
|
||||||
|
isid == None or \
|
||||||
|
secc == None or \
|
||||||
|
outd == None:
|
||||||
|
print(usage())
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
try:
|
||||||
|
f = Flask(warn)
|
||||||
|
f.parseSids(isid)
|
||||||
|
f.parseClasses(secc)
|
||||||
|
f.parseVectors(avec)
|
||||||
|
f.createHeaders(outd, mode)
|
||||||
|
except Exception, e:
|
||||||
|
print(e)
|
||||||
|
sys.exit(2)
|
@ -1,224 +0,0 @@
|
|||||||
#!/bin/sh -
|
|
||||||
#
|
|
||||||
|
|
||||||
# FLASK
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
awk=$1
|
|
||||||
shift
|
|
||||||
|
|
||||||
# output files
|
|
||||||
av_permissions="av_permissions.h"
|
|
||||||
av_inherit="av_inherit.h"
|
|
||||||
common_perm_to_string="common_perm_to_string.h"
|
|
||||||
av_perm_to_string="av_perm_to_string.h"
|
|
||||||
|
|
||||||
cat $* | $awk "
|
|
||||||
BEGIN {
|
|
||||||
outfile = \"$av_permissions\"
|
|
||||||
inheritfile = \"$av_inherit\"
|
|
||||||
cpermfile = \"$common_perm_to_string\"
|
|
||||||
avpermfile = \"$av_perm_to_string\"
|
|
||||||
"'
|
|
||||||
nextstate = "COMMON_OR_AV";
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > outfile;
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > inheritfile;
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > cpermfile;
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > avpermfile;
|
|
||||||
;
|
|
||||||
}
|
|
||||||
/^[ \t]*#/ {
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
$1 == "common" {
|
|
||||||
if (nextstate != "COMMON_OR_AV")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected COMMON definition on line %d\n", NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($2 in common_defined)
|
|
||||||
{
|
|
||||||
printf("Duplicate COMMON definition for %s on line %d.\n", $2, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
common_defined[$2] = 1;
|
|
||||||
|
|
||||||
tclass = $2;
|
|
||||||
common_name = $2;
|
|
||||||
permission = 1;
|
|
||||||
|
|
||||||
printf("TB_(common_%s_perm_to_string)\n", $2) > cpermfile;
|
|
||||||
|
|
||||||
nextstate = "COMMON-OPENBRACKET";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
$1 == "class" {
|
|
||||||
if (nextstate != "COMMON_OR_AV" &&
|
|
||||||
nextstate != "CLASS_OR_CLASS-OPENBRACKET")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected class definition on line %d\n", NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
tclass = $2;
|
|
||||||
|
|
||||||
if (tclass in av_defined)
|
|
||||||
{
|
|
||||||
printf("Duplicate access vector definition for %s on line %d\n", tclass, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
av_defined[tclass] = 1;
|
|
||||||
|
|
||||||
inherits = "";
|
|
||||||
permission = 1;
|
|
||||||
|
|
||||||
nextstate = "INHERITS_OR_CLASS-OPENBRACKET";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
$1 == "inherits" {
|
|
||||||
if (nextstate != "INHERITS_OR_CLASS-OPENBRACKET")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected INHERITS definition on line %d\n", NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!($2 in common_defined))
|
|
||||||
{
|
|
||||||
printf("COMMON %s is not defined (line %d).\n", $2, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
inherits = $2;
|
|
||||||
permission = common_base[$2];
|
|
||||||
|
|
||||||
for (combined in common_perms)
|
|
||||||
{
|
|
||||||
split(combined,separate, SUBSEP);
|
|
||||||
if (separate[1] == inherits)
|
|
||||||
{
|
|
||||||
inherited_perms[common_perms[combined]] = separate[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
j = 1;
|
|
||||||
for (i in inherited_perms) {
|
|
||||||
ind[j] = i + 0;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
n = asort(ind);
|
|
||||||
for (i = 1; i <= n; i++) {
|
|
||||||
perm = inherited_perms[ind[i]];
|
|
||||||
printf("#define %s__%s", toupper(tclass), toupper(perm)) > outfile;
|
|
||||||
spaces = 40 - (length(perm) + length(tclass));
|
|
||||||
if (spaces < 1)
|
|
||||||
spaces = 1;
|
|
||||||
for (j = 0; j < spaces; j++)
|
|
||||||
printf(" ") > outfile;
|
|
||||||
printf("0x%08xUL\n", ind[i]) > outfile;
|
|
||||||
}
|
|
||||||
for (i in ind) delete ind[i];
|
|
||||||
for (i in inherited_perms) delete inherited_perms[i];
|
|
||||||
|
|
||||||
printf(" S_(SECCLASS_%s, %s, 0x%08xUL)\n", toupper(tclass), inherits, permission) > inheritfile;
|
|
||||||
|
|
||||||
nextstate = "CLASS_OR_CLASS-OPENBRACKET";
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
$1 == "{" {
|
|
||||||
if (nextstate != "INHERITS_OR_CLASS-OPENBRACKET" &&
|
|
||||||
nextstate != "CLASS_OR_CLASS-OPENBRACKET" &&
|
|
||||||
nextstate != "COMMON-OPENBRACKET")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected { on line %d\n", NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextstate == "INHERITS_OR_CLASS-OPENBRACKET")
|
|
||||||
nextstate = "CLASS-CLOSEBRACKET";
|
|
||||||
|
|
||||||
if (nextstate == "CLASS_OR_CLASS-OPENBRACKET")
|
|
||||||
nextstate = "CLASS-CLOSEBRACKET";
|
|
||||||
|
|
||||||
if (nextstate == "COMMON-OPENBRACKET")
|
|
||||||
nextstate = "COMMON-CLOSEBRACKET";
|
|
||||||
}
|
|
||||||
/[a-z][a-z_]*/ {
|
|
||||||
if (nextstate != "COMMON-CLOSEBRACKET" &&
|
|
||||||
nextstate != "CLASS-CLOSEBRACKET")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected symbol %s on line %d\n", $1, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextstate == "COMMON-CLOSEBRACKET")
|
|
||||||
{
|
|
||||||
if ((common_name,$1) in common_perms)
|
|
||||||
{
|
|
||||||
printf("Duplicate permission %s for common %s on line %d.\n", $1, common_name, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
common_perms[common_name,$1] = permission;
|
|
||||||
|
|
||||||
printf("#define COMMON_%s__%s", toupper(common_name), toupper($1)) > outfile;
|
|
||||||
|
|
||||||
printf(" S_(\"%s\")\n", $1) > cpermfile;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((tclass,$1) in av_perms)
|
|
||||||
{
|
|
||||||
printf("Duplicate permission %s for %s on line %d.\n", $1, tclass, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
av_perms[tclass,$1] = permission;
|
|
||||||
|
|
||||||
if (inherits != "")
|
|
||||||
{
|
|
||||||
if ((inherits,$1) in common_perms)
|
|
||||||
{
|
|
||||||
printf("Permission %s in %s on line %d conflicts with common permission.\n", $1, tclass, inherits, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("#define %s__%s", toupper(tclass), toupper($1)) > outfile;
|
|
||||||
|
|
||||||
printf(" S_(SECCLASS_%s, %s__%s, \"%s\")\n", toupper(tclass), toupper(tclass), toupper($1), $1) > avpermfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
spaces = 40 - (length($1) + length(tclass));
|
|
||||||
if (spaces < 1)
|
|
||||||
spaces = 1;
|
|
||||||
|
|
||||||
for (i = 0; i < spaces; i++)
|
|
||||||
printf(" ") > outfile;
|
|
||||||
printf("0x%08xUL\n", permission) > outfile;
|
|
||||||
permission = permission * 2;
|
|
||||||
}
|
|
||||||
$1 == "}" {
|
|
||||||
if (nextstate != "CLASS-CLOSEBRACKET" &&
|
|
||||||
nextstate != "COMMON-CLOSEBRACKET")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected } on line %d\n", NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextstate == "COMMON-CLOSEBRACKET")
|
|
||||||
{
|
|
||||||
common_base[common_name] = permission;
|
|
||||||
printf("TE_(common_%s_perm_to_string)\n\n", common_name) > cpermfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
nextstate = "COMMON_OR_AV";
|
|
||||||
}
|
|
||||||
END {
|
|
||||||
if (nextstate != "COMMON_OR_AV" && nextstate != "CLASS_OR_CLASS-OPENBRACKET")
|
|
||||||
printf("Parse error: Unexpected end of file\n");
|
|
||||||
|
|
||||||
}'
|
|
||||||
|
|
||||||
# FLASK
|
|
@ -1,95 +0,0 @@
|
|||||||
#!/bin/sh -
|
|
||||||
#
|
|
||||||
|
|
||||||
# FLASK
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
awk=$1
|
|
||||||
shift 1
|
|
||||||
|
|
||||||
# output file
|
|
||||||
output_file="flask.h"
|
|
||||||
debug_file="class_to_string.h"
|
|
||||||
debug_file2="initial_sid_to_string.h"
|
|
||||||
|
|
||||||
cat $* | $awk "
|
|
||||||
BEGIN {
|
|
||||||
outfile = \"$output_file\"
|
|
||||||
debugfile = \"$debug_file\"
|
|
||||||
debugfile2 = \"$debug_file2\"
|
|
||||||
"'
|
|
||||||
nextstate = "CLASS";
|
|
||||||
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > outfile;
|
|
||||||
|
|
||||||
printf("#ifndef _SELINUX_FLASK_H_\n") > outfile;
|
|
||||||
printf("#define _SELINUX_FLASK_H_\n") > outfile;
|
|
||||||
printf("\n/*\n * Security object class definitions\n */\n") > outfile;
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > debugfile;
|
|
||||||
printf("/*\n * Security object class definitions\n */\n") > debugfile;
|
|
||||||
printf(" S_(\"null\")\n") > debugfile;
|
|
||||||
printf("/* This file is automatically generated. Do not edit. */\n") > debugfile2;
|
|
||||||
printf("static char *initial_sid_to_string[] =\n{\n") > debugfile2;
|
|
||||||
printf(" \"null\",\n") > debugfile2;
|
|
||||||
}
|
|
||||||
/^[ \t]*#/ {
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
$1 == "class" {
|
|
||||||
if (nextstate != "CLASS")
|
|
||||||
{
|
|
||||||
printf("Parse error: Unexpected class definition on line %d\n", NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($2 in class_found)
|
|
||||||
{
|
|
||||||
printf("Duplicate class definition for %s on line %d.\n", $2, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
class_found[$2] = 1;
|
|
||||||
|
|
||||||
class_value++;
|
|
||||||
|
|
||||||
printf("#define SECCLASS_%s", toupper($2)) > outfile;
|
|
||||||
for (i = 0; i < 40 - length($2); i++)
|
|
||||||
printf(" ") > outfile;
|
|
||||||
printf("%d\n", class_value) > outfile;
|
|
||||||
|
|
||||||
printf(" S_(\"%s\")\n", $2) > debugfile;
|
|
||||||
}
|
|
||||||
$1 == "sid" {
|
|
||||||
if (nextstate == "CLASS")
|
|
||||||
{
|
|
||||||
nextstate = "SID";
|
|
||||||
printf("\n/*\n * Security identifier indices for initial entities\n */\n") > outfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($2 in sid_found)
|
|
||||||
{
|
|
||||||
printf("Duplicate SID definition for %s on line %d.\n", $2, NR);
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
sid_found[$2] = 1;
|
|
||||||
sid_value++;
|
|
||||||
|
|
||||||
printf("#define SECINITSID_%s", toupper($2)) > outfile;
|
|
||||||
for (i = 0; i < 37 - length($2); i++)
|
|
||||||
printf(" ") > outfile;
|
|
||||||
printf("%d\n", sid_value) > outfile;
|
|
||||||
printf(" \"%s\",\n", $2) > debugfile2;
|
|
||||||
}
|
|
||||||
END {
|
|
||||||
if (nextstate != "SID")
|
|
||||||
printf("Parse error: Unexpected end of file\n");
|
|
||||||
|
|
||||||
printf("\n#define SECINITSID_NUM") > outfile;
|
|
||||||
for (i = 0; i < 34; i++)
|
|
||||||
printf(" ") > outfile;
|
|
||||||
printf("%d\n", sid_value) > outfile;
|
|
||||||
printf("\n#endif\n") > outfile;
|
|
||||||
printf("};\n\n") > debugfile2;
|
|
||||||
}'
|
|
||||||
|
|
||||||
# FLASK
|
|
Loading…
Reference in New Issue
Block a user