• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python3 -Es
2#
3# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
4#
5# Copyright (C) 2006 Red Hat
6# see file 'COPYING' for use and warranty information
7#
8# This program is free software; you can redistribute it and/or
9# modify it under the terms of the GNU General Public License as
10# published by the Free Software Foundation; version 2 only
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20#
21
22# Parse interfaces and output extracted information about them
23# suitable for policy generation. By default writes the output
24# to the default location (obtained from sepolgen.defaults), but
25# will output to another file provided as an argument:
26#   sepolgen-ifgen [headers] [output-filename]
27
28
29import sys
30import os
31import tempfile
32import subprocess
33
34import selinux
35
36import sepolgen.refparser as refparser
37import sepolgen.defaults as defaults
38import sepolgen.interfaces as interfaces
39
40
41VERSION = "%prog .1"
42ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper"
43
44
45def parse_options():
46    from optparse import OptionParser
47
48    parser = OptionParser(version=VERSION)
49    parser.add_option("-o", "--output", dest="output", default=defaults.interface_info(),
50                      help="filename to store output")
51    parser.add_option("-i", "--interfaces", dest="headers", default=defaults.headers(),
52                      help="location of the interface header files")
53    parser.add_option("-a", "--attribute_info", dest="attribute_info")
54    parser.add_option("-p", "--policy", dest="policy_path")
55    parser.add_option("-v", "--verbose", action="store_true", default=False,
56                      help="print debugging output")
57    parser.add_option("-d", "--debug", action="store_true", default=False,
58                      help="extra debugging output")
59    parser.add_option("--attr-helper", default=ATTR_HELPER,
60                      help="path to sepolgen-ifgen-attr-helper")
61    parser.add_option("--no_attrs", action="store_true", default=False,
62                      help="do not retrieve attribute access from kernel policy")
63    options, args = parser.parse_args()
64
65    return options
66
67
68def get_policy():
69    p = selinux.selinux_current_policy_path()
70    if p and os.path.exists(p):
71        return p
72    i = selinux.security_policyvers()
73    p = selinux.selinux_binary_policy_path() + "." + str(i)
74    while i > 0 and not os.path.exists(p):
75        i = i - 1
76        p = selinux.selinux_binary_policy_path() + "." + str(i)
77    if i > 0:
78        return p
79    return None
80
81
82def get_attrs(policy_path, attr_helper):
83    try:
84        if not policy_path:
85            policy_path = get_policy()
86        if not policy_path:
87            sys.stderr.write("No installed policy to check\n")
88            return None
89        outfile = tempfile.NamedTemporaryFile()
90    except IOError as e:
91        sys.stderr.write("could not open attribute output file\n")
92        return None
93    except OSError:
94        # SELinux Disabled Machine
95        return None
96
97    fd = open("/dev/null", "w")
98    ret = subprocess.Popen([attr_helper, policy_path, outfile.name], stdout=fd).wait()
99    fd.close()
100    if ret != 0:
101        sys.stderr.write("could not run attribute helper\n")
102        return None
103
104    attrs = interfaces.AttributeSet()
105    try:
106        attrs.from_file(outfile)
107    except:
108        print("error parsing attribute info")
109        return None
110
111    return attrs
112
113
114def main():
115    options = parse_options()
116
117    # Open the output first to generate errors before parsing
118    try:
119        f = open(options.output, "w")
120    except IOError as e:
121        sys.stderr.write("could not open output file [%s]\n" % options.output)
122        return 1
123
124    if options.verbose:
125        log = sys.stdout
126    else:
127        log = None
128
129    # Get the attributes from the binary
130    attrs = None
131    if not options.no_attrs:
132        attrs = get_attrs(options.policy_path, options.attr_helper)
133        if attrs is None:
134            return 1
135
136    # Parse the headers
137    try:
138        headers = refparser.parse_headers(options.headers, output=log, debug=options.debug)
139    except ValueError as e:
140        sys.stderr.write("error parsing headers: %s\n" % e)
141        return 1
142
143    if_set = interfaces.InterfaceSet(output=log)
144    if_set.add_headers(headers, attributes=attrs)
145    if_set.to_file(f)
146    f.close()
147
148    if refparser.success:
149        return 0
150    else:
151        return 1
152
153if __name__ == "__main__":
154    sys.exit(main())
155