|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/22697/root/usr/share/firstboot/modules/ |
Upload File : |
#
# securitylevel.py - GUI front end code for basic system security
#
# Brent Fox <bfox@redhat.com>
#
# Copyright 2002, 2003, 2004 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.
#
import string
import gtk
import gtk.glade
import gobject
import sys
import os
import socket
sys.path.append('/usr/share/system-config-securitylevel')
import scs_checklist as checklist
import trustedchecklist
import selinuxPage
import types
##
## I18N
##
from rhpl.translate import _, N_
import rhpl.translate as translate
domain = "system-config-securitylevel"
translate.textdomain (domain)
##
## Icon for windows
##
iconPixbuf = None
try:
iconPixbuf = gtk.gdk.pixbuf_new_from_file("/usr/share/system-config-securitylevel/pixmaps/system-config-securitylevel.png")
except:
pass
##
## Pull in the Glade file
##
if os.access("system-config-securitylevel.glade", os.F_OK):
xml = gtk.glade.XML ("system-config-securitylevel.glade", domain=domain)
else:
xml = gtk.glade.XML ("/usr/share/system-config-securitylevel/system-config-securitylevel.glade", domain=domain)
class childWindow:
# You must specify a runPriority for the firstboot module order
runPriority = 50
moduleName = _("Firewall")
commentTag = _("Configure system security level and firewall rules")
shortMessage = _("You can use a firewall to allow access to specific "
"services on your computer from other computers and "
"prevent unauthorized access from the outside world. "
"Which services, if any, do you wish to allow access to?")
def destroy(self, args):
gtk.main_quit()
def __init__(self):
self.xml = xml
self.dirty = False
self.doDebug = None
self.selinuxPage = None
self.other_changed_firsttime = True
self.serviceDict = \
{"SSH": {"ports": [("ssh", "tcp")], "modules": []},
"Telnet": {"ports": [("telnet", "tcp")], "modules": []},
"WWW (HTTP)": {"ports": [("http", "tcp")], "modules": []},
"FTP": {"ports": [("ftp", "tcp")],
"modules": ["ip_conntrack_ftp"]},
"NFS4": {"ports": [("nfs", "tcp")], "modules": []},
_("Secure WWW (HTTPS)"): {"ports": [("https", "tcp")], "modules": []},
_("Mail (SMTP)"): {"ports": [("smtp", "tcp")], "modules": []},
_("Samba"): {"ports": [("137", "udp"), ("138", "udp"),
("139", "tcp"), ("445", "tcp")],
"modules": []}}
def setupScreen(self):
# Bring in widgets from glade file.
self.incomingSW = self.xml.get_widget("incomingSW")
self.mainVBox = self.xml.get_widget("mainVBox")
self.mainWindow = self.xml.get_widget("mainWindow")
self.notebook = self.xml.get_widget("scsNotebook")
self.securityOptionMenu = self.xml.get_widget("securityOptionMenu")
self.seLinuxVBox = self.xml.get_widget("seLinuxVBox")
self.otherPortsView = self.xml.get_widget("otherPortsView")
self.trustedServicesBox = self.xml.get_widget("trustedServicesBox")
self.otherPortsExpander = self.xml.get_widget("otherPortsExpander")
self.addPortButton = self.xml.get_widget("addPortButton")
self.removePortButton = self.xml.get_widget("removePortButton")
self.addPortDialog = self.xml.get_widget("addPortDialog")
self.addPortTable = self.xml.get_widget("addPortTable")
self.portEntry = self.xml.get_widget("portEntry")
self.mainWindow.set_icon(iconPixbuf)
# Set up the enabled/disabled firewall combo box.
listStore = gtk.ListStore(gobject.TYPE_STRING)
self.securityOptionMenu.set_model(listStore)
cell = gtk.CellRendererText()
self.securityOptionMenu.pack_start(cell, True)
self.securityOptionMenu.add_attribute(cell, 'text', 0)
self.security_changed_firsttime = True
self.securityOptionMenu.connect('changed', self.security_changed_cb)
self.securityOptionMenu.append_text(_("Enabled"))
self.securityOptionMenu.append_text(_("Disabled"))
# Set up the trusted services checklist.
self.incomingList = checklist.CheckList(columns=1)
keyList = self.serviceDict.keys()
keyList.sort()
for item in keyList:
self.incomingList.append_row((item, ""), False)
self.incomingSW.add(self.incomingList)
# Set up the view and columns for the Other Ports section.
self.otherPortsStore = gtk.ListStore(gobject.TYPE_STRING,
gobject.TYPE_STRING)
otherPortsSorted = gtk.TreeModelSort(self.otherPortsStore)
otherPortsSorted.set_sort_column_id(0, gtk.SORT_ASCENDING)
self.otherPortsView.set_model(otherPortsSorted)
portsCol = gtk.TreeViewColumn("Ports", gtk.CellRendererText(), text=0)
portsCol.set_expand(True)
self.otherPortsView.append_column(portsCol)
protoCol = gtk.TreeViewColumn("Proto", gtk.CellRendererText(), text=1)
self.otherPortsView.append_column(protoCol)
self.addPortButton.connect("clicked", self.add_port_cb)
self.removePortButton.connect("clicked", self.remove_port_cb)
# Add buttons to the "Add Port" dialog, since they don't want to
# behave otherwise.
self.addPortDialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_OK, gtk.RESPONSE_OK)
# Add options to the protocol combo box.
self.protoCombo = gtk.combo_box_new_text()
self.addPortTable.attach(self.protoCombo, 1, 2, 1, 2)
self.protoCombo.append_text("tcp")
self.protoCombo.append_text("udp")
self.protoCombo.set_active(0)
def firewall_activated(self, *args):
self.trustedServicesBox.set_sensitive(True)
self.otherPortsExpander.set_sensitive(True)
self.dirty = True
def none_activated(self, *args):
self.trustedServicesBox.set_sensitive(False)
self.otherPortsExpander.set_sensitive(False)
self.dirty = True
def add_port_cb(self, button, *args):
protoMapping = ["tcp", "udp"]
self.addPortDialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.addPortDialog.set_transient_for(self.mainWindow)
self.addPortDialog.set_modal(True)
self.addPortDialog.show_all()
self.portEntry.set_text("")
self.portEntry.grab_focus()
self.protoCombo.set_active(0)
# Loop until we get a valid port string.
while True:
result = self.addPortDialog.run()
if result == gtk.RESPONSE_OK:
portStr = self.portEntry.get_text()
proto = protoMapping[self.protoCombo.get_active()]
ports = self.portIsValid(portStr)
if not ports:
self.invalidPortDialog(portStr)
continue
else:
portStr = ports
if self.findPortInStore(portStr, proto) is None:
self.otherPortsStore.append([portStr, proto])
self.dirty = True
break
else:
break
self.addPortDialog.hide()
def remove_port_cb(self, button, *args):
selection = self.otherPortsView.get_selection()
(model, treeModelSortIter) = selection.get_selected()
if treeModelSortIter is None:
return
# Convert the iter on the TreeModelSort to an iter on the underlying
# ListStore so we can delete the right thing.
iter = model.convert_iter_to_child_iter(None, treeModelSortIter)
if iter is not None:
# Need to get past the TreeModelSort to whatever's underneath.
model.get_model().remove(iter)
self.dirty = True
def security_changed_cb(self, combobox, *args):
if self.security_changed_firsttime == True:
self.security_changed_firsttime = False
return
model = combobox.get_model()
active = combobox.get_active()
if active < 0:
return None
elif active == 0:
self.firewall_activated()
elif active == 1:
self.none_activated()
else:
return None
def other_changed_cb(self, *args):
if self.other_changed_firsttime == True:
self.other_changed_firsttime = False
return
self.dirty = True
def okClicked(self, *args):
rc = self.apply()
if rc == 0:
self.destroy(args)
def applyClicked(self, *args):
self.apply()
def readFile(self):
path = "/etc/sysconfig/system-config-securitylevel"
if os.access(path, os.R_OK) == 1:
lines = open(path, 'r').readlines()
else:
#The file isn't there, so just return and keep on going
self.trustedServicesBox.set_sensitive(True)
self.otherPortsExpander.set_sensitive(True)
return
devicesList = []
masqList = []
servicesList = []
portsList = []
# Special list so we can infer Samba browsing being enabled if all
# the ports are enabled.
sambaList = []
self.trustedServicesBox.set_sensitive(True)
self.otherPortsExpander.set_sensitive(True)
for line in lines:
stripped = string.strip(line)
if stripped != "" and stripped[0] != "#":
if stripped in ["--high", "--medium", "--enabled"]:
self.securityOptionMenu.set_active(0)
elif stripped == "--disabled":
self.securityOptionMenu.set_active(1)
self.trustedServicesBox.set_sensitive(False)
self.otherPortsExpander.set_sensitive(False)
elif line[:8] == "--trust=":
key, device = string.split(line, "=")
devicesList.append(string.strip(device))
elif line[:7] == "--masq=":
key, device = string.split(line, "=")
masqList.append(string.strip(device))
elif line[:7] == "--port=":
key, value = string.split(line, "=")
try:
service, protocol = string.split(value, ":")
except ValueError:
service = value
protocol = "tcp"
service = string.strip(service)
protocol = string.strip(protocol)
if service in ["22", "ssh"] and protocol == 'tcp':
service = 'ssh'
elif service in ["80", "http"] and protocol == 'tcp':
service = 'http'
elif service in ["443", "https"] and protocol == 'tcp':
service = 'https'
elif service in ["23", "telnet"] and protocol == 'tcp':
service = 'telnet'
elif service in ["21", "ftp"] and protocol == 'tcp':
service = 'ftp'
elif service in ["25", "smtp"] and protocol == 'tcp':
service = 'smtp'
elif service in ["2049", "nfs"] and protocol == 'tcp':
service = 'nfs'
else:
# Catch ports that aren't in /etc/services.
try:
protoname = socket.getservbyport(int(service), protocol)
except:
protoname = service
# Use the translated names anyway, in case we're
# only enabling some of these ports and not samba.
if service == '137' and protocol == 'udp' or \
service == '138' and protocol == 'udp' or \
service == '139' and protocol == 'tcp' or \
service == '445' and protocol == 'tcp':
sambaList.append(protoname + ":" + protocol)
else:
portsList.append(protoname + ":" + protocol)
continue
servicesList.append(service)
# Lame. If all the ports were added for Samba browsing, add it to
# the incomingList instead of adding the ports to the portsList.
# This would be easier if we had a --service option or similar
# that stood for a set of ports, rather than specify each one.
if len(sambaList) == 4:
iter = self.incomingList.store.get_iter_first()
while iter:
if self.incomingList.store.get_value(iter, 1) == _("Samba"):
self.incomingList.store.set_value(iter, 0, True)
break
iter = self.incomingList.store.iter_next(iter)
else:
portsList.extend (sambaList)
iter = self.incomingList.store.get_iter_first()
while iter:
val = self.incomingList.store.get_value(iter, 1)
for (port, proto) in self.serviceDict[val]["ports"]:
if port in servicesList:
self.incomingList.store.set_value(iter, 0, True)
iter = self.incomingList.store.iter_next(iter)
# Add the enabled other ports to the view.
for pair in portsList:
(port, proto) = pair.split(':')
port = self.portIsValid(port)
if port and proto in ["tcp", "udp"]:
self.otherPortsStore.append([port, proto])
def findPortInStore(self, port, proto):
iter = self.otherPortsStore.get_iter_first()
while iter:
if port == self.otherPortsStore.get_value(iter, 0) and \
proto == self.otherPortsStore.get_value(iter, 1):
return iter
else:
iter = self.otherPortsStore.iter_next(iter)
return None
def getPortID(self, port):
try:
id = int(port)
except:
try:
id = socket.getservbyname(port)
except:
return -1
if id > 65535:
return -1
return id
def getPortRange(self, ports):
splits = ports.split("-")
matched = [ ]
for i in xrange(len(splits), 0, -1):
id1 = self.getPortID("-".join(splits[:i]))
port2 = "-".join(splits[i:])
if len(port2) > 0:
id2 = self.getPortID(port2)
if id1 >= 0 and id2 >= 0:
if id1 <= id2:
matched.append((id1, id2))
else:
matched.append((id2, id1))
else:
if id1 >= 0:
matched.append((id1,))
if i == len(splits):
# full match, stop here
break
if len(matched) < 1:
return -1
elif len(matched) > 1:
return None
return matched[0]
def portIsValid(self, port):
ports = self.getPortRange(port)
if not (isinstance(ports, types.ListType) or \
isinstance(ports, types.TupleType)):
return None
if len(ports) == 1:
return "%d" % ports[0]
return "%d-%d" % (ports[0], ports[1])
def invalidPortDialog(self, port):
text = _("Invalid port given: '%s'. Please give a port number "
"or service name.") % port
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_OK,
text)
dlg.set_modal(True)
dlg.set_icon(iconPixbuf)
dlg.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
dlg.set_transient_for(self.mainWindow)
dlg.show_all()
dlg.run()
dlg.destroy()
def confirmDialog(self):
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO,
_("Clicking the 'Yes' button will set the security level of the "
"system and override any "
"existing firewall configuration. Are you sure that you want "
"to do this?"))
dlg.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
dlg.set_transient_for(self.mainWindow)
dlg.set_modal(True)
dlg.set_icon(iconPixbuf)
dlg.show_all()
result = dlg.run()
dlg.destroy()
return result
def apply(self, *args):
if self.selinuxPage and self.selinuxPage.selinuxsupport:
self.selinuxPage.apply()
if self.dirty != True and self.incomingList.dirty != True:
return 0
# With the new enabled/disabled behavior, we have to ignore the config
# file or else you can only ever turn on services.
args = ['/usr/sbin/lokkit', '--quiet', '-f']
index = self.securityOptionMenu.get_active()
if index == 0:
args.append('--enabled')
elif index == 1:
args.append('--disabled')
count = 0
keyList = self.serviceDict.keys()
keyList.sort()
for service in keyList:
if self.incomingList.get_active(count):
for (port, proto) in self.serviceDict[service]["ports"]:
args.append('--port=' + port + ':' + proto)
for module in self.serviceDict[service]["modules"]:
args.append('--addmodule=' + module)
else:
for module in self.serviceDict[service]["modules"]:
args.append('--removemodule=' + module)
count = count + 1
model = self.otherPortsView.get_model()
iter = model.get_iter_first()
while iter:
args.append("--port=%s:%s" % (model.get_value(iter, 0),
model.get_value(iter, 1)))
iter = model.iter_next(iter)
if self.confirmDialog() == gtk.RESPONSE_NO:
return None
if self.doDebug:
print "don't call lokkit if in debug mode"
else:
(rfd, wfd) = os.pipe()
pid = os.fork()
if pid == 0:
try:
os.close(rfd)
fd = os.open("/dev/null", os.O_RDONLY)
if fd != 0:
os.dup2(fd, 0)
os.close(fd)
if wfd != 1:
os.dup2(wfd, 1)
os.close(wfd)
os.dup2(1, 2)
os.execv(args[0], args)
finally:
os._exit(255)
os.close(wfd)
# no need to read in chunks if we don't pass on data to some
# output func
cret = ""
cout = os.read(rfd, 8192)
while cout:
cret += cout
cout = os.read(rfd, 8192)
os.close(rfd)
(cpid, status) = os.waitpid(pid, 0)
# failed to configure firewall, show error message
if status != 0:
dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR,
gtk.BUTTONS_CLOSE)
dialog.set_markup("<b>" + _("Configuration failed") + \
"</b>")
dialog.format_secondary_text(" ".join(args) + "\n\n" + \
cret.strip())
dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
dialog.set_transient_for(self.mainWindow)
dialog.set_modal(True)
dialog.show_all()
dialog.run()
dialog.destroy()
return 1
# Set these to False so if you click Apply followed by OK, you're not
# prompted twice.
self.dirty = False
self.incomingList.dirty = False
return 0
def launch(self, doDebug = None):
self.doDebug = doDebug
self.setupScreen()
messageLabel = gtk.Label(_(self.shortMessage))
messageLabel.set_line_wrap(True)
messageLabel.set_size_request(500, -1)
messageLabel.set_alignment(0.0, 0.5)
self.readFile()
vbox = gtk.VBox(spacing=10)
vbox.pack_start(messageLabel, expand=False)
self.mainVBox.reparent(vbox)
icon = gtk.Image()
icon.set_from_pixbuf(iconPixbuf)
return vbox, icon, self.moduleName
def stand_alone(self):
desktopName = _("Security Level and Firewall")
self.setupScreen()
self.okButton = self.xml.get_widget("okButton")
self.cancelButton = self.xml.get_widget("cancelButton")
self.applyButton = self.xml.get_widget("applyButton")
self.selinuxPage = selinuxPage.selinuxPage(xml)
self.mainWindow.connect("destroy", self.destroy)
self.okButton.connect("clicked", self.okClicked)
self.cancelButton.connect("clicked", self.destroy)
self.applyButton.connect("clicked", self.applyClicked)
# Put labels on the notebook tabs since gazpacho doesn't provide a
# way to do that right now.
firewallLabel = gtk.Label(_("_Firewall Options"))
firewallLabel.set_use_underline(True)
self.notebook.set_tab_label(self.mainVBox, firewallLabel)
selinuxLabel = gtk.Label(_("_SELinux"))
selinuxLabel.set_use_underline(True)
self.notebook.set_tab_label(self.seLinuxVBox, selinuxLabel)
self.readFile()
self.mainWindow.show_all()
gtk.main()