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