diff options
author | Alberto Gonzalez Iniesta <agi@inittab.org> | 2016-12-27 18:25:47 +0100 |
---|---|---|
committer | Alberto Gonzalez Iniesta <agi@inittab.org> | 2016-12-27 18:25:47 +0100 |
commit | 79f3537f69e125f19f59c36aa090120a63186a54 (patch) | |
tree | 2089a3b7dac990841dbc2e4d9b2f535b82dbb0af /src/openvpn/pf.c | |
parent | f2137fedb30cb87448eb03b2f288920df6187571 (diff) | |
parent | 3a2bbdb05ca6a6996e424c9fb225cb0d53804125 (diff) |
Merge tag 'upstream/2.4.0'
Upstream version 2.4.0
Diffstat (limited to 'src/openvpn/pf.c')
-rw-r--r-- | src/openvpn/pf.c | 1079 |
1 files changed, 572 insertions, 507 deletions
diff --git a/src/openvpn/pf.c b/src/openvpn/pf.c index a3208db..56b6858 100644 --- a/src/openvpn/pf.c +++ b/src/openvpn/pf.c @@ -5,7 +5,7 @@ * packet encryption, packet authentication, and * packet compression. * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> + * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 @@ -41,285 +41,307 @@ #include "pf-inline.h" static void -pf_destroy (struct pf_set *pfs) +pf_destroy(struct pf_set *pfs) { - if (pfs) - { - if (pfs->cns.hash_table) - hash_free (pfs->cns.hash_table); - - { - struct pf_cn_elem *l = pfs->cns.list; - while (l) - { - struct pf_cn_elem *next = l->next; - free (l->rule.cn); - free (l); - l = next; - } - } - { - struct pf_subnet *l = pfs->sns.list; - while (l) - { - struct pf_subnet *next = l->next; - free (l); - l = next; - } - } - free (pfs); + if (pfs) + { + if (pfs->cns.hash_table) + { + hash_free(pfs->cns.hash_table); + } + + { + struct pf_cn_elem *l = pfs->cns.list; + while (l) + { + struct pf_cn_elem *next = l->next; + free(l->rule.cn); + free(l); + l = next; + } + } + { + struct pf_subnet *l = pfs->sns.list; + while (l) + { + struct pf_subnet *next = l->next; + free(l); + l = next; + } + } + free(pfs); } } static bool -add_client (const char *line, const char *prefix, const int line_num, struct pf_cn_elem ***next, const bool exclude) +add_client(const char *line, const char *prefix, const int line_num, struct pf_cn_elem ***next, const bool exclude) { - struct pf_cn_elem *e; - ALLOC_OBJ_CLEAR (e, struct pf_cn_elem); - e->rule.exclude = exclude; - e->rule.cn = string_alloc (line, NULL); - **next = e; - *next = &e->next; - return true; + struct pf_cn_elem *e; + ALLOC_OBJ_CLEAR(e, struct pf_cn_elem); + e->rule.exclude = exclude; + e->rule.cn = string_alloc(line, NULL); + **next = e; + *next = &e->next; + return true; } static bool -add_subnet (const char *line, const char *prefix, const int line_num, struct pf_subnet ***next, const bool exclude) +add_subnet(const char *line, const char *prefix, const int line_num, struct pf_subnet ***next, const bool exclude) { - struct in_addr network; - in_addr_t netmask = 0; - - if (strcmp (line, "unknown")) - { - int netbits = 32; - char *div = strchr (line, '/'); - - if (div) - { - *div++ = '\0'; - if (sscanf (div, "%d", &netbits) != 1) - { - msg (D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: '%s'", prefix, line_num, div); - return false; - } - if (netbits < 0 || netbits > 32) - { - msg (D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", prefix, line_num, div); - return false; - } - } - - if (openvpn_inet_aton (line, &network) != OIA_IP) - { - msg (D_PF_INFO, "PF: %s/%d: bad network address: '%s'", prefix, line_num, line); - return false; - } - netmask = netbits_to_netmask (netbits); - if ((network.s_addr & htonl (netmask)) != network.s_addr) + struct in_addr network; + in_addr_t netmask = 0; + + if (strcmp(line, "unknown")) + { + int netbits = 32; + char *div = strchr(line, '/'); + + if (div) + { + *div++ = '\0'; + if (sscanf(div, "%d", &netbits) != 1) + { + msg(D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: '%s'", prefix, line_num, div); + return false; + } + if (netbits < 0 || netbits > 32) + { + msg(D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", prefix, line_num, div); + return false; + } + } + + if (openvpn_inet_aton(line, &network) != OIA_IP) + { + msg(D_PF_INFO, "PF: %s/%d: bad network address: '%s'", prefix, line_num, line); + return false; + } + netmask = netbits_to_netmask(netbits); + if ((network.s_addr & htonl(netmask)) != network.s_addr) { - network.s_addr &= htonl (netmask); - msg (M_WARN, "WARNING: PF: %s/%d: incorrect subnet %s/%d changed to %s/%d", prefix, line_num, line, netbits, inet_ntoa (network), netbits); + network.s_addr &= htonl(netmask); + msg(M_WARN, "WARNING: PF: %s/%d: incorrect subnet %s/%d changed to %s/%d", prefix, line_num, line, netbits, inet_ntoa(network), netbits); } } - else + else { - /* match special "unknown" tag for addresses unrecognized by mroute */ - network.s_addr = htonl(0); - netmask = IPV4_NETMASK_HOST; + /* match special "unknown" tag for addresses unrecognized by mroute */ + network.s_addr = htonl(0); + netmask = IPV4_NETMASK_HOST; } - { - struct pf_subnet *e; - ALLOC_OBJ_CLEAR (e, struct pf_subnet); - e->rule.exclude = exclude; - e->rule.network = ntohl (network.s_addr); - e->rule.netmask = netmask; - **next = e; - *next = &e->next; - return true; - } + { + struct pf_subnet *e; + ALLOC_OBJ_CLEAR(e, struct pf_subnet); + e->rule.exclude = exclude; + e->rule.network = ntohl(network.s_addr); + e->rule.netmask = netmask; + **next = e; + *next = &e->next; + return true; + } } static uint32_t -cn_hash_function (const void *key, uint32_t iv) +cn_hash_function(const void *key, uint32_t iv) { - return hash_func ((uint8_t *)key, strlen ((char *)key) + 1, iv); + return hash_func((uint8_t *)key, strlen((char *)key) + 1, iv); } static bool -cn_compare_function (const void *key1, const void *key2) +cn_compare_function(const void *key1, const void *key2) { - return !strcmp((const char *)key1, (const char *)key2); + return !strcmp((const char *)key1, (const char *)key2); } static bool -genhash (struct pf_cn_set *cns, const char *prefix, const int n_clients) +genhash(struct pf_cn_set *cns, const char *prefix, const int n_clients) { - struct pf_cn_elem *e; - bool status = true; - int n_buckets = n_clients; - - if (n_buckets < 16) - n_buckets = 16; - cns->hash_table = hash_init (n_buckets, 0, cn_hash_function, cn_compare_function); - for (e = cns->list; e != NULL; e = e->next) - { - if (!hash_add (cns->hash_table, e->rule.cn, &e->rule, false)) - { - msg (D_PF_INFO, "PF: %s: duplicate common name in [clients] section: '%s'", prefix, e->rule.cn); - status = false; - } - } - - return status; + struct pf_cn_elem *e; + bool status = true; + int n_buckets = n_clients; + + if (n_buckets < 16) + { + n_buckets = 16; + } + cns->hash_table = hash_init(n_buckets, 0, cn_hash_function, cn_compare_function); + for (e = cns->list; e != NULL; e = e->next) + { + if (!hash_add(cns->hash_table, e->rule.cn, &e->rule, false)) + { + msg(D_PF_INFO, "PF: %s: duplicate common name in [clients] section: '%s'", prefix, e->rule.cn); + status = false; + } + } + + return status; } static struct pf_set * -pf_init (const struct buffer_list *bl, const char *prefix, const bool allow_kill) +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; +#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; } #ifdef PLUGIN_PF static struct pf_set * -pf_init_from_file (const char *fn) +pf_init_from_file(const char *fn) { - struct buffer_list *bl = buffer_list_file (fn, PF_MAX_LINE_LEN); - if (bl) + struct buffer_list *bl = buffer_list_file(fn, PF_MAX_LINE_LEN); + if (bl) { - struct pf_set *pfs = pf_init (bl, fn, true); - buffer_list_free (bl); - return pfs; + struct pf_set *pfs = pf_init(bl, fn, true); + buffer_list_free(bl); + return pfs; } - else + else { - msg (D_PF_INFO|M_ERRNO, "PF: %s: cannot open", fn); - return NULL; + msg(D_PF_INFO|M_ERRNO, "PF: %s: cannot open", fn); + return NULL; } } #endif @@ -327,390 +349,433 @@ pf_init_from_file (const char *fn) #ifdef ENABLE_DEBUG static const char * -drop_accept (const bool accept) +drop_accept(const bool accept) { - return accept ? "ACCEPT" : "DROP"; + return accept ? "ACCEPT" : "DROP"; } static const char * -pct_name (const int type) +pct_name(const int type) { - switch (type) + switch (type) { - case PCT_SRC: - return "SRC"; - case PCT_DEST: - return "DEST"; - default: - return "???"; + case PCT_SRC: + return "SRC"; + + case PCT_DEST: + return "DEST"; + + default: + return "???"; } } static void -pf_cn_test_print (const char *prefix, - const int type, - const char *prefix2, - const char *cn, - const bool allow, - const struct pf_cn *rule) +pf_cn_test_print(const char *prefix, + const int type, + const char *prefix2, + const char *cn, + const bool allow, + const struct pf_cn *rule) { - if (rule) + if (rule) { - dmsg (D_PF_DEBUG, "PF: %s/%s/%s %s %s rule=[%s %s]", - prefix, prefix2, pct_name (type), - cn, drop_accept (allow), - rule->cn, drop_accept (!rule->exclude)); + dmsg(D_PF_DEBUG, "PF: %s/%s/%s %s %s rule=[%s %s]", + prefix, prefix2, pct_name(type), + cn, drop_accept(allow), + rule->cn, drop_accept(!rule->exclude)); } - else + else { - dmsg (D_PF_DEBUG, "PF: %s/%s/%s %s %s", - prefix, prefix2, pct_name (type), - cn, drop_accept (allow)); + dmsg(D_PF_DEBUG, "PF: %s/%s/%s %s %s", + prefix, prefix2, pct_name(type), + cn, drop_accept(allow)); } } static void -pf_addr_test_print (const char *prefix, - const char *prefix2, - const struct context *src, - const struct mroute_addr *dest, - const bool allow, - const struct ipv4_subnet *rule) +pf_addr_test_print(const char *prefix, + const char *prefix2, + const struct context *src, + const struct mroute_addr *dest, + const bool allow, + const struct ipv4_subnet *rule) { - struct gc_arena gc = gc_new (); - if (rule) - { - dmsg (D_PF_DEBUG, "PF: %s/%s %s %s %s rule=[%s/%s %s]", - prefix, - prefix2, - tls_common_name (src->c2.tls_multi, false), - mroute_addr_print_ex (dest, MAPF_SHOW_ARP, &gc), - drop_accept (allow), - print_in_addr_t (rule->network, 0, &gc), - print_in_addr_t (rule->netmask, 0, &gc), - drop_accept (!rule->exclude)); - } - else - { - dmsg (D_PF_DEBUG, "PF: %s/%s %s %s %s", - prefix, - prefix2, - tls_common_name (src->c2.tls_multi, false), - mroute_addr_print_ex (dest, MAPF_SHOW_ARP, &gc), - drop_accept (allow)); - } - gc_free (&gc); + struct gc_arena gc = gc_new(); + if (rule) + { + dmsg(D_PF_DEBUG, "PF: %s/%s %s %s %s rule=[%s/%s %s]", + prefix, + prefix2, + tls_common_name(src->c2.tls_multi, false), + mroute_addr_print_ex(dest, MAPF_SHOW_ARP, &gc), + drop_accept(allow), + print_in_addr_t(rule->network, 0, &gc), + print_in_addr_t(rule->netmask, 0, &gc), + drop_accept(!rule->exclude)); + } + else + { + dmsg(D_PF_DEBUG, "PF: %s/%s %s %s %s", + prefix, + prefix2, + tls_common_name(src->c2.tls_multi, false), + mroute_addr_print_ex(dest, MAPF_SHOW_ARP, &gc), + drop_accept(allow)); + } + gc_free(&gc); } -#endif +#endif /* ifdef ENABLE_DEBUG */ static inline struct pf_cn * -lookup_cn_rule (struct hash *h, const char *cn, const uint32_t cn_hash) +lookup_cn_rule(struct hash *h, const char *cn, const uint32_t cn_hash) { - struct hash_element *he = hash_lookup_fast (h, hash_bucket (h, cn_hash), cn, cn_hash); - if (he) - return (struct pf_cn *) he->value; - else - return NULL; + struct hash_element *he = hash_lookup_fast(h, hash_bucket(h, cn_hash), cn, cn_hash); + if (he) + { + return (struct pf_cn *) he->value; + } + else + { + return NULL; + } } bool -pf_cn_test (struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix) +pf_cn_test(struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix) { - if (pfs && !pfs->kill) - { - const char *cn; - uint32_t cn_hash; - if (tls_common_name_hash (tm, &cn, &cn_hash)) - { - const struct pf_cn *rule = lookup_cn_rule (pfs->cns.hash_table, cn, cn_hash); - if (rule) - { + if (pfs && !pfs->kill) + { + const char *cn; + uint32_t cn_hash; + if (tls_common_name_hash(tm, &cn, &cn_hash)) + { + const struct pf_cn *rule = lookup_cn_rule(pfs->cns.hash_table, cn, cn_hash); + if (rule) + { #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_cn_test_print ("PF_CN_MATCH", type, prefix, cn, !rule->exclude, rule); + if (check_debug_level(D_PF_DEBUG)) + { + pf_cn_test_print("PF_CN_MATCH", type, prefix, cn, !rule->exclude, rule); + } #endif - if (!rule->exclude) - return true; - else - return false; - } - else - { + if (!rule->exclude) + { + return true; + } + else + { + return false; + } + } + else + { #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_cn_test_print ("PF_CN_DEFAULT", type, prefix, cn, pfs->cns.default_allow, NULL); + if (check_debug_level(D_PF_DEBUG)) + { + pf_cn_test_print("PF_CN_DEFAULT", type, prefix, cn, pfs->cns.default_allow, NULL); + } #endif - if (pfs->cns.default_allow) - return true; - else - return false; - } - } + if (pfs->cns.default_allow) + { + return true; + } + else + { + return false; + } + } + } } #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_cn_test_print ("PF_CN_FAULT", type, prefix, tls_common_name (tm, false), false, NULL); + if (check_debug_level(D_PF_DEBUG)) + { + pf_cn_test_print("PF_CN_FAULT", type, prefix, tls_common_name(tm, false), false, NULL); + } #endif - return false; + return false; } bool -pf_addr_test_dowork (const struct context *src, const struct mroute_addr *dest, const char *prefix) +pf_addr_test_dowork(const struct context *src, const struct mroute_addr *dest, const char *prefix) { - struct pf_set *pfs = src->c2.pf.pfs; - if (pfs && !pfs->kill) - { - const in_addr_t addr = in_addr_t_from_mroute_addr (dest); - const struct pf_subnet *se = pfs->sns.list; - while (se) - { - if ((addr & se->rule.netmask) == se->rule.network) - { + struct pf_set *pfs = src->c2.pf.pfs; + if (pfs && !pfs->kill) + { + const in_addr_t addr = in_addr_t_from_mroute_addr(dest); + const struct pf_subnet *se = pfs->sns.list; + while (se) + { + if ((addr & se->rule.netmask) == se->rule.network) + { #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_addr_test_print ("PF_ADDR_MATCH", prefix, src, dest, !se->rule.exclude, &se->rule); + if (check_debug_level(D_PF_DEBUG)) + { + pf_addr_test_print("PF_ADDR_MATCH", prefix, src, dest, !se->rule.exclude, &se->rule); + } #endif - return !se->rule.exclude; - } - se = se->next; - } + return !se->rule.exclude; + } + se = se->next; + } #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_addr_test_print ("PF_ADDR_DEFAULT", prefix, src, dest, pfs->sns.default_allow, NULL); + if (check_debug_level(D_PF_DEBUG)) + { + pf_addr_test_print("PF_ADDR_DEFAULT", prefix, src, dest, pfs->sns.default_allow, NULL); + } #endif - return pfs->sns.default_allow; + return pfs->sns.default_allow; } - else + else { #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_addr_test_print ("PF_ADDR_FAULT", prefix, src, dest, false, NULL); + if (check_debug_level(D_PF_DEBUG)) + { + pf_addr_test_print("PF_ADDR_FAULT", prefix, src, dest, false, NULL); + } #endif - return false; + return false; } } #ifdef PLUGIN_PF void -pf_check_reload (struct context *c) +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++; - } + 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); + if (reloaded && check_debug_level(D_PF_DEBUG)) + { + pf_context_print(&c->c2.pf, "pf_check_reload", D_PF_DEBUG); + } #endif } -#endif +#endif /* ifdef PLUGIN_PF */ #ifdef MANAGEMENT_PF bool -pf_load_from_buffer_list (struct context *c, const struct buffer_list *config) +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) + 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; + if (c->c2.pf.pfs) + { + pf_destroy(c->c2.pf.pfs); + } + c->c2.pf.pfs = pfs; + return true; + } + else + { + return false; } - else - return false; } #endif void -pf_init_context (struct context *c) +pf_init_context(struct context *c) { - struct gc_arena gc = gc_new (); + struct gc_arena gc = gc_new(); #ifdef PLUGIN_PF - if (plugin_defined (c->plugins, OPENVPN_PLUGIN_ENABLE_PF)) + if (plugin_defined(c->plugins, OPENVPN_PLUGIN_ENABLE_PF)) { - const char *pf_file = create_temp_file (c->options.tmp_dir, "pf", &gc); - if( pf_file ) { - setenv_str (c->c2.es, "pf_file", pf_file); + const char *pf_file = create_temp_file(c->options.tmp_dir, "pf", &gc); + if (pf_file) + { + setenv_str(c->c2.es, "pf_file", pf_file); - if (plugin_call (c->plugins, OPENVPN_PLUGIN_ENABLE_PF, NULL, NULL, c->c2.es) == OPENVPN_PLUGIN_FUNC_SUCCESS) - { - event_timeout_init (&c->c2.pf.reload, 1, now); - c->c2.pf.filename = string_alloc (pf_file, &c->c2.gc); - c->c2.pf.enabled = true; + if (plugin_call(c->plugins, OPENVPN_PLUGIN_ENABLE_PF, NULL, NULL, c->c2.es) == OPENVPN_PLUGIN_FUNC_SUCCESS) + { + event_timeout_init(&c->c2.pf.reload, 1, now); + c->c2.pf.filename = string_alloc(pf_file, &c->c2.gc); + c->c2.pf.enabled = true; #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_context_print (&c->c2.pf, "pf_init_context#1", D_PF_DEBUG); + if (check_debug_level(D_PF_DEBUG)) + { + pf_context_print(&c->c2.pf, "pf_init_context#1", D_PF_DEBUG); + } #endif - } - else - { - msg (M_WARN, "WARNING: OPENVPN_PLUGIN_ENABLE_PF disabled"); - } - } + } + else + { + msg(M_WARN, "WARNING: OPENVPN_PLUGIN_ENABLE_PF disabled"); + } + } } -#endif +#endif /* ifdef PLUGIN_PF */ #ifdef MANAGEMENT_PF - if (!c->c2.pf.enabled && management_enable_pf (management)) + if (!c->c2.pf.enabled && management_enable_pf(management)) { - c->c2.pf.enabled = true; + c->c2.pf.enabled = true; #ifdef ENABLE_DEBUG - if (check_debug_level (D_PF_DEBUG)) - pf_context_print (&c->c2.pf, "pf_init_context#2", D_PF_DEBUG); + if (check_debug_level(D_PF_DEBUG)) + { + pf_context_print(&c->c2.pf, "pf_init_context#2", D_PF_DEBUG); + } #endif } #endif - gc_free (&gc); + gc_free(&gc); } void -pf_destroy_context (struct pf_context *pfc) +pf_destroy_context(struct pf_context *pfc) { #ifdef PLUGIN_PF - if (pfc->filename) + if (pfc->filename) { - platform_unlink (pfc->filename); + platform_unlink(pfc->filename); } #endif - if (pfc->pfs) - pf_destroy (pfc->pfs); + if (pfc->pfs) + { + pf_destroy(pfc->pfs); + } } #ifdef ENABLE_DEBUG static void -pf_subnet_set_print (const struct pf_subnet_set *s, const int lev) +pf_subnet_set_print(const struct pf_subnet_set *s, const int lev) { - struct gc_arena gc = gc_new (); - if (s) + struct gc_arena gc = gc_new(); + if (s) { - struct pf_subnet *e; + struct pf_subnet *e; - msg (lev, " ----- struct pf_subnet_set -----"); - msg (lev, " default_allow=%s", drop_accept (s->default_allow)); + msg(lev, " ----- struct pf_subnet_set -----"); + msg(lev, " default_allow=%s", drop_accept(s->default_allow)); - for (e = s->list; e != NULL; e = e->next) - { - msg (lev, " %s/%s %s", - print_in_addr_t (e->rule.network, 0, &gc), - print_in_addr_t (e->rule.netmask, 0, &gc), - drop_accept (!e->rule.exclude)); - } + for (e = s->list; e != NULL; e = e->next) + { + msg(lev, " %s/%s %s", + print_in_addr_t(e->rule.network, 0, &gc), + print_in_addr_t(e->rule.netmask, 0, &gc), + drop_accept(!e->rule.exclude)); + } } - gc_free (&gc); + gc_free(&gc); } static void -pf_cn_set_print (const struct pf_cn_set *s, const int lev) +pf_cn_set_print(const struct pf_cn_set *s, const int lev) { - if (s) - { - struct hash_iterator hi; - struct hash_element *he; - - msg (lev, " ----- struct pf_cn_set -----"); - msg (lev, " default_allow=%s", drop_accept (s->default_allow)); - - if (s->hash_table) - { - hash_iterator_init (s->hash_table, &hi); - while ((he = hash_iterator_next (&hi))) - { - struct pf_cn *e = (struct pf_cn *)he->value; - msg (lev, " %s %s", - e->cn, - drop_accept (!e->exclude)); - } - - msg (lev, " ----------"); - - { - struct pf_cn_elem *ce; - for (ce = s->list; ce != NULL; ce = ce->next) - { - struct pf_cn *e = lookup_cn_rule (s->hash_table, ce->rule.cn, cn_hash_function (ce->rule.cn, 0)); - if (e) - { - msg (lev, " %s %s", - e->cn, - drop_accept (!e->exclude)); - } - else - { - msg (lev, " %s LOOKUP FAILED", ce->rule.cn); - } - } - } - } + if (s) + { + struct hash_iterator hi; + struct hash_element *he; + + msg(lev, " ----- struct pf_cn_set -----"); + msg(lev, " default_allow=%s", drop_accept(s->default_allow)); + + if (s->hash_table) + { + hash_iterator_init(s->hash_table, &hi); + while ((he = hash_iterator_next(&hi))) + { + struct pf_cn *e = (struct pf_cn *)he->value; + msg(lev, " %s %s", + e->cn, + drop_accept(!e->exclude)); + } + + msg(lev, " ----------"); + + { + struct pf_cn_elem *ce; + for (ce = s->list; ce != NULL; ce = ce->next) + { + struct pf_cn *e = lookup_cn_rule(s->hash_table, ce->rule.cn, cn_hash_function(ce->rule.cn, 0)); + if (e) + { + msg(lev, " %s %s", + e->cn, + drop_accept(!e->exclude)); + } + else + { + msg(lev, " %s LOOKUP FAILED", ce->rule.cn); + } + } + } + } } } static void -pf_set_print (const struct pf_set *pfs, const int lev) +pf_set_print(const struct pf_set *pfs, const int lev) { - if (pfs) + if (pfs) { - msg (lev, " ----- struct pf_set -----"); - msg (lev, " kill=%d", pfs->kill); - pf_subnet_set_print (&pfs->sns, lev); - pf_cn_set_print (&pfs->cns, lev); + msg(lev, " ----- struct pf_set -----"); + msg(lev, " kill=%d", pfs->kill); + pf_subnet_set_print(&pfs->sns, lev); + pf_cn_set_print(&pfs->cns, lev); } } void -pf_context_print (const struct pf_context *pfc, const char *prefix, const int lev) +pf_context_print(const struct pf_context *pfc, const char *prefix, const int lev) { - msg (lev, "----- %s : struct pf_context -----", prefix); - if (pfc) + msg(lev, "----- %s : struct pf_context -----", prefix); + if (pfc) { - msg (lev, "enabled=%d", pfc->enabled); + msg(lev, "enabled=%d", pfc->enabled); #ifdef PLUGIN_PF - msg (lev, "filename='%s'", np(pfc->filename)); - msg (lev, "file_last_mod=%u", (unsigned int)pfc->file_last_mod); - msg (lev, "n_check_reload=%u", pfc->n_check_reload); - msg (lev, "reload=[%d,%u,%u]", pfc->reload.defined, pfc->reload.n, (unsigned int)pfc->reload.last); + msg(lev, "filename='%s'", np(pfc->filename)); + msg(lev, "file_last_mod=%u", (unsigned int)pfc->file_last_mod); + msg(lev, "n_check_reload=%u", pfc->n_check_reload); + msg(lev, "reload=[%d,%u,%u]", pfc->reload.defined, pfc->reload.n, (unsigned int)pfc->reload.last); #endif - pf_set_print (pfc->pfs, lev); + pf_set_print(pfc->pfs, lev); } - msg (lev, "--------------------"); + msg(lev, "--------------------"); } -#endif +#endif /* ifdef ENABLE_DEBUG */ -#endif +#endif /* if defined(ENABLE_PF) */ |