Blame src/firewalld

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()