ab5473d
#! /usr/bin/python -Es
ab5473d
# Copyright (C) 2012 Red Hat 
ab5473d
# see file 'COPYING' for use and warranty information
ab5473d
#
ab5473d
# setrans is a tool for analyzing process transistions in SELinux policy
ab5473d
#
ab5473d
#    This program is free software; you can redistribute it and/or
ab5473d
#    modify it under the terms of the GNU General Public License as
ab5473d
#    published by the Free Software Foundation; either version 2 of
ab5473d
#    the License, or (at your option) any later version.
ab5473d
#
ab5473d
#    This program is distributed in the hope that it will be useful,
ab5473d
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
ab5473d
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ab5473d
#    GNU General Public License for more details.
ab5473d
#
ab5473d
#    You should have received a copy of the GNU General Public License
ab5473d
#    along with this program; if not, write to the Free Software
ab5473d
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
ab5473d
#                                        02111-1307  USA
ab5473d
#
ab5473d
#  
ab5473d
import sys
ab5473d
import seobject
ab5473d
import setools
ab5473d
search=setools.sesearch
ab5473d
seinfo=setools.seinfo
ab5473d
ab5473d
portRec = seobject.portRecords()
ab5473d
portrecs = portRec.get_all_by_type()
ab5473d
portrecsbynum = portRec.get_all()
ab5473d
port_types =  setools.seinfo(setools.ATTRIBUTE,"port_type")[0]["types"]
ab5473d
ab5473d
def get_types(src, tclass, perm):
ab5473d
    allows=search([setools.ALLOW],{setools.SCONTEXT:src,setools.CLASS:tclass, setools.PERMS:perm})
ab5473d
    nlist=[]
ab5473d
    if allows:
ab5473d
        for i in map(lambda y: y[setools.TCONTEXT], filter(lambda x: set(perm).issubset(x[setools.PERMS]), allows)):
ab5473d
            if i not in nlist:
ab5473d
                nlist.append(i)
ab5473d
    return nlist
ab5473d
   
ab5473d
ab5473d
def get_network_connect(src, protocol, perm):
ab5473d
    d={}
ab5473d
    tlist = get_types(src, "%s_socket" % protocol, [perm])
ab5473d
    if len(tlist) > 0:
ab5473d
        if "port_type" in tlist:
ab5473d
            d[(src,protocol,perm)] = ["all ports"]
ab5473d
            return d
ab5473d
ab5473d
        d[(src,protocol,perm)] = []
ab5473d
ab5473d
        for i in tlist:
ab5473d
            if i == "ephemeral_port_type":
ab5473d
                if "unreserved_port_type" in tlist:
ab5473d
                    continue
ab5473d
                i = "ephemeral_port_t"
ab5473d
            if i == "unreserved_port_t":
ab5473d
                if "unreserved_port_type" in tlist:
ab5473d
                    continue
ab5473d
                if "port_t" in tlist:
ab5473d
                    continue
ab5473d
            if i == "port_t":
ab5473d
                d[(src,protocol,perm)].append("all ports with out defined types")
ab5473d
            elif i == "unreserved_port_type":
ab5473d
                d[(src,protocol,perm)].append("%s: all ports > 1024" % i)
ab5473d
            elif i == "reserved_port_type":
ab5473d
                d[(src,protocol,perm)].append("%s: all ports < 1024" % i)
ab5473d
            elif i == "rpc_port_type":
ab5473d
                d[(src,protocol,perm)].append("%s: all ports > 500 and  < 1024" % i)
ab5473d
            else:
ab5473d
                try:
ab5473d
                    d[(src,protocol,perm)].append("%s: %s" % (i, ",".join(portrecs[(i, protocol)])))
ab5473d
                except KeyError:
ab5473d
                    pass
ab5473d
    return d
ab5473d
ab5473d
def print_net(src, protocol, perm):
ab5473d
    portdict = get_network_connect(src, protocol, perm)
ab5473d
    if len(portdict) > 0:
ab5473d
        print "%s: %s %s" % (src, protocol, perm)
ab5473d
        for p in portdict:
ab5473d
            for recs in portdict[p]:
ab5473d
                print "\t" + recs
ab5473d
ab5473d
ab5473d
if __name__ == '__main__':
ab5473d
    setype = sys.argv[1]
ab5473d
    if setype.isdigit():
ab5473d
        port = int(setype)
ab5473d
ab5473d
        found = False
ab5473d
        for i in portrecsbynum:
ab5473d
            if i[0] <= port and port <= i[1]:
ab5473d
                if i[0] == i[1]:
ab5473d
                    range = i[0]
ab5473d
                else:
ab5473d
                    range = "%s-%s" % (i[0], i[1])
ab5473d
                found = True
ab5473d
                print "%s: %s %s %s" % (setype, i[2], portrecsbynum[i][0], range)
ab5473d
        if not found:
ab5473d
            if port < 500:
ab5473d
                print "Undefined reserved port type" 
ab5473d
            else:
ab5473d
                print "Undefined port type" 
ab5473d
    elif setype in port_types:
ab5473d
        if (setype,'tcp') in portrecs.keys():
ab5473d
            print "%s: tcp: %s" % (setype, ",".join(portrecs[setype,'tcp']))
ab5473d
        if (setype,'udp') in portrecs.keys():
ab5473d
            print "%s: udp: %s" % (setype, ",".join(portrecs[setype,'udp']))
ab5473d
    else:
ab5473d
        print_net(setype, "tcp", "name_connect")
ab5473d
        for net in ("tcp", "udp"):
ab5473d
            print_net(setype, net, "name_bind")