Beispiel #1
0
void
pf_check_reload(struct context *c)
{
    const int slow_wakeup = 15;
    const int fast_wakeup = 1;
    const int wakeup_transition = 60;
    bool reloaded = false;

    if (c->c2.pf.enabled
        && c->c2.pf.filename
        && event_timeout_trigger(&c->c2.pf.reload, &c->c2.timeval, ETT_DEFAULT))
    {
        platform_stat_t s;
        if (!platform_stat(c->c2.pf.filename, &s))
        {
            if (s.st_mtime > c->c2.pf.file_last_mod)
            {
                struct pf_set *pfs = pf_init_from_file(c->c2.pf.filename);
                if (pfs)
                {
                    if (c->c2.pf.pfs)
                    {
                        pf_destroy(c->c2.pf.pfs);
                    }
                    c->c2.pf.pfs = pfs;
                    reloaded = true;
                    if (pf_kill_test(pfs))
                    {
                        c->sig->signal_received = SIGTERM;
                        c->sig->signal_text = "pf-kill";
                    }
                }
                c->c2.pf.file_last_mod = s.st_mtime;
            }
        }
        {
            int wakeup = slow_wakeup;
            if (!c->c2.pf.pfs && c->c2.pf.n_check_reload < wakeup_transition)
            {
                wakeup = fast_wakeup;
            }
            event_timeout_init(&c->c2.pf.reload, wakeup, now);
            reset_coarse_timers(c);
            c->c2.pf.n_check_reload++;
        }
    }
#ifdef ENABLE_DEBUG
    if (reloaded && check_debug_level(D_PF_DEBUG))
    {
        pf_context_print(&c->c2.pf, "pf_check_reload", D_PF_DEBUG);
    }
#endif
}
Beispiel #2
0
void
pf_destroy_context (struct pf_context *pfc)
{
#ifdef PLUGIN_PF
  if (pfc->filename)
    {
      delete_file (pfc->filename);
      free (pfc->filename);
    }
#endif
  if (pfc->pfs)
    pf_destroy (pfc->pfs);
}
Beispiel #3
0
void
pf_destroy_context (struct pf_context *pfc)
{
#ifdef PLUGIN_PF
  if (pfc->filename)
    {
      platform_unlink (pfc->filename);
      free (pfc->filename);
    }
#endif
  if (pfc->pfs)
    pf_destroy (pfc->pfs);
}
Beispiel #4
0
bool
pf_load_from_buffer_list (struct context *c, const struct buffer_list *config)
{
  struct pf_set *pfs = pf_init (config, "[SERVER-PF]", false);
  if (pfs)
    {
      if (c->c2.pf.pfs)
	pf_destroy (c->c2.pf.pfs);
      c->c2.pf.pfs = pfs;
      return true;
    }
  else
    return false;
}
Beispiel #5
0
static struct pf_set *
pf_init(const struct buffer_list *bl, const char *prefix, const bool allow_kill)
{
#define MODE_UNDEF   0
#define MODE_CLIENTS 1
#define MODE_SUBNETS 2
    int mode = MODE_UNDEF;
    int line_num = 0;
    int n_clients = 0;
    int n_subnets = 0;
    int n_errors = 0;
    struct pf_set *pfs = NULL;
    char line[PF_MAX_LINE_LEN];

    ALLOC_OBJ_CLEAR(pfs, struct pf_set);
    if (bl)
    {
        struct pf_cn_elem **cl = &pfs->cns.list;
        struct pf_subnet **sl = &pfs->sns.list;
        struct buffer_entry *be;

        for (be = bl->head; be != NULL; be = be->next)
        {
            ++line_num;
            strncpynt(line, BSTR(&be->buf), sizeof(line));
            rm_trailing_chars(line, "\r\n\t ");
            if (line[0] == '\0' || line[0] == '#')
            {
            }
            else if (line[0] == '+' || line[0] == '-')
            {
                bool exclude = (line[0] == '-');

                if (line[1] =='\0')
                {
                    msg(D_PF_INFO, "PF: %s/%d: no data after +/-: '%s'", prefix, line_num, line);
                    ++n_errors;
                }
                else if (mode == MODE_CLIENTS)
                {
                    if (add_client(&line[1], prefix, line_num, &cl, exclude))
                    {
                        ++n_clients;
                    }
                    else
                    {
                        ++n_errors;
                    }
                }
                else if (mode == MODE_SUBNETS)
                {
                    if (add_subnet(&line[1], prefix, line_num, &sl, exclude))
                    {
                        ++n_subnets;
                    }
                    else
                    {
                        ++n_errors;
                    }
                }
                else if (mode == MODE_UNDEF)
                {
                }
                else
                {
                    ASSERT(0);
                }
            }
            else if (line[0] == '[')
            {
                if (!strcasecmp(line, "[clients accept]"))
                {
                    mode = MODE_CLIENTS;
                    pfs->cns.default_allow = true;
                }
                else if (!strcasecmp(line, "[clients drop]"))
                {
                    mode = MODE_CLIENTS;
                    pfs->cns.default_allow = false;
                }
                else if (!strcasecmp(line, "[subnets accept]"))
                {
                    mode = MODE_SUBNETS;
                    pfs->sns.default_allow = true;
                }
                else if (!strcasecmp(line, "[subnets drop]"))
                {
                    mode = MODE_SUBNETS;
                    pfs->sns.default_allow = false;
                }
                else if (!strcasecmp(line, "[end]"))
                {
                    goto done;
                }
                else if (allow_kill && !strcasecmp(line, "[kill]"))
                {
                    goto kill;
                }
                else
                {
                    mode = MODE_UNDEF;
                    msg(D_PF_INFO, "PF: %s/%d unknown tag: '%s'", prefix, line_num, line);
                    ++n_errors;
                }
            }
            else
            {
                msg(D_PF_INFO, "PF: %s/%d line must begin with '+', '-', or '[' : '%s'", prefix, line_num, line);
                ++n_errors;
            }
        }
        ++n_errors;
        msg(D_PF_INFO, "PF: %s: missing [end]", prefix);
    }
    else
    {
        msg(D_PF_INFO, "PF: %s: cannot open", prefix);
        ++n_errors;
    }

done:
    if (bl)
    {
        if (!n_errors)
        {
            if (!genhash(&pfs->cns, prefix, n_clients))
            {
                ++n_errors;
            }
        }
        if (n_errors)
        {
            msg(D_PF_INFO, "PF: %s rejected due to %d error(s)", prefix, n_errors);
        }
    }
    if (n_errors)
    {
        pf_destroy(pfs);
        pfs = NULL;
    }
    return pfs;

kill:
    pf_destroy(pfs);
    ALLOC_OBJ_CLEAR(pfs, struct pf_set);
    pfs->kill = true;
    return pfs;
}