Chris PeBenito e9b004
#!/usr/bin/python -E
Chris PeBenito e9b004
#
Chris PeBenito e9b004
# Author(s):	Caleb Case <ccase@tresys.com>
Chris PeBenito e9b004
#
Chris PeBenito e9b004
# Adapted from the bash/awk scripts mkflask.sh and mkaccess_vector.sh
Chris PeBenito e9b004
#
Chris PeBenito e9b004
Chris PeBenito e9b004
import getopt
Chris PeBenito e9b004
import os
Chris PeBenito e9b004
import sys
Chris PeBenito e9b004
import re
Chris PeBenito e9b004
Chris PeBenito e9b004
class ParseError(Exception):
Chris PeBenito e9b004
	def __init__(self, type, file, line):
Chris PeBenito e9b004
		self.type = type
Chris PeBenito e9b004
		self.file = file
Chris PeBenito e9b004
		self.line = line
Chris PeBenito e9b004
	def __str__(self):
Chris PeBenito e9b004
		typeS = self.type
Chris PeBenito e9b004
		if type(self.type) is not str: typeS = Flask.CONSTANT_S[self.type]
Chris PeBenito e9b004
		return "Parse Error: Unexpected %s on line %d of %s." % (typeS, self.line, self.file)
Chris PeBenito e9b004
Chris PeBenito e9b004
class DuplicateError(Exception):
Chris PeBenito e9b004
	def __init__(self, type, file, line, symbol):
Chris PeBenito e9b004
		self.type = type
Chris PeBenito e9b004
		self.file = file
Chris PeBenito e9b004
		self.line = line
Chris PeBenito e9b004
		self.symbol = symbol
Chris PeBenito e9b004
	def __str__(self):
Chris PeBenito e9b004
		typeS = self.type
Chris PeBenito e9b004
		if type(self.type) is not str: typeS = Flask.CONSTANT_S[self.type]
Chris PeBenito e9b004
		return "Duplicate Error: Duplicate %s '%s' on line %d of %s." % (typeS, self.symbol, self.line, self.file)
Chris PeBenito e9b004
Chris PeBenito e9b004
class UndefinedError(Exception):
Chris PeBenito e9b004
	def __init__(self, type, file, line, symbol):
Chris PeBenito e9b004
		self.type = type
Chris PeBenito e9b004
		self.file = file
Chris PeBenito e9b004
		self.line = line
Chris PeBenito e9b004
		self.symbol = symbol
Chris PeBenito e9b004
	def __str__(self):
Chris PeBenito e9b004
		typeS = self.type
Chris PeBenito e9b004
		if type(self.type) is not str: typeS = Flask.CONSTANT_S[self.type]
Chris PeBenito e9b004
		return "Undefined Error: %s '%s' is not defined but used on line %d of %s." % (typeS, self.symbol, self.line, self.file)
Chris PeBenito e9b004
Chris PeBenito e9b004
class UnusedError(Exception):
Chris PeBenito e9b004
	def __init__(self, info):
Chris PeBenito e9b004
		self.info = info
Chris PeBenito e9b004
	def __str__(self):
Chris PeBenito e9b004
		return "Unused Error: %s" % self.info
Chris PeBenito e9b004
Chris PeBenito e9b004
class Flask:
Chris PeBenito e9b004
	'''
Chris PeBenito e9b004
	FLASK container class with utilities for parsing definition
Chris PeBenito e9b004
	files and creating c header files.
Chris PeBenito e9b004
	'''
Chris PeBenito e9b004
Chris PeBenito e9b004
	#Constants used in definitions parsing.
Chris PeBenito e9b004
	WHITE    = re.compile(r'^\s*$')
Chris PeBenito e9b004
	COMMENT  = re.compile(r'^\s*#')
Chris PeBenito e9b004
	USERFLAG = re.compile(r'# userspace')
Chris PeBenito e9b004
	CLASS    = re.compile(r'^class (?P<name>\w+)')
Chris PeBenito e9b004
	COMMON   = re.compile(r'^common (?P<name>\w+)')
Chris PeBenito e9b004
	INHERITS = re.compile(r'^inherits (?P<name>\w+)')
Chris PeBenito e9b004
	OPENB    = re.compile(r'^{')
Chris PeBenito e9b004
	VECTOR   = re.compile(r'^\s*(?P<name>\w+)')
Chris PeBenito e9b004
	CLOSEB   = re.compile(r'^}')
Chris PeBenito e9b004
	SID      = re.compile(r'^sid (?P<name>\w+)')
Chris PeBenito e9b004
	EOF      = "end of file"
Chris PeBenito e9b004
Chris PeBenito e9b004
	#Constants used in header generation.
Chris PeBenito e9b004
	USERSPACE = 0
Chris PeBenito e9b004
	KERNEL    = 1
Chris PeBenito e9b004
Chris PeBenito e9b004
	CONSTANT_S = { \
Chris PeBenito e9b004
		#parsing constants
Chris PeBenito e9b004
		WHITE    : "whitespace", \
Chris PeBenito e9b004
		COMMENT  : "comment", \
Chris PeBenito e9b004
		USERFLAG : "userspace flag", \
Chris PeBenito e9b004
		CLASS    : "class definition", \
Chris PeBenito e9b004
		COMMON   : "common definition", \
Chris PeBenito e9b004
		INHERITS : "inherits definition", \
Chris PeBenito e9b004
		OPENB    : "'{'", \
Chris PeBenito e9b004
		VECTOR   : "access vector definition", \
Chris PeBenito e9b004
		CLOSEB   : "'}'", \
Chris PeBenito e9b004
		SID      : "security identifier", \
Chris PeBenito e9b004
		EOF      : "end of file", \
Chris PeBenito e9b004
		#generation constants
Chris PeBenito e9b004
		USERSPACE : "userspace mode", \
Chris PeBenito e9b004
		KERNEL    : "kernel mode", \
Chris PeBenito e9b004
	}
Chris PeBenito e9b004
Chris PeBenito e9b004
	def __init__(self, warn = True):
Chris PeBenito e9b004
		self.WARN = warn
Chris PeBenito e9b004
		self.autogen   = "/* This file is automatically generated.  Do not edit. */\n"
Chris PeBenito e9b004
		self.commons   = []
Chris PeBenito e9b004
		self.common    = {}
Chris PeBenito e9b004
		self.classes   = []
Chris PeBenito e9b004
		self.vectors   = []
Chris PeBenito e9b004
		self.vector    = {}
Chris PeBenito e9b004
		self.userspace = {}
Chris PeBenito e9b004
		self.sids      = []
Chris PeBenito e9b004
		self.inherits  = {}
Chris PeBenito e9b004
	
Chris PeBenito e9b004
	def warning(self, msg):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		Prints a warning message out to stderr if warnings are enabled.
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		if self.WARN: sys.stderr.write("Warning: %s\n" % msg)
Chris PeBenito e9b004
Chris PeBenito e9b004
	def parseClasses(self, path):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		Parses security class definitions from the given path.
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		classes = []
Chris PeBenito e9b004
		input = open(path, 'r')
Chris PeBenito e9b004
Chris PeBenito e9b004
		number = 0
Chris PeBenito e9b004
		for line in input:
Chris PeBenito e9b004
			number += 1
Chris PeBenito e9b004
			m = self.COMMENT.search(line)
Chris PeBenito e9b004
			if m: continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.WHITE.search(line)
Chris PeBenito e9b004
			if m: continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.CLASS.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				g = m.groupdict()
Chris PeBenito e9b004
				c = g['name']
Chris PeBenito e9b004
				if c in classes: raise DuplicateError, (self.CLASS, path, number, c)
Chris PeBenito e9b004
				classes.append(c)
Chris PeBenito e9b004
				if self.USERFLAG.search(line):
Chris PeBenito e9b004
					self.userspace[c] = True
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			raise ParseError, ("data.  Was expecting either a comment, whitespace, or class definition. ", path, number)
Chris PeBenito e9b004
Chris PeBenito e9b004
		self.classes = classes
Chris PeBenito e9b004
		return classes
Chris PeBenito e9b004
Chris PeBenito e9b004
	def parseSids(self, path):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		Parses initial SID definitions from the given path.
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
Chris PeBenito e9b004
		sids = []
Chris PeBenito e9b004
		input = open(path, 'r')
Chris PeBenito e9b004
		for line in input:
Chris PeBenito e9b004
			m = self.COMMENT.search(line)
Chris PeBenito e9b004
			if m: continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.WHITE.search(line)
Chris PeBenito e9b004
			if m: continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.SID.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				g = m.groupdict()
Chris PeBenito e9b004
				s = g['name']
Chris PeBenito e9b004
				if s in sids: raise DuplicateError, (self.SID, path, number, s)
Chris PeBenito e9b004
				sids.append(s)
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
			
Chris PeBenito e9b004
			raise ParseError, ("data. Was expecting either a comment, whitespace, or security identifier. ", path, number)
Chris PeBenito e9b004
Chris PeBenito e9b004
		self.sids = sids
Chris PeBenito e9b004
		return sids
Chris PeBenito e9b004
Chris PeBenito e9b004
	def parseVectors(self, path):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		Parses access vector definitions from the given path.
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		vectors = []
Chris PeBenito e9b004
		vector  = {}
Chris PeBenito e9b004
		commons = []
Chris PeBenito e9b004
		common = {}
Chris PeBenito e9b004
		inherits = {}
Chris PeBenito e9b004
		input = open(path, 'r')
Chris PeBenito e9b004
Chris PeBenito e9b004
		# states
Chris PeBenito e9b004
		NONE    = 0
Chris PeBenito e9b004
		COMMON  = 1
Chris PeBenito e9b004
		CLASS   = 2
Chris PeBenito e9b004
		INHERIT = 3
Chris PeBenito e9b004
		OPEN    = 4
Chris PeBenito e9b004
Chris PeBenito e9b004
		state = NONE
Chris PeBenito e9b004
		state2 = NONE
Chris PeBenito e9b004
		number = 0
Chris PeBenito e9b004
		for line in input:
Chris PeBenito e9b004
			number += 1
Chris PeBenito e9b004
			m = self.COMMENT.search(line)
Chris PeBenito e9b004
			if m: continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.WHITE.search(line)
Chris PeBenito e9b004
			if m: 
Chris PeBenito e9b004
				if state == INHERIT:
Chris PeBenito e9b004
					state = NONE
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.COMMON.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				if state != NONE: raise ParseError, (self.COMMON, path, number)
Chris PeBenito e9b004
				g = m.groupdict()
Chris PeBenito e9b004
				c = g['name']
Chris PeBenito e9b004
				if c in commons: raise DuplicateError, (self.COMMON, path, number, c)
Chris PeBenito e9b004
				commons.append(c)
Chris PeBenito e9b004
				common[c] = []
Chris PeBenito e9b004
				state = COMMON
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.CLASS.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				if state != NONE: raise ParseError, (self.CLASS, number)
Chris PeBenito e9b004
				g = m.groupdict()
Chris PeBenito e9b004
				c = g['name']
Chris PeBenito e9b004
				if c in vectors: raise DuplicateError, (self.CLASS, path, number, c)
Chris PeBenito e9b004
				if c not in self.classes: raise UndefinedError, (self.CLASS, path, number, c)
Chris PeBenito e9b004
				vectors.append(c)
Chris PeBenito e9b004
				vector[c] = []
Chris PeBenito e9b004
				state = CLASS
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
			
Chris PeBenito e9b004
			m = self.INHERITS.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				if state != CLASS: raise ParseError, (self.INHERITS, number)
Chris PeBenito e9b004
				g = m.groupdict()
Chris PeBenito e9b004
				i = g['name']
Chris PeBenito e9b004
				if c in inherits: raise DuplicateError, (self.INHERITS, path, number, c)
Chris PeBenito e9b004
				if i not in common: raise UndefinedError, (self.COMMON, path, number, i)
Chris PeBenito e9b004
				inherits[c] = i
Chris PeBenito e9b004
				state = INHERIT
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.OPENB.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				if (state != CLASS \
Chris PeBenito e9b004
				and state != INHERIT \
Chris PeBenito e9b004
				and state != COMMON) \
Chris PeBenito e9b004
				or state2 != NONE: 
Chris PeBenito e9b004
					raise ParseError, (self.OPENB, path, number)
Chris PeBenito e9b004
				state2 = OPEN
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.VECTOR.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				if state2 != OPEN: raise ParseError, (self.VECTOR, path, number)
Chris PeBenito e9b004
				g = m.groupdict()
Chris PeBenito e9b004
				v = g['name']
Chris PeBenito e9b004
				if state == CLASS or state == INHERIT:
Chris PeBenito e9b004
					if v in vector[c]: raise DuplicateError, (self.VECTOR, path, number, v)
Chris PeBenito e9b004
					vector[c].append(v)
Chris PeBenito e9b004
				elif state == COMMON:
Chris PeBenito e9b004
					if v in common[c]: raise DuplicateError, (self.VECTOR, path, number, v)
Chris PeBenito e9b004
					common[c].append(v)
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
Chris PeBenito e9b004
			m = self.CLOSEB.search(line)
Chris PeBenito e9b004
			if m:
Chris PeBenito e9b004
				if state2 != OPEN: raise ParseError, (self.CLOSEB, path, number)
Chris PeBenito e9b004
				state = NONE
Chris PeBenito e9b004
				state2 = NONE
Chris PeBenito e9b004
				c = None
Chris PeBenito e9b004
				continue
Chris PeBenito e9b004
			
Chris PeBenito e9b004
			raise ParseError, ("data", path, number)
Chris PeBenito e9b004
Chris PeBenito e9b004
		if state != NONE and state2 != NONE: raise ParseError, (self.EOF, path, number)
Chris PeBenito e9b004
Chris PeBenito e9b004
		cvdiff = set(self.classes) - set(vectors)
Chris PeBenito e9b004
		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
Chris PeBenito e9b004
Chris PeBenito e9b004
		self.commons = commons
Chris PeBenito e9b004
		self.common = common
Chris PeBenito e9b004
		self.vectors = vectors
Chris PeBenito e9b004
		self.vector = vector
Chris PeBenito e9b004
		self.inherits = inherits
Chris PeBenito e9b004
		return vector
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createHeaders(self, path, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		Creates the C header files in the specified MODE and outputs
Chris PeBenito e9b004
		them to give PATH.
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		headers = { \
Chris PeBenito e9b004
			'av_inherit.h'            : self.createAvInheritH(mode), \
Chris PeBenito e9b004
			'av_perm_to_string.h'     : self.createAvPermToStringH(mode), \
Chris PeBenito e9b004
			'av_permissions.h'        : self.createAvPermissionsH(mode), \
Chris PeBenito e9b004
			'class_to_string.h'       : self.createClassToStringH(mode), \
Chris PeBenito e9b004
			'common_perm_to_string.h' : self.createCommonPermToStringH(mode), \
Chris PeBenito e9b004
			'flask.h'                 : self.createFlaskH(mode), \
Chris PeBenito e9b004
			'initial_sid_to_string.h' : self.createInitialSidToStringH(mode) \
Chris PeBenito e9b004
		}
Chris PeBenito e9b004
Chris PeBenito e9b004
		for key, value in headers.items():
Chris PeBenito e9b004
			of = open(os.path.join(path, key), 'w')
Chris PeBenito e9b004
			of.writelines(value)
Chris PeBenito e9b004
			of.close()
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createUL(self, count):
Chris PeBenito e9b004
		fields = [1, 2, 4, 8]
Chris PeBenito e9b004
		return "0x%08xUL" % (fields[count % 4] << 4 * (count / 4))
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createAvInheritH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
		for c in self.vectors:
Chris PeBenito e9b004
			if self.inherits.has_key(c):
Chris PeBenito e9b004
				i = self.inherits[c]
Chris PeBenito e9b004
				count = len(self.common[i])
Chris PeBenito e9b004
				user = self.userspace.has_key(c)
Chris PeBenito e9b004
				if mode == self.KERNEL and user:
Chris PeBenito e9b004
					results.append("   S_(0, 0, 0)\n")
Chris PeBenito e9b004
				else:
Chris PeBenito e9b004
					results.append("   S_(SECCLASS_%s, %s, %s)\n" % (c.upper(), i, self.createUL(count)))
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createAvPermToStringH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
		for c in self.vectors:
Chris PeBenito e9b004
			for p in self.vector[c]:
Chris PeBenito e9b004
				user = self.userspace.has_key(c)
Chris PeBenito e9b004
				if (mode == self.KERNEL and not user) or (mode == self.USERSPACE):
Chris PeBenito e9b004
					results.append("   S_(SECCLASS_%s, %s__%s, \"%s\")\n" % (c.upper(), c.upper(), p.upper(), p))
Chris PeBenito e9b004
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createAvPermissionsH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
Chris PeBenito e9b004
		width = 57
Chris PeBenito e9b004
		count = 0
Chris PeBenito e9b004
		for common in self.commons:
Chris PeBenito e9b004
			count = 0
Chris PeBenito e9b004
			shift = 0
Chris PeBenito e9b004
			for p in self.common[common]:
Chris PeBenito e9b004
				columnA = "#define COMMON_%s__%s " % (common.upper(), p.upper())
Chris PeBenito e9b004
				columnA += "".join([" " for i in range(width - len(columnA))])
Chris PeBenito e9b004
				results.append("%s%s\n" % (columnA, self.createUL(count)))
Chris PeBenito e9b004
				count += 1
Chris PeBenito e9b004
Chris PeBenito e9b004
		width = 50 # broken for old tools whitespace
Chris PeBenito e9b004
		for c in self.vectors:
Chris PeBenito e9b004
			count = 0
Chris PeBenito e9b004
Chris PeBenito e9b004
			ps = []
Chris PeBenito e9b004
			if self.inherits.has_key(c):
Chris PeBenito e9b004
				ps += self.common[self.inherits[c]]
Chris PeBenito e9b004
			ps += self.vector[c]
Chris PeBenito e9b004
			for p in ps: 
Chris PeBenito e9b004
				columnA = "#define %s__%s " % (c.upper(), p.upper())
Chris PeBenito e9b004
				columnA += "".join([" " for i in range(width - len(columnA))])
Chris PeBenito e9b004
				user = self.userspace.has_key(c)
Chris PeBenito e9b004
				if not (mode == self.KERNEL and user):
Chris PeBenito e9b004
					results.append("%s%s\n" % (columnA, self.createUL(count)))
Chris PeBenito e9b004
				count += 1
Chris PeBenito e9b004
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createClassToStringH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
		results.append("/*\n * Security object class definitions\n */\n")
Chris PeBenito f88ef6
Chris PeBenito f88ef6
		if mode == self.KERNEL:
Chris PeBenito f88ef6
			results.append("    S_(NULL)\n")
Chris PeBenito f88ef6
		else:
Chris PeBenito f88ef6
			results.append("    S_(\"null\")\n")
Chris PeBenito f88ef6
Chris PeBenito e9b004
		for c in self.classes:
Chris PeBenito e9b004
			user = self.userspace.has_key(c)
Chris PeBenito e9b004
			if mode == self.KERNEL and user:
Chris PeBenito e9b004
				results.append("    S_(NULL)\n")
Chris PeBenito e9b004
			else:
Chris PeBenito e9b004
				results.append("    S_(\"%s\")\n" % c)
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createCommonPermToStringH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
		for common in self.commons:
Chris PeBenito e9b004
			results.append("TB_(common_%s_perm_to_string)\n" % common)
Chris PeBenito e9b004
			for p in self.common[common]:
Chris PeBenito e9b004
				results.append("    S_(\"%s\")\n" % p)
Chris PeBenito e9b004
			results.append("TE_(common_%s_perm_to_string)\n\n" % common)
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
	
Chris PeBenito e9b004
	def createFlaskH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
		results.append("#ifndef _SELINUX_FLASK_H_\n")
Chris PeBenito e9b004
		results.append("#define _SELINUX_FLASK_H_\n")
Chris PeBenito e9b004
		results.append("\n")
Chris PeBenito e9b004
		results.append("/*\n")
Chris PeBenito e9b004
		results.append(" * Security object class definitions\n")
Chris PeBenito e9b004
		results.append(" */\n")
Chris PeBenito e9b004
Chris PeBenito e9b004
		count = 0
Chris PeBenito e9b004
		width = 57
Chris PeBenito e9b004
		for c in self.classes:
Chris PeBenito e9b004
			count += 1
Chris PeBenito e9b004
			columnA = "#define SECCLASS_%s " % c.upper()
Chris PeBenito e9b004
			columnA += "".join([" " for i in range(width - len(columnA))])
Chris PeBenito e9b004
			user = self.userspace.has_key(c)
Chris PeBenito e9b004
			if not (mode == self.KERNEL and user):
Chris PeBenito e9b004
				results.append("%s%d\n" % (columnA, count))
Chris PeBenito e9b004
Chris PeBenito e9b004
		results.append("\n")
Chris PeBenito e9b004
		results.append("/*\n")
Chris PeBenito e9b004
		results.append(" * Security identifier indices for initial entities\n")
Chris PeBenito e9b004
		results.append(" */\n")
Chris PeBenito e9b004
		
Chris PeBenito e9b004
		count = 0
Chris PeBenito e9b004
		width = 56 # broken for old tools whitespace
Chris PeBenito e9b004
		for s in self.sids:
Chris PeBenito e9b004
			count += 1
Chris PeBenito e9b004
			columnA = "#define SECINITSID_%s " % s.upper()
Chris PeBenito e9b004
			columnA += "".join([" " for i in range(width - len(columnA))])
Chris PeBenito e9b004
			results.append("%s%d\n" % (columnA, count))
Chris PeBenito e9b004
Chris PeBenito e9b004
		results.append("\n")
Chris PeBenito e9b004
		columnA = "#define SECINITSID_NUM "
Chris PeBenito e9b004
		columnA += "".join([" " for i in range(width - len(columnA))])
Chris PeBenito e9b004
		results.append("%s%d\n" % (columnA, count))
Chris PeBenito e9b004
Chris PeBenito e9b004
		results.append("\n")
Chris PeBenito e9b004
		results.append("#endif\n")
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
Chris PeBenito e9b004
Chris PeBenito e9b004
Chris PeBenito e9b004
	def createInitialSidToStringH(self, mode = USERSPACE):
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		'''
Chris PeBenito e9b004
		results = []
Chris PeBenito e9b004
		results.append(self.autogen)
Chris PeBenito e9b004
		results.append("static char *initial_sid_to_string[] =\n")
Chris PeBenito e9b004
		results.append("{\n")
Chris PeBenito e9b004
		results.append("    \"null\",\n")
Chris PeBenito e9b004
		for s in self.sids:
Chris PeBenito e9b004
			results.append("    \"%s\",\n" % s)
Chris PeBenito e9b004
		results.append("};\n")
Chris PeBenito e9b004
		results.append("\n")
Chris PeBenito e9b004
Chris PeBenito e9b004
		return results
Chris PeBenito e9b004
Chris PeBenito e9b004
def usage():
Chris PeBenito e9b004
	'''
Chris PeBenito e9b004
	Returns the usage string.
Chris PeBenito e9b004
	'''
Chris PeBenito e9b004
	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])
Chris PeBenito e9b004
	usage += '\n'
Chris PeBenito e9b004
	usage += ' -a --access_vectors\taccess vector definitions\n'
Chris PeBenito e9b004
	usage += ' -i --initial_sids\tinitial sid definitions\n'
Chris PeBenito e9b004
	usage += ' -s --security_classes\tsecurity class definitions\n'
Chris PeBenito e9b004
	usage += ' -o --output\toutput directory for generated files\n'
Chris PeBenito e9b004
	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'
Chris PeBenito e9b004
	usage += ' -u --user\toutput mode set to userspace\n'
Chris PeBenito e9b004
	usage += ' -w --nowarnings\tsupresses output of warning messages\n'
Chris PeBenito e9b004
	return usage
Chris PeBenito e9b004
Chris PeBenito e9b004
########## MAIN ##########
Chris PeBenito e9b004
if __name__ == '__main__':
Chris PeBenito e9b004
	
Chris PeBenito e9b004
	# Parse command line args
Chris PeBenito e9b004
	try:
Chris PeBenito e9b004
		opts, args = getopt.getopt(sys.argv[1:], 'a:i:s:o:kuwh', ['access_vectors=', 'initial_sids=', 'security_classes=', 'output=', 'kernel', 'user', 'nowarnings', 'help'])
Chris PeBenito e9b004
	except getopt.GetoptError:
Chris PeBenito e9b004
		print(usage())
Chris PeBenito e9b004
		sys.exit(2)
Chris PeBenito e9b004
	
Chris PeBenito e9b004
	avec = None
Chris PeBenito e9b004
	isid = None
Chris PeBenito e9b004
	secc = None
Chris PeBenito e9b004
	outd = None
Chris PeBenito e9b004
	mode = None
Chris PeBenito e9b004
	warn = True
Chris PeBenito e9b004
	for o, a in opts:
Chris PeBenito e9b004
		if o in ('-h', '--help'):
Chris PeBenito e9b004
			print(usage())
Chris PeBenito e9b004
			sys.exit(0)
Chris PeBenito e9b004
		elif o in ('-a', '--access_vectors'):
Chris PeBenito e9b004
			avec = a
Chris PeBenito e9b004
		elif o in ('-i', '--initial_sids'):
Chris PeBenito e9b004
			isid = a
Chris PeBenito e9b004
		elif o in ('-s', '--security_classes'):
Chris PeBenito e9b004
			secc = a
Chris PeBenito e9b004
		elif o in ('-o', '--output'):
Chris PeBenito e9b004
			outd = a
Chris PeBenito e9b004
		elif o in ('-k', '--kernel'):
Chris PeBenito e9b004
			if mode != None:
Chris PeBenito e9b004
				print(usage())
Chris PeBenito e9b004
				sys.exit(2)
Chris PeBenito e9b004
			mode = Flask.KERNEL
Chris PeBenito e9b004
		elif o in ('-u', '--user'):
Chris PeBenito e9b004
			if mode != None:
Chris PeBenito e9b004
				print(usage())
Chris PeBenito e9b004
				sys.exit(2)
Chris PeBenito e9b004
			mode = Flask.USERSPACE
Chris PeBenito e9b004
		elif o in ('-w', '--nowarnings'):
Chris PeBenito e9b004
			warn = False
Chris PeBenito e9b004
		else:
Chris PeBenito e9b004
			print(usage())
Chris PeBenito e9b004
			sys.exit(2)
Chris PeBenito e9b004
Chris PeBenito e9b004
	if avec == None or \
Chris PeBenito e9b004
	   isid == None or \
Chris PeBenito e9b004
	   secc == None or \
Chris PeBenito e9b004
	   outd == None:
Chris PeBenito e9b004
		   print(usage())
Chris PeBenito e9b004
		   sys.exit(2)
Chris PeBenito e9b004
Chris PeBenito e9b004
	try:
Chris PeBenito e9b004
		f = Flask(warn)
Chris PeBenito e9b004
		f.parseSids(isid)
Chris PeBenito e9b004
		f.parseClasses(secc)
Chris PeBenito e9b004
		f.parseVectors(avec)
Chris PeBenito e9b004
		f.createHeaders(outd, mode)
Chris PeBenito e9b004
	except Exception, e:
Chris PeBenito e9b004
		print(e)
Chris PeBenito e9b004
		sys.exit(2)