Blob Blame History Raw
#! /usr/bin/python -Es
# Copyright (C) 2012 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 sys
import seobject
import setools
search=setools.sesearch
seinfo=setools.seinfo

portRec = seobject.portRecords()
portrecs = portRec.get_all_by_type()
portrecsbynum = portRec.get_all()
port_types =  setools.seinfo(setools.ATTRIBUTE,"port_type")[0]["types"]

def get_types(src, tclass, perm):
    allows=search([setools.ALLOW],{setools.SCONTEXT:src,setools.CLASS:tclass, setools.PERMS:perm})
    nlist=[]
    if allows:
        for i in map(lambda y: y[setools.TCONTEXT], filter(lambda x: set(perm).issubset(x[setools.PERMS]), allows)):
            if i not in nlist:
                nlist.append(i)
    return nlist
   

def get_network_connect(src, protocol, perm):
    d={}
    tlist = get_types(src, "%s_socket" % protocol, [perm])
    if len(tlist) > 0:
        if "port_type" in tlist:
            d[(src,protocol,perm)] = ["all ports"]
            return d

        d[(src,protocol,perm)] = []

        for i in tlist:
            if i == "ephemeral_port_type":
                if "unreserved_port_type" in tlist:
                    continue
                i = "ephemeral_port_t"
            if i == "unreserved_port_t":
                if "unreserved_port_type" in tlist:
                    continue
                if "port_t" in tlist:
                    continue
            if i == "port_t":
                d[(src,protocol,perm)].append("all ports with out defined types")
            elif i == "unreserved_port_type":
                d[(src,protocol,perm)].append("%s: all ports > 1024" % i)
            elif i == "reserved_port_type":
                d[(src,protocol,perm)].append("%s: all ports < 1024" % i)
            elif i == "rpc_port_type":
                d[(src,protocol,perm)].append("%s: all ports > 500 and  < 1024" % i)
            else:
                try:
                    d[(src,protocol,perm)].append("%s: %s" % (i, ",".join(portrecs[(i, protocol)])))
                except KeyError:
                    pass
    return d

def print_net(src, protocol, perm):
    portdict = get_network_connect(src, protocol, perm)
    if len(portdict) > 0:
        print "%s: %s %s" % (src, protocol, perm)
        for p in portdict:
            for recs in portdict[p]:
                print "\t" + recs


if __name__ == '__main__':
    setype = sys.argv[1]
    if setype.isdigit():
        port = int(setype)

        found = False
        for i in portrecsbynum:
            if i[0] <= port and port <= i[1]:
                if i[0] == i[1]:
                    range = i[0]
                else:
                    range = "%s-%s" % (i[0], i[1])
                found = True
                print "%s: %s %s %s" % (setype, i[2], portrecsbynum[i][0], range)
        if not found:
            if port < 500:
                print "Undefined reserved port type" 
            else:
                print "Undefined port type" 
    elif setype in port_types:
        if (setype,'tcp') in portrecs.keys():
            print "%s: tcp: %s" % (setype, ",".join(portrecs[setype,'tcp']))
        if (setype,'udp') in portrecs.keys():
            print "%s: udp: %s" % (setype, ",".join(portrecs[setype,'udp']))
    else:
        print_net(setype, "tcp", "name_connect")
        for net in ("tcp", "udp"):
            print_net(setype, net, "name_bind")