|
Packit |
a8ec6b |
#!/bin/python
|
|
Packit |
a8ec6b |
# -*- coding: utf-8 -*-
|
|
Packit |
a8ec6b |
#
|
|
Packit |
a8ec6b |
# Copyright (C) 2010-2016 Red Hat, Inc.
|
|
Packit |
a8ec6b |
# Authors:
|
|
Packit |
a8ec6b |
# Thomas Woerner <twoerner@redhat.com>
|
|
Packit |
a8ec6b |
#
|
|
Packit |
a8ec6b |
# This program is free software; you can redistribute it and/or modify
|
|
Packit |
a8ec6b |
# it under the terms of the GNU General Public License as published by
|
|
Packit |
a8ec6b |
# the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
a8ec6b |
# (at your option) any later version.
|
|
Packit |
a8ec6b |
#
|
|
Packit |
a8ec6b |
# This program is distributed in the hope that it will be useful,
|
|
Packit |
a8ec6b |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
a8ec6b |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
a8ec6b |
# GNU General Public License for more details.
|
|
Packit |
a8ec6b |
#
|
|
Packit |
a8ec6b |
# You should have received a copy of the GNU General Public License
|
|
Packit |
a8ec6b |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
a8ec6b |
#
|
|
Packit |
a8ec6b |
# python fork magic derived from setroubleshoot
|
|
Packit |
a8ec6b |
# Copyright (C) 2006,2007,2008,2009 Red Hat, Inc.
|
|
Packit |
a8ec6b |
# Authors:
|
|
Packit |
a8ec6b |
# John Dennis <jdennis@redhat.com>
|
|
Packit |
a8ec6b |
# Dan Walsh <dwalsh@redhat.com>
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
import os
|
|
Packit |
a8ec6b |
import sys
|
|
Packit |
a8ec6b |
import dbus
|
|
Packit |
a8ec6b |
import traceback
|
|
Packit |
a8ec6b |
import argparse
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
from firewall import config
|
|
Packit |
a8ec6b |
from firewall.functions import firewalld_is_active
|
|
Packit |
a8ec6b |
from firewall.core.logger import log, FileLog
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
def parse_cmdline():
|
|
Packit |
a8ec6b |
parser = argparse.ArgumentParser()
|
|
Packit |
a8ec6b |
parser.add_argument('--debug',
|
|
Packit |
a8ec6b |
nargs='?', const=1, default=0, type=int,
|
|
Packit |
a8ec6b |
choices=range(1, log.DEBUG_MAX+1),
|
|
Packit |
a8ec6b |
help="""Enable logging of debug messages.
|
|
Packit |
a8ec6b |
Additional argument in range 1..%s can be used
|
|
Packit |
a8ec6b |
to specify log level.""" % log.DEBUG_MAX,
|
|
Packit |
a8ec6b |
metavar="level")
|
|
Packit |
a8ec6b |
parser.add_argument('--debug-gc',
|
|
Packit |
a8ec6b |
help="""Turn on garbage collector leak information.
|
|
Packit |
a8ec6b |
The collector runs every 10 seconds and if there are
|
|
Packit |
a8ec6b |
leaks, it prints information about the leaks.""",
|
|
Packit |
a8ec6b |
action="store_true")
|
|
Packit |
a8ec6b |
parser.add_argument('--nofork',
|
|
Packit |
a8ec6b |
help="""Turn off daemon forking,
|
|
Packit |
a8ec6b |
run as a foreground process.""",
|
|
Packit |
a8ec6b |
action="store_true")
|
|
Packit |
a8ec6b |
parser.add_argument('--nopid',
|
|
Packit |
a8ec6b |
help="""Disable writing pid file and don't check
|
|
Packit |
a8ec6b |
for existing server process.""",
|
|
Packit |
a8ec6b |
action="store_true")
|
|
Packit |
a8ec6b |
parser.add_argument('--system-config',
|
|
Packit |
a8ec6b |
help="""Path to firewalld system configuration""",
|
|
Packit |
a8ec6b |
metavar="path")
|
|
Packit |
a8ec6b |
parser.add_argument('--default-config',
|
|
Packit |
a8ec6b |
help="""Path to firewalld default configuration""",
|
|
Packit |
a8ec6b |
metavar="path")
|
|
Packit |
a8ec6b |
parser.add_argument('--log-file',
|
|
Packit |
a8ec6b |
help="""Path to firewalld log file""",
|
|
Packit |
a8ec6b |
metavar="path")
|
|
Packit |
a8ec6b |
return parser.parse_args()
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
def setup_logging(args):
|
|
Packit |
a8ec6b |
# Set up logging capabilities
|
|
Packit |
a8ec6b |
log.setDateFormat("%Y-%m-%d %H:%M:%S")
|
|
Packit |
a8ec6b |
log.setFormat("%(date)s %(label)s%(message)s")
|
|
Packit |
a8ec6b |
log.setInfoLogging("*", log.syslog, [ log.FATAL, log.ERROR, log.WARNING ],
|
|
Packit |
a8ec6b |
fmt="%(label)s%(message)s")
|
|
Packit |
a8ec6b |
log.setDebugLogLevel(log.NO_INFO)
|
|
Packit |
a8ec6b |
log.setDebugLogLevel(log.NO_DEBUG)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if args.debug:
|
|
Packit |
a8ec6b |
log.setInfoLogLevel(log.INFO_MAX)
|
|
Packit |
a8ec6b |
log.setDebugLogLevel(args.debug)
|
|
Packit |
a8ec6b |
if args.nofork:
|
|
Packit |
a8ec6b |
log.addInfoLogging("*", log.stdout)
|
|
Packit |
a8ec6b |
log.addDebugLogging("*", log.stdout)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
log_file = FileLog(config.FIREWALLD_LOGFILE, "a")
|
|
Packit |
a8ec6b |
try:
|
|
Packit |
a8ec6b |
log_file.open()
|
|
Packit |
a8ec6b |
except IOError as e:
|
|
Packit |
a8ec6b |
log.error("Failed to open log file '%s': %s", config.FIREWALLD_LOGFILE,
|
|
Packit |
a8ec6b |
str(e))
|
|
Packit |
a8ec6b |
else:
|
|
Packit |
a8ec6b |
log.addInfoLogging("*", log_file, [ log.FATAL, log.ERROR, log.WARNING ])
|
|
Packit |
a8ec6b |
log.addDebugLogging("*", log_file)
|
|
Packit |
a8ec6b |
if args.debug:
|
|
Packit |
a8ec6b |
log.addInfoLogging("*", log_file)
|
|
Packit |
a8ec6b |
log.addDebugLogging("*", log_file)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
def startup(args):
|
|
Packit |
a8ec6b |
try:
|
|
Packit |
a8ec6b |
if not args.nofork:
|
|
Packit |
a8ec6b |
# do the UNIX double-fork magic, see Stevens' "Advanced
|
|
Packit |
a8ec6b |
# Programming in the UNIX Environment" for details (ISBN 0201563177)
|
|
Packit |
a8ec6b |
pid = os.fork()
|
|
Packit |
a8ec6b |
if pid > 0:
|
|
Packit |
a8ec6b |
# exit first parent
|
|
Packit |
a8ec6b |
sys.exit(0)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# decouple from parent environment
|
|
Packit |
a8ec6b |
os.chdir("/")
|
|
Packit |
a8ec6b |
os.setsid()
|
|
Packit |
a8ec6b |
os.umask(os.umask(0o077) | 0o022)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# Do not close the file descriptors here anymore
|
|
Packit |
a8ec6b |
# File descriptors are now closed in runProg before execve
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# Redirect the standard I/O file descriptors to /dev/null
|
|
Packit |
a8ec6b |
if hasattr(os, "devnull"):
|
|
Packit |
a8ec6b |
REDIRECT_TO = os.devnull
|
|
Packit |
a8ec6b |
else:
|
|
Packit |
a8ec6b |
REDIRECT_TO = "/dev/null"
|
|
Packit |
a8ec6b |
fd = os.open(REDIRECT_TO, os.O_RDWR)
|
|
Packit |
a8ec6b |
os.dup2(fd, 0) # standard input (0)
|
|
Packit |
a8ec6b |
os.dup2(fd, 1) # standard output (1)
|
|
Packit |
a8ec6b |
os.dup2(fd, 2) # standard error (2)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if not args.nopid:
|
|
Packit |
a8ec6b |
# write the pid file
|
|
Packit |
a8ec6b |
with open(config.FIREWALLD_PIDFILE, "w") as f:
|
|
Packit |
a8ec6b |
f.write(str(os.getpid()))
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if not os.path.exists(config.FIREWALLD_TEMPDIR):
|
|
Packit |
a8ec6b |
os.mkdir(config.FIREWALLD_TEMPDIR, 0o750)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if args.system_config:
|
|
Packit |
a8ec6b |
config.set_system_config_paths(args.system_config)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if args.default_config:
|
|
Packit |
a8ec6b |
config.set_default_config_paths(args.default_config)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# Start the server mainloop here
|
|
Packit |
a8ec6b |
from firewall.server import server
|
|
Packit |
a8ec6b |
server.run_server(args.debug_gc)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# Clean up on exit
|
|
Packit |
a8ec6b |
if not args.nopid and os.path.exists(config.FIREWALLD_PIDFILE):
|
|
Packit |
a8ec6b |
os.remove(config.FIREWALLD_PIDFILE)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
except OSError as e:
|
|
Packit |
a8ec6b |
log.fatal("Fork #1 failed: %d (%s)" % (e.errno, e.strerror))
|
|
Packit |
a8ec6b |
log.error(traceback.format_exc())
|
|
Packit |
a8ec6b |
if not args.nopid and os.path.exists(config.FIREWALLD_PIDFILE):
|
|
Packit |
a8ec6b |
os.remove(config.FIREWALLD_PIDFILE)
|
|
Packit |
a8ec6b |
sys.exit(1)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
except dbus.exceptions.DBusException as e:
|
|
Packit |
a8ec6b |
log.fatal(str(e))
|
|
Packit |
a8ec6b |
log.error(traceback.format_exc())
|
|
Packit |
a8ec6b |
if not args.nopid and os.path.exists(config.FIREWALLD_PIDFILE):
|
|
Packit |
a8ec6b |
os.remove(config.FIREWALLD_PIDFILE)
|
|
Packit |
a8ec6b |
sys.exit(1)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
except IOError as e:
|
|
Packit |
a8ec6b |
log.fatal(str(e))
|
|
Packit |
a8ec6b |
log.error(traceback.format_exc())
|
|
Packit |
a8ec6b |
if not args.nopid and os.path.exists(config.FIREWALLD_PIDFILE):
|
|
Packit |
a8ec6b |
os.remove(config.FIREWALLD_PIDFILE)
|
|
Packit |
a8ec6b |
sys.exit(1)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
def main():
|
|
Packit |
a8ec6b |
# firewalld should only be run as the root user
|
|
Packit |
a8ec6b |
if os.getuid() != 0:
|
|
Packit |
a8ec6b |
print("You need to be root to run %s." % sys.argv[0])
|
|
Packit |
a8ec6b |
sys.exit(-1)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# Process the command-line arguments
|
|
Packit |
a8ec6b |
args = parse_cmdline()
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if args.log_file:
|
|
Packit |
a8ec6b |
config.FIREWALLD_LOGFILE = args.log_file
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
setup_logging(args)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
# Don't attempt to run two copies of firewalld simultaneously
|
|
Packit |
a8ec6b |
if not args.nopid and firewalld_is_active():
|
|
Packit |
a8ec6b |
log.fatal("Not starting FirewallD, already running.")
|
|
Packit |
a8ec6b |
sys.exit(1)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
startup(args)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
sys.exit(0)
|
|
Packit |
a8ec6b |
|
|
Packit |
a8ec6b |
if __name__ == '__main__':
|
|
Packit |
a8ec6b |
main()
|