#!/usr/bin/python3 -EsI
#
# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
#
# Copyright (C) 2006 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2 only
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#

# Parse interfaces and output extracted information about them
# suitable for policy generation. By default writes the output
# to the default location (obtained from sepolgen.defaults), but
# will output to another file provided as an argument:
#   sepolgen-ifgen [headers] [output-filename]


import sys
import tempfile
import subprocess

import selinux

import sepolgen.refparser as refparser
import sepolgen.defaults as defaults
import sepolgen.interfaces as interfaces


VERSION = "%prog .1"
ATTR_HELPER = "/usr/bin/sepolgen-ifgen-attr-helper"


def parse_options():
    from optparse import OptionParser

    parser = OptionParser(version=VERSION)
    parser.add_option("-o", "--output", dest="output", default=defaults.interface_info(),
                      help="filename to store output")
    parser.add_option("-i", "--interfaces", dest="headers", default=defaults.headers(),
                      help="location of the interface header files")
    parser.add_option("-a", "--attribute_info", dest="attribute_info")
    parser.add_option("-p", "--policy", dest="policy_path")
    parser.add_option("-v", "--verbose", action="store_true", default=False,
                      help="print debugging output")
    parser.add_option("-d", "--debug", action="store_true", default=False,
                      help="extra debugging output")
    parser.add_option("--attr-helper", default=ATTR_HELPER,
                      help="path to sepolgen-ifgen-attr-helper")
    parser.add_option("--no_attrs", action="store_true", default=False,
                      help="do not retrieve attribute access from kernel policy")
    options, args = parser.parse_args()

    return options


def get_attrs(policy_path, attr_helper):
    try:
        outfile = tempfile.NamedTemporaryFile()
    except IOError as e:
        sys.stderr.write("could not open attribute output file\n")
        return None

    fd = open("/dev/null", "w")
    if policy_path:
        ret = subprocess.Popen([attr_helper, outfile.name, policy_path], stdout=fd).wait()
    else:
        ret = subprocess.Popen([attr_helper, outfile.name], stdout=fd).wait()
    fd.close()
    if ret != 0:
        sys.stderr.write("could not run attribute helper\n")
        return None

    attrs = interfaces.AttributeSet()
    try:
        attrs.from_file(outfile)
    except:
        print("error parsing attribute info")
        return None

    return attrs


def main():
    options = parse_options()

    # Open the output first to generate errors before parsing
    try:
        f = open(options.output, "w")
    except IOError as e:
        sys.stderr.write("could not open output file [%s]\n" % options.output)
        return 1

    if options.verbose:
        log = sys.stdout
    else:
        log = None

    # Get the attributes from the binary
    attrs = None
    if not options.no_attrs:
        attrs = get_attrs(options.policy_path, options.attr_helper)
        if attrs is None:
            return 1

    # Parse the headers
    try:
        headers = refparser.parse_headers(options.headers, output=log, debug=options.debug)
    except ValueError as e:
        sys.stderr.write("error parsing headers: %s\n" % e)
        return 1

    if_set = interfaces.InterfaceSet(output=log)
    if_set.add_headers(headers, attributes=attrs)
    if_set.to_file(f)
    f.close()

    if refparser.success:
        return 0
    else:
        return 1

if __name__ == "__main__":
    sys.exit(main())
