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 }
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); }
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); }
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; }
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; }