コード例 #1
0
ファイル: fwknopd.c プロジェクト: AsherBond/fwknop
void
clean_exit(fko_srv_options_t *opts, unsigned int fw_cleanup_flag, unsigned int exit_status)
{
    if(fw_cleanup_flag == FW_CLEANUP)
        fw_cleanup(opts);

#if USE_FILE_CACHE
    free_replay_list(opts);
#endif

    free_logging();
    free_configs(opts);
    exit(exit_status);
}
コード例 #2
0
ファイル: utils.c プロジェクト: PKRoma/fwknop
void
clean_exit(fko_srv_options_t *opts, unsigned int fw_cleanup_flag, unsigned int exit_status)
{
#if HAVE_LIBFIU
    if(opts->config[CONF_FAULT_INJECTION_TAG] != NULL)
    {
        fiu_disable(opts->config[CONF_FAULT_INJECTION_TAG]);
    }
#endif

    if(!opts->test && (fw_cleanup_flag == FW_CLEANUP))
        fw_cleanup(opts);

#if USE_FILE_CACHE
    free_replay_list(opts);
#endif

    free_logging();
    free_configs(opts);
    exit(exit_status);
}
コード例 #3
0
ファイル: fwknopd.c プロジェクト: maxkas/fwknop
int
main(int argc, char **argv)
{
    int                 res, last_sig, rp_cache_count;
    char               *locale;
    pid_t               old_pid;

    fko_srv_options_t   opts;

    while(1)
    {
        /* Handle command line
        */
        config_init(&opts, argc, argv);

        /* Process any options that do their thing and exit. */

        /* Kill the currently running fwknopd?
        */
        if(opts.kill == 1)
        {
            old_pid = get_running_pid(&opts);

            if(old_pid > 0)
            {
                res = kill(old_pid, SIGTERM);
                if(res == 0)
                {
                    fprintf(stderr, "Killed fwknopd (pid=%i)\n", old_pid);
                    exit(EXIT_SUCCESS);
                }
                else
                {
                    perror("Unable to kill fwknop: ");
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                fprintf(stderr, "No running fwknopd detected.\n");
                exit(EXIT_FAILURE);
            }
        }

        /* Status of the currently running fwknopd?
        */
        if(opts.status == 1)
        {
            old_pid = write_pid_file(&opts);

            if(old_pid > 0)
                fprintf(stderr, "Detected fwknopd is running (pid=%i).\n", old_pid);
            else
                fprintf(stderr, "No running fwknopd detected.\n");

            exit(EXIT_SUCCESS);
        }

        /* Restart the currently running fwknopd?
        */
        if(opts.restart == 1 || opts.status == 1)
        {
            old_pid = get_running_pid(&opts);

            if(old_pid > 0)
            {
                res = kill(old_pid, SIGHUP);
                if(res == 0)
                {
                    fprintf(stderr, "Sent restart signal to fwknopd (pid=%i)\n", old_pid);
                    exit(EXIT_SUCCESS);
                }
                else
                {
                    perror("Unable to send signal to fwknop: ");
                    exit(EXIT_FAILURE);
                }
            }
            else
            {
                fprintf(stderr, "No running fwknopd detected.\n");
                exit(EXIT_FAILURE);
            }
        }

        /* Initialize logging.
        */
        init_logging(&opts);

#if HAVE_LOCALE_H 
        /* Set the locale if specified. 
        */ 
        if(opts.config[CONF_LOCALE] != NULL
          && strncasecmp(opts.config[CONF_LOCALE], "NONE", 4) != 0) 
        { 
            locale = setlocale(LC_ALL, opts.config[CONF_LOCALE]); 
 
            if(locale == NULL) 
            { 
                log_msg(LOG_ERR, 
                    "WARNING: Unable to set locale to '%s'.", 
                    opts.config[CONF_LOCALE] 
                ); 
            } 
            else 
            { 
                if(opts.verbose) 
                    log_msg(LOG_INFO, 
                        "Locale set to '%s'.", opts.config[CONF_LOCALE] 
                    ); 
            } 
        } 
#endif 

        /* Make sure we have a valid run dir and path leading to digest file
         * in case it configured to be somewhere other than the run dir.
        */
        check_dir_path((const char *)opts.config[CONF_FWKNOP_RUN_DIR], "Run", 0);
#if USE_FILE_CACHE
        check_dir_path((const char *)opts.config[CONF_DIGEST_FILE], "Run", 1);
#else
        check_dir_path((const char *)opts.config[CONF_DIGEST_DB_FILE], "Run", 1);
#endif

        /* Process the access.conf file.
        */
        parse_access_file(&opts);

        /* Show config (including access.conf vars) and exit dump config was
         * wanted.
        */
        if(opts.dump_config == 1)
        {
            dump_config(&opts);
            dump_access_list(&opts);
            exit(EXIT_SUCCESS);
        }

        /* Initialize the firewall rules handler based on the fwknopd.conf
         * file, but (for iptables firewalls) don't flush any rules or create
         * any chains yet.  This allows us to dump the current firewall rules
         * via fw_rules_dump() in --fw-list mode before changing around any rules
         * of an existing fwknopd process.
        */
        fw_config_init(&opts);

        if(opts.fw_list == 1)
        {
            fw_dump_rules(&opts);
            exit(EXIT_SUCCESS);
        }

        /* If we are a new process (just being started), proceed with normal
         * start-up.  Otherwise, we are here as a result of a signal sent to an
         * existing process and we want to restart.
        */
        if(get_running_pid(&opts) != getpid())
        {
            /* If foreground mode is not set, the fork off and become a daemon.
            * Otherwise, attempt to get the pid file lock and go on.
            */
            if(opts.foreground == 0)
            {
                daemonize_process(&opts);
            }
            else
            {
                old_pid = write_pid_file(&opts);
                if(old_pid > 0)
                {
                    fprintf(stderr,
                        "* An instance of fwknopd is already running: (PID=%i).\n", old_pid
                    );

                    exit(EXIT_FAILURE);
                }
                else if(old_pid < 0)
                {
                    fprintf(stderr, "* PID file error. The lock may not be effective.\n");
                }
            }

            log_msg(LOG_INFO, "Starting %s", MY_NAME);
        }
        else
        {
            log_msg(LOG_INFO, "Re-starting %s", MY_NAME);
        }

        if(opts.verbose > 1 && opts.foreground)
        {
            dump_config(&opts);
            dump_access_list(&opts);
        }

        /* Initialize the digest cache for replay attack detection (either
         * with dbm support or with the default simple cache file strategy)
         * if so configured.
        */
        if(strncasecmp(opts.config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
        {
            rp_cache_count = replay_cache_init(&opts);

            if(rp_cache_count < 0)
            {
                log_msg(LOG_WARNING,
                    "Error opening digest cache file. Incoming digests will not be remembered."
                );
                strlcpy(opts.config[CONF_ENABLE_DIGEST_PERSISTENCE], "N", 2);
            }

            if(opts.verbose)
                log_msg(LOG_ERR,
                    "Using Digest Cache: '%s' (entry count = %i)",
#if USE_FILE_CACHE
                    opts.config[CONF_DIGEST_FILE], rp_cache_count
#else
                    opts.config[CONF_DIGEST_DB_FILE], rp_cache_count
#endif
                );
        }

        /* Prepare the firewall - i.e. flush any old rules and (for iptables)
         * create fwknop chains.
        */
        fw_initialize(&opts);

        /* If the TCP server option was set, fire it up here.
        */
        if(strncasecmp(opts.config[CONF_ENABLE_TCP_SERVER], "Y", 1) == 0)
        {
            if(atoi(opts.config[CONF_TCPSERV_PORT]) <= 0
              || atoi(opts.config[CONF_TCPSERV_PORT]) >  65535)
            {
                log_msg(LOG_WARNING,
                    "WARNING: ENABLE_TCP_SERVER is set, but TCPSERV_PORT is not valid. TCP server not started!"
                );
            }
            else
            {
                run_tcp_server(&opts);
            }
        }

        /* Intiate pcap capture mode...
        */
        pcap_capture(&opts);

        if(got_signal) {
            last_sig   = got_signal;
            got_signal = 0;

            if(got_sighup)
            {
                log_msg(LOG_WARNING, "Got SIGHUP.  Re-reading configs.");
                free_configs(&opts);
                kill(opts.tcp_server_pid, SIGTERM);
                usleep(1000000);
                got_sighup = 0;
            }
            else if(got_sigint)
            {
                log_msg(LOG_WARNING, "Got SIGINT.  Exiting...");
                got_sigint = 0;
                break;
            }
            else if(got_sigterm)
            {
                log_msg(LOG_WARNING, "Got SIGTERM.  Exiting...");
                got_sigterm = 0;
                break;
            }
            else
            {
                log_msg(LOG_WARNING,
                    "Got signal %i. No defined action but to exit.", last_sig);
                break;
            }
        }
        else if (opts.packet_ctr_limit > 0
            && opts.packet_ctr >= opts.packet_ctr_limit)
        {
            log_msg(LOG_INFO,
                "Packet count limit (%d) reached.  Exiting...",
                opts.packet_ctr_limit);
            break;
        }
        else    /* got_signal was not set (should be if we are here) */
        {
            log_msg(LOG_WARNING,
                "Capture ended without signal.  Exiting...");
            break;
        }
    }

    log_msg(LOG_INFO, "Shutting Down fwknopd.");

    /* Kill the TCP server (if we have one running).
    */
    if(opts.tcp_server_pid > 0)
    {
        log_msg(LOG_INFO, "Killing the TCP server (pid=%i)",
            opts.tcp_server_pid);

        kill(opts.tcp_server_pid, SIGTERM);

        /* --DSS XXX: This seems to be necessary if the tcp server
         *            was restarted by this program.  We need to
         *            investigate and fix this. For now, this works
         *            (it is kludgy, but does no harm afaik).
        */
        kill(opts.tcp_server_pid, SIGKILL);
    }

    /* Other cleanup.
    */
    fw_cleanup();
    free_logging();

#if USE_FILE_CACHE
    free_replay_list(&opts);
#endif

    free_configs(&opts);

    return(0);
}
コード例 #4
0
ファイル: fw_util_ipfw.c プロジェクト: AsherBond/fwknop
void
fw_initialize(const fko_srv_options_t *opts)
{
    int             res = 0;
    unsigned short  curr_rule;
    char           *ndx;

    /* For now, we just call fw_cleanup to start with clean slate.
    */
    if(strncasecmp(opts->config[CONF_FLUSH_IPFW_AT_INIT], "Y", 1) == 0)
        res = fw_cleanup(opts);

    if(res != 0)
    {
        fprintf(stderr, "Fatal: Errors detected during ipfw rules initialization.\n");
        exit(EXIT_FAILURE);
    }

    /* Allocate our rule_map array for tracking active (and expired) rules.
    */
    fwc.rule_map = calloc(fwc.max_rules, sizeof(char));

    if(fwc.rule_map == NULL)
    {
        fprintf(stderr, "Fatal: Memory allocation error in fw_initialize.\n");
        exit(EXIT_FAILURE);
    }

    /* Create a check-state rule if necessary.
    */
    if(strncasecmp(opts->config[CONF_IPFW_ADD_CHECK_STATE], "Y", 1) == 0)
    {
        zero_cmd_buffers();

        snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPFW_ADD_CHECK_STATE_ARGS,
            fwc.fw_command,
            fwc.start_rule_num,
            fwc.active_set_num
        );

        res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);

        if (opts->verbose)
            log_msg(LOG_INFO, "fw_initialize() CMD: '%s' (res: %d, err: %s)",
                cmd_buf, res, err_buf);

        if(EXTCMD_IS_SUCCESS(res))
        {
            log_msg(LOG_INFO, "Added check-state rule %u to set %u",
                fwc.start_rule_num,
                fwc.active_set_num
            );

            fwc.rule_map[0] = RULE_ACTIVE;
        }
        else
            log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
    }

    if(fwc.expire_set_num > 0
            && (strncasecmp(opts->config[CONF_FLUSH_IPFW_AT_INIT], "Y", 1) == 0))
    {
        /* Make sure our expire set is disabled.
        */
        zero_cmd_buffers();

        snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPFW_DISABLE_SET_ARGS,
            fwc.fw_command,
            fwc.expire_set_num
        );

        res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);

        if (opts->verbose)
            log_msg(LOG_INFO, "fw_initialize() CMD: '%s' (res: %d, err: %s)",
                cmd_buf, res, err_buf);

        if(EXTCMD_IS_SUCCESS(res))
            log_msg(LOG_INFO, "Set ipfw expire set %u to disabled.",
                fwc.expire_set_num);
        else
            log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
    }

    /* Now read the expire set in case there are existing
     * rules to track.
    */
    zero_cmd_buffers();

    snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPFW_LIST_EXP_SET_RULES_ARGS,
        opts->fw_config->fw_command,
        fwc.expire_set_num
    );

    res = run_extcmd(cmd_buf, cmd_out, STANDARD_CMD_OUT_BUFSIZE, 0);

    if (opts->verbose)
        log_msg(LOG_INFO, "fw_initialize() CMD: '%s' (res: %d)",
            cmd_buf, res);

    if(!EXTCMD_IS_SUCCESS(res))
    {
        log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, cmd_out);
        return;
    }

    if(opts->verbose > 1)
        log_msg(LOG_INFO, "RULES LIST: %s", cmd_out);

    /* Find the first "# DISABLED" string (if any).
    */
    ndx = strstr(cmd_out, "# DISABLED ");

    /* Assume no disabled rules if we did not see the string.
    */
    if(ndx == NULL)
        return;

    /* Otherwise we walk each line to pull the rule number and
     * set the appropriate rule map entries.
    */
    while(ndx != NULL)
    {
        /* Skip over the DISABLED string to the rule num.
        */
        ndx += 11;

        if(isdigit(*ndx))
        {
            curr_rule = atoi(ndx);

            if(curr_rule >= fwc.start_rule_num
              && curr_rule < fwc.start_rule_num + fwc.max_rules)
            {
                fwc.rule_map[curr_rule - fwc.start_rule_num] = RULE_EXPIRED;
                fwc.total_rules++;
            }
        }
        else
            log_msg(LOG_WARNING, "fw_initialize: No rule number found where expected.");

        /* Find the next "# DISABLED" string (if any).
        */
        ndx = strstr(ndx, "# DISABLED ");
    }
}