## portsPage.py - show selinux mappings
## Copyright (C) 2006 Red Hat, Inc.

## 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., 675 Mass Ave, Cambridge, MA 02139, USA.

## Author: Dan Walsh
import string
import gtk
import gtk.glade
import os
import gobject
import sys
import seobject
import commands
from semanagePage import *

##
## I18N
##
PROGNAME = "policycoreutils"
import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
TYPE_COL = 0
PROTOCOL_COL = 1
MLS_COL = 2
PORT_COL = 3
try:
    gettext.install(PROGNAME,
                    localedir="/usr/share/locale",
                    unicode=False,
                    codeset='utf-8')
except IOError:
    import __builtin__
    __builtin__.__dict__['_'] = unicode


class portsPage(semanagePage):

    def __init__(self, xml):
        semanagePage.__init__(self, xml, "ports", _("Network Port"))
        xml.signal_connect("on_group_clicked", self.on_group_clicked)
        self.group = False
        self.ports_filter = xml.get_widget("portsFilterEntry")
        self.ports_filter.connect("focus_out_event", self.filter_changed)
        self.ports_filter.connect("activate", self.filter_changed)
        self.ports_name_entry = xml.get_widget("portsNameEntry")
        self.ports_protocol_combo = xml.get_widget("portsProtocolCombo")
        self.ports_number_entry = xml.get_widget("portsNumberEntry")
        self.ports_mls_entry = xml.get_widget("portsMLSEntry")
        self.ports_add_button = xml.get_widget("portsAddButton")
        self.ports_properties_button = xml.get_widget("portsPropertiesButton")
        self.ports_delete_button = xml.get_widget("portsDeleteButton")
        liststore = self.ports_protocol_combo.get_model()
        iter = liststore.get_iter_first()
        self.ports_protocol_combo.set_active_iter(iter)
        self.init_store()
        self.edit = True
        self.load()

    def filter_changed(self, *arg):
        filter = arg[0].get_text()
        if filter != self.filter:
            if self.edit:
                self.load(filter)
            else:
                self.group_load(filter)

    def init_store(self):
        self.store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
        self.view.set_model(self.store)
        self.store.set_sort_column_id(0, gtk.SORT_ASCENDING)

        self.view.set_search_equal_func(self.search)
        col = gtk.TreeViewColumn(_("SELinux Port\nType"), gtk.CellRendererText(), text=TYPE_COL)
        col.set_sort_column_id(TYPE_COL)
        col.set_resizable(True)
        self.view.append_column(col)
        self.store.set_sort_column_id(TYPE_COL, gtk.SORT_ASCENDING)

        col = gtk.TreeViewColumn(_("Protocol"), gtk.CellRendererText(), text=PROTOCOL_COL)
        col.set_sort_column_id(PROTOCOL_COL)
        col.set_resizable(True)
        self.view.append_column(col)

        self.mls_col = gtk.TreeViewColumn(_("MLS/MCS\nLevel"), gtk.CellRendererText(), text=MLS_COL)
        self.mls_col.set_resizable(True)
        self.mls_col.set_sort_column_id(MLS_COL)
        self.view.append_column(self.mls_col)

        col = gtk.TreeViewColumn(_("Port"), gtk.CellRendererText(), text=PORT_COL)
        col.set_sort_column_id(PORT_COL)
        col.set_resizable(True)
        self.view.append_column(col)
        self.store.set_sort_func(PORT_COL, self.sort_int, "")

    def sort_int(self, treemodel, iter1, iter2, user_data):
        try:
            p1 = int(treemodel.get_value(iter1, PORT_COL).split('-')[0])
            p2 = int(treemodel.get_value(iter2, PORT_COL).split('-')[0])
            if p1 > p2:
                return 1
            if p1 == p2:
                return 0
            return -1
        except:
            return 0

    def load(self, filter=""):
        self.filter = filter
        self.port = seobject.portRecords()
        dict = self.port.get_all(self.local)
        keys = dict.keys()
        keys.sort()
        self.store.clear()
        for k in keys:
            if not (self.match(str(k[0]), filter) or self.match(dict[k][0], filter) or self.match(k[2], filter) or self.match(dict[k][1], filter) or self.match(dict[k][1], filter)):
                continue
            iter = self.store.append()
            if k[0] == k[1]:
                self.store.set_value(iter, PORT_COL, k[0])
            else:
                rec = "%s-%s" % k[:2]
                self.store.set_value(iter, PORT_COL, rec)
            self.store.set_value(iter, TYPE_COL, dict[k][0])
            self.store.set_value(iter, PROTOCOL_COL, k[2])
            self.store.set_value(iter, MLS_COL, dict[k][1])
        self.view.get_selection().select_path((0,))

    def group_load(self, filter=""):
        self.filter = filter
        self.port = seobject.portRecords()
        dict = self.port.get_all_by_type(self.local)
        keys = dict.keys()
        keys.sort()
        self.store.clear()
        for k in keys:
            ports_string = ", ".join(dict[k])
            if not (self.match(ports_string, filter) or self.match(k[0], filter) or self.match(k[1], filter)):
                continue
            iter = self.store.append()
            self.store.set_value(iter, TYPE_COL, k[0])
            self.store.set_value(iter, PROTOCOL_COL, k[1])
            self.store.set_value(iter, PORT_COL, ports_string)
            self.store.set_value(iter, MLS_COL, "")
        self.view.get_selection().select_path((0,))

    def propertiesDialog(self):
        if self.edit:
            semanagePage.propertiesDialog(self)

    def dialogInit(self):
        store, iter = self.view.get_selection().get_selected()
        self.ports_number_entry.set_text(store.get_value(iter, PORT_COL))
        self.ports_number_entry.set_sensitive(False)
        self.ports_protocol_combo.set_sensitive(False)
        self.ports_name_entry.set_text(store.get_value(iter, TYPE_COL))
        self.ports_mls_entry.set_text(store.get_value(iter, MLS_COL))
        protocol = store.get_value(iter, PROTOCOL_COL)
        liststore = self.ports_protocol_combo.get_model()
        iter = liststore.get_iter_first()
        while iter != None and liststore.get_value(iter, 0) != protocol:
            iter = liststore.iter_next(iter)
        if iter != None:
            self.ports_protocol_combo.set_active_iter(iter)

    def dialogClear(self):
        self.ports_number_entry.set_text("")
        self.ports_number_entry.set_sensitive(True)
        self.ports_protocol_combo.set_sensitive(True)
        self.ports_name_entry.set_text("")
        self.ports_mls_entry.set_text("s0")

    def delete(self):
        store, iter = self.view.get_selection().get_selected()
        port = store.get_value(iter, PORT_COL)
        protocol = store.get_value(iter, 1)
        try:
            self.wait()
            (rc, out) = commands.getstatusoutput("semanage port -d -p %s %s" % (protocol, port))
            self.ready()
            if rc != 0:
                return self.error(out)
            store.remove(iter)
            self.view.get_selection().select_path((0,))
        except ValueError, e:
            self.error(e.args[0])

    def add(self):
        target = self.ports_name_entry.get_text().strip()
        mls = self.ports_mls_entry.get_text().strip()
        port_number = self.ports_number_entry.get_text().strip()
        if port_number == "":
            port_number = "1"
        for i in port_number.split("-"):
            if not i.isdigit():
                self.error(_("Port number \"%s\" is not valid.  0 < PORT_NUMBER < 65536 ") % port_number)
                return False
        list_model = self.ports_protocol_combo.get_model()
        iter = self.ports_protocol_combo.get_active_iter()
        protocol = list_model.get_value(iter, 0)
        self.wait()
        (rc, out) = commands.getstatusoutput("semanage port -a -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
        self.ready()
        if rc != 0:
            self.error(out)
            return False
        iter = self.store.append()

        self.store.set_value(iter, TYPE_COL, target)
        self.store.set_value(iter, PORT_COL, port_number)
        self.store.set_value(iter, PROTOCOL_COL, protocol)
        self.store.set_value(iter, MLS_COL, mls)

    def modify(self):
        target = self.ports_name_entry.get_text().strip()
        mls = self.ports_mls_entry.get_text().strip()
        port_number = self.ports_number_entry.get_text().strip()
        list_model = self.ports_protocol_combo.get_model()
        iter = self.ports_protocol_combo.get_active_iter()
        protocol = list_model.get_value(iter, 0)
        self.wait()
        (rc, out) = commands.getstatusoutput("semanage port -m -p %s -r %s -t %s %s" % (protocol, mls, target, port_number))
        self.ready()
        if rc != 0:
            self.error(out)
            return False
        store, iter = self.view.get_selection().get_selected()
        self.store.set_value(iter, TYPE_COL, target)
        self.store.set_value(iter, PORT_COL, port_number)
        self.store.set_value(iter, PROTOCOL_COL, protocol)
        self.store.set_value(iter, MLS_COL, mls)

    def on_group_clicked(self, button):
        self.ports_add_button.set_sensitive(self.group)
        self.ports_properties_button.set_sensitive(self.group)
        self.ports_delete_button.set_sensitive(self.group)
        self.mls_col.set_visible(self.group)

        self.group = not self.group
        if self.group:
            button.set_label(_("List View"))
            self.group_load(self.filter)
        else:
            button.set_label(_("Group View"))
            self.load(self.filter)

        return True
