blob: 4a71cda4d5022f70badb1f8857d304cceeddd368 [file] [log] [blame]
Nicolas Iooss72dc5c62019-02-17 21:57:41 +01001#!/usr/bin/python3 -Es
Joshua Brindle13cd4c82008-08-19 15:30:36 -04002#
3# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
4#
Jason Zaman789d0eb2015-07-24 16:07:13 +08005# Copyright (C) 2006 Red Hat
Joshua Brindle13cd4c82008-08-19 15:30:36 -04006# 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
Eric Parisf14912e2011-08-03 11:11:40 -040031import tempfile
32import subprocess
33
34import selinux
Joshua Brindle13cd4c82008-08-19 15:30:36 -040035
36import sepolgen.refparser as refparser
37import sepolgen.defaults as defaults
38import sepolgen.interfaces as interfaces
39
40
41VERSION = "%prog .1"
Eric Parisf14912e2011-08-03 11:11:40 -040042ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper"
Joshua Brindle13cd4c82008-08-19 15:30:36 -040043
Jason Zaman789d0eb2015-07-24 16:07:13 +080044
Joshua Brindle13cd4c82008-08-19 15:30:36 -040045def 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")
Eric Parisf14912e2011-08-03 11:11:40 -040053 parser.add_option("-a", "--attribute_info", dest="attribute_info")
54 parser.add_option("-p", "--policy", dest="policy_path")
Joshua Brindle13cd4c82008-08-19 15:30:36 -040055 parser.add_option("-v", "--verbose", action="store_true", default=False,
Nicolas Ioossb550c0e2019-08-05 22:11:20 +020056 help="print debugging output")
Joshua Brindle13cd4c82008-08-19 15:30:36 -040057 parser.add_option("-d", "--debug", action="store_true", default=False,
Jason Zaman789d0eb2015-07-24 16:07:13 +080058 help="extra debugging output")
Nicolas Ioosse1f2db52019-01-05 20:37:57 +010059 parser.add_option("--attr-helper", default=ATTR_HELPER,
60 help="path to sepolgen-ifgen-attr-helper")
Eric Parisf14912e2011-08-03 11:11:40 -040061 parser.add_option("--no_attrs", action="store_true", default=False,
62 help="do not retrieve attribute access from kernel policy")
Joshua Brindle13cd4c82008-08-19 15:30:36 -040063 options, args = parser.parse_args()
Jason Zaman789d0eb2015-07-24 16:07:13 +080064
Joshua Brindle13cd4c82008-08-19 15:30:36 -040065 return options
66
Jason Zaman789d0eb2015-07-24 16:07:13 +080067
Eric Parisf14912e2011-08-03 11:11:40 -040068def get_policy():
Dan Walsh7eec00a2013-10-09 16:18:15 -040069 p = selinux.selinux_current_policy_path()
Dan Walsh5fe159b2013-11-13 10:43:46 -050070 if p and os.path.exists(p):
Dan Walsh7eec00a2013-10-09 16:18:15 -040071 return p
Eric Parisf14912e2011-08-03 11:11:40 -040072 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
Jason Zaman789d0eb2015-07-24 16:07:13 +080081
Nicolas Ioosse1f2db52019-01-05 20:37:57 +010082def get_attrs(policy_path, attr_helper):
Eric Parisf14912e2011-08-03 11:11:40 -040083 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()
Michal Srbd1359512015-07-21 02:38:19 +020090 except IOError as e:
Eric Parisf14912e2011-08-03 11:11:40 -040091 sys.stderr.write("could not open attribute output file\n")
92 return None
93 except OSError:
94 # SELinux Disabled Machine
95 return None
96
Jason Zaman789d0eb2015-07-24 16:07:13 +080097 fd = open("/dev/null", "w")
Nicolas Ioosse1f2db52019-01-05 20:37:57 +010098 ret = subprocess.Popen([attr_helper, policy_path, outfile.name], stdout=fd).wait()
Eric Parisf14912e2011-08-03 11:11:40 -040099 fd.close()
100 if ret != 0:
Nicolas Ioossc7599122018-12-21 21:43:31 +0100101 sys.stderr.write("could not run attribute helper\n")
Eric Parisf14912e2011-08-03 11:11:40 -0400102 return None
103
104 attrs = interfaces.AttributeSet()
105 try:
106 attrs.from_file(outfile)
107 except:
Michal Srbd1359512015-07-21 02:38:19 +0200108 print("error parsing attribute info")
Eric Parisf14912e2011-08-03 11:11:40 -0400109 return None
110
111 return attrs
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400112
Jason Zaman789d0eb2015-07-24 16:07:13 +0800113
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400114def main():
115 options = parse_options()
116
117 # Open the output first to generate errors before parsing
118 try:
119 f = open(options.output, "w")
Michal Srbd1359512015-07-21 02:38:19 +0200120 except IOError as e:
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400121 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
Nicolas Ioossb550c0e2019-08-05 22:11:20 +0200129 # Get the attributes from the binary
Eric Parisf14912e2011-08-03 11:11:40 -0400130 attrs = None
131 if not options.no_attrs:
Nicolas Ioosse1f2db52019-01-05 20:37:57 +0100132 attrs = get_attrs(options.policy_path, options.attr_helper)
Eric Parisf14912e2011-08-03 11:11:40 -0400133 if attrs is None:
134 return 1
135
136 # Parse the headers
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400137 try:
138 headers = refparser.parse_headers(options.headers, output=log, debug=options.debug)
Michal Srbd1359512015-07-21 02:38:19 +0200139 except ValueError as e:
Nicolas Iooss621c4062018-12-21 21:43:32 +0100140 sys.stderr.write("error parsing headers: %s\n" % e)
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400141 return 1
142
143 if_set = interfaces.InterfaceSet(output=log)
Eric Parisf14912e2011-08-03 11:11:40 -0400144 if_set.add_headers(headers, attributes=attrs)
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400145 if_set.to_file(f)
146 f.close()
147
148 if refparser.success:
149 return 0
150 else:
151 return 1
Jason Zaman789d0eb2015-07-24 16:07:13 +0800152
Joshua Brindle13cd4c82008-08-19 15:30:36 -0400153if __name__ == "__main__":
154 sys.exit(main())