summaryrefslogtreecommitdiff
path: root/src/openvpn/pf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/pf.c')
-rw-r--r--src/openvpn/pf.c1079
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) */