#! /usr/bin/python -Es
# Copyright (C) 2011 Red Hat 
# see file 'COPYING' for use and warranty information
#
# setrans is a tool for analyzing process transistions in SELinux policy
#
#    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; either version 2 of
#    the License, or (at your option) any later version.
#
#    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
#
#  
import sepolicy
search=sepolicy.search
info=sepolicy.info
__all__ = [ 'setrans', ]

def _entrypoint(src):
    trans=search([sepolicy.ALLOW],{sepolicy.SOURCE:src})
    return map(lambda y: y[sepolicy.TARGET], filter(lambda x: "entrypoint" in x[sepolicy.PERMS], trans))
    

def _get_trans(src):
    return search([sepolicy.TRANSITION],{sepolicy.SOURCE:src, sepolicy.CLASS:"process"})

class setrans:
    def __init__(self, source, dest=None):
        self.seen = []
        self.sdict = {}
        self.source=source
        self.dest=dest
        self._process(self.source)
            
    def _process(self, source):
        if source in self.sdict:
            return self.sdict[source]
        self.sdict[source] = {}
        trans = _get_trans(source)
        if not trans:
            return
        self.sdict[source]["name"] = source
        if not self.dest:
            self.sdict[source]["map"] = trans
        else:
            self.sdict[source]["map"] = map(lambda y: y, filter(lambda x: x["transtype"] == self.dest, trans))
            self.sdict[source]["child"] = map(lambda y: y["transtype"], filter(lambda x: x["transtype"] not in [self.dest,source] , trans))
            for s in self.sdict[source]["child"]:
                self._process(s)
            
    def out(self, name, header=""):
        buf = ""
        if name in self.seen:
            return buf
        self.seen.append(name)

        if "map" in self.sdict[name]:
            for t in self.sdict[name]["map"]:
                cond=sepolicy.get_conditionals(t["source"], t["transtype"],"process",["transition"])
                if cond:
                    buf += "%s%s @ %s --> %s %s\n" % (header, t["source"], t["target"], t["transtype"], sepolicy.get_conditionals_format_text(cond))
                else:
                    buf += "%s%s @ %s --> %s\n" % (header, t["source"], t["target"], t["transtype"])

        if "child" in self.sdict[name]:
            for x in self.sdict[name]["child"]:
                buf+= self.out(x, "%s%s ... " % (header, name))
        return buf

    def output(self):
        self.seen = []
        print self.out(self.source)
