10b8af757b67ee795deef9523f1fd72ca28721e22Eric Paris#! /usr/bin/python -Es 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Copyright (C) 2006 Red Hat 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# see file 'COPYING' for use and warranty information 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This program is free software; you can redistribute it and/or 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# modify it under the terms of the GNU General Public License as 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# published by the Free Software Foundation; version 2 only 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# This program is distributed in the hope that it will be useful, 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# but WITHOUT ANY WARRANTY; without even the implied warranty of 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# GNU General Public License for more details. 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# You should have received a copy of the GNU General Public License 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# along with this program; if not, write to the Free Software 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Parse interfaces and output extracted information about them 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# suitable for policy generation. By default writes the output 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# to the default location (obtained from sepolgen.defaults), but 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# will output to another file provided as an argument: 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# sepolgen-ifgen [headers] [output-filename] 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport sys 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport os 31f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Parisimport tempfile 32f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Parisimport subprocess 33f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris 34f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Parisimport selinux 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport sepolgen.refparser as refparser 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport sepolgen.defaults as defaults 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport sepolgen.interfaces as interfaces 3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4113cd4c8960688af11ad23b4c946149015c80d54Joshua BrindleVERSION = "%prog .1" 42f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric ParisATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper" 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef parse_options(): 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle from optparse import OptionParser 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parser = OptionParser(version=VERSION) 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parser.add_option("-o", "--output", dest="output", default=defaults.interface_info(), 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle help="filename to store output") 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parser.add_option("-i", "--interfaces", dest="headers", default=defaults.headers(), 5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle help="location of the interface header files") 52f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris parser.add_option("-a", "--attribute_info", dest="attribute_info") 53f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris parser.add_option("-p", "--policy", dest="policy_path") 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parser.add_option("-v", "--verbose", action="store_true", default=False, 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle help="print debuging output") 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle parser.add_option("-d", "--debug", action="store_true", default=False, 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle help="extra debugging output") 58f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris parser.add_option("--no_attrs", action="store_true", default=False, 59f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris help="do not retrieve attribute access from kernel policy") 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle options, args = parser.parse_args() 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return options 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 64f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Parisdef get_policy(): 657eec00a5be8b5cebcbbc9a30b42b34f4a623c587Dan Walsh p = selinux.selinux_current_policy_path() 665fe159bfdd0347d48ad6dfa97c92f43c00982bc4Dan Walsh if p and os.path.exists(p): 677eec00a5be8b5cebcbbc9a30b42b34f4a623c587Dan Walsh return p 68f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris i = selinux.security_policyvers() 69f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris p = selinux.selinux_binary_policy_path() + "." + str(i) 70f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris while i > 0 and not os.path.exists(p): 71f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris i = i - 1 72f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris p = selinux.selinux_binary_policy_path() + "." + str(i) 73f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if i > 0: 74f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return p 75f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return None 76f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris 77f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Parisdef get_attrs(policy_path): 78f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris try: 79f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if not policy_path: 80f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris policy_path = get_policy() 81f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if not policy_path: 82f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris sys.stderr.write("No installed policy to check\n") 83f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return None 84f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris outfile = tempfile.NamedTemporaryFile() 85f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris except IOError, e: 86f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris sys.stderr.write("could not open attribute output file\n") 87f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return None 88f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris except OSError: 89f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris # SELinux Disabled Machine 90f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return None 91f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris 92f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris fd = open("/dev/null","w") 93f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris ret = subprocess.Popen([ATTR_HELPER, policy_path, outfile.name], stdout=fd).wait() 94f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris fd.close() 95f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if ret != 0: 96f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris sys.stderr.write("could not run attribute helper") 97f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return None 98f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris 99f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris attrs = interfaces.AttributeSet() 100f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris try: 101f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris attrs.from_file(outfile) 102f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris except: 103f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris print "error parsing attribute info" 104f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return None 105f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris 106f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return attrs 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef main(): 10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle options = parse_options() 11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle # Open the output first to generate errors before parsing 11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle try: 11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle f = open(options.output, "w") 11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle except IOError, e: 11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sys.stderr.write("could not open output file [%s]\n" % options.output) 11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if options.verbose: 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle log = sys.stdout 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else: 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle log = None 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 123f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris # Get the attibutes from the binary 124f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris attrs = None 125f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if not options.no_attrs: 126f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris attrs = get_attrs(options.policy_path) 127f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if attrs is None: 128f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris return 1 129f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris 130f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris # Parse the headers 13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle try: 13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle headers = refparser.parse_headers(options.headers, output=log, debug=options.debug) 13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle except ValueError, e: 13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle print "error parsing headers" 13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle print str(e) 13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1 13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if_set = interfaces.InterfaceSet(output=log) 139f14912ee6e8402a8ca357c518d9c4a8f79cade99Eric Paris if_set.add_headers(headers, attributes=attrs) 14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if_set.to_file(f) 14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle f.close() 14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if refparser.success: 14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0 14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else: 14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 1 14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleif __name__ == "__main__": 14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sys.exit(main()) 150