OpenVPN
pf.c
Go to the documentation of this file.
1 /*
2  * OpenVPN -- An application to securely tunnel IP networks
3  * over a single TCP/UDP port, with support for SSL/TLS-based
4  * session authentication and key exchange,
5  * packet encryption, packet authentication, and
6  * packet compression.
7  *
8  * Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2
12  * as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23 
24 /* packet filter functions */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #elif defined(_MSC_VER)
29 #include "config-msvc.h"
30 #endif
31 
32 #include "syshead.h"
33 
34 #if defined(ENABLE_PF)
35 
36 #include "init.h"
37 #include "memdbg.h"
38 #include "pf.h"
39 #include "ssl_verify.h"
40 
41 
42 static void
43 pf_destroy(struct pf_set *pfs)
44 {
45  if (pfs)
46  {
47  if (pfs->cns.hash_table)
48  {
49  hash_free(pfs->cns.hash_table);
50  }
51 
52  {
53  struct pf_cn_elem *l = pfs->cns.list;
54  while (l)
55  {
56  struct pf_cn_elem *next = l->next;
57  free(l->rule.cn);
58  free(l);
59  l = next;
60  }
61  }
62  {
63  struct pf_subnet *l = pfs->sns.list;
64  while (l)
65  {
66  struct pf_subnet *next = l->next;
67  free(l);
68  l = next;
69  }
70  }
71  free(pfs);
72  }
73 }
74 
75 static bool
76 add_client(const char *line, const char *prefix, const int line_num, struct pf_cn_elem ***next, const bool exclude)
77 {
78  struct pf_cn_elem *e;
79  ALLOC_OBJ_CLEAR(e, struct pf_cn_elem);
80  e->rule.exclude = exclude;
81  e->rule.cn = string_alloc(line, NULL);
82  **next = e;
83  *next = &e->next;
84  return true;
85 }
86 
87 static bool
88 add_subnet(const char *line, const char *prefix, const int line_num, struct pf_subnet ***next, const bool exclude)
89 {
90  struct in_addr network;
91  in_addr_t netmask = 0;
92 
93  if (strcmp(line, "unknown"))
94  {
95  int netbits = 32;
96  char *div = strchr(line, '/');
97 
98  if (div)
99  {
100  *div++ = '\0';
101  if (sscanf(div, "%d", &netbits) != 1)
102  {
103  msg(D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: '%s'", prefix, line_num, div);
104  return false;
105  }
106  if (netbits < 0 || netbits > 32)
107  {
108  msg(D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", prefix, line_num, div);
109  return false;
110  }
111  }
112 
113  if (openvpn_inet_aton(line, &network) != OIA_IP)
114  {
115  msg(D_PF_INFO, "PF: %s/%d: bad network address: '%s'", prefix, line_num, line);
116  return false;
117  }
118  netmask = netbits_to_netmask(netbits);
119  if ((network.s_addr & htonl(netmask)) != network.s_addr)
120  {
121  network.s_addr &= htonl(netmask);
122  msg(M_WARN, "WARNING: PF: %s/%d: incorrect subnet %s/%d changed to %s/%d", prefix, line_num, line, netbits, inet_ntoa(network), netbits);
123  }
124  }
125  else
126  {
127  /* match special "unknown" tag for addresses unrecognized by mroute */
128  network.s_addr = htonl(0);
129  netmask = IPV4_NETMASK_HOST;
130  }
131 
132  {
133  struct pf_subnet *e;
134  ALLOC_OBJ_CLEAR(e, struct pf_subnet);
135  e->rule.exclude = exclude;
136  e->rule.network = ntohl(network.s_addr);
137  e->rule.netmask = netmask;
138  **next = e;
139  *next = &e->next;
140  return true;
141  }
142 }
143 
144 static uint32_t
145 cn_hash_function(const void *key, uint32_t iv)
146 {
147  return hash_func((uint8_t *)key, strlen((char *)key) + 1, iv);
148 }
149 
150 static bool
151 cn_compare_function(const void *key1, const void *key2)
152 {
153  return !strcmp((const char *)key1, (const char *)key2);
154 }
155 
156 static bool
157 genhash(struct pf_cn_set *cns, const char *prefix, const int n_clients)
158 {
159  struct pf_cn_elem *e;
160  bool status = true;
161  int n_buckets = n_clients;
162 
163  if (n_buckets < 16)
164  {
165  n_buckets = 16;
166  }
167  cns->hash_table = hash_init(n_buckets, 0, cn_hash_function, cn_compare_function);
168  for (e = cns->list; e != NULL; e = e->next)
169  {
170  if (!hash_add(cns->hash_table, e->rule.cn, &e->rule, false))
171  {
172  msg(D_PF_INFO, "PF: %s: duplicate common name in [clients] section: '%s'", prefix, e->rule.cn);
173  status = false;
174  }
175  }
176 
177  return status;
178 }
179 
180 static struct pf_set *
181 pf_init(const struct buffer_list *bl, const char *prefix, const bool allow_kill)
182 {
183 #define MODE_UNDEF 0
184 #define MODE_CLIENTS 1
185 #define MODE_SUBNETS 2
186  int mode = MODE_UNDEF;
187  int line_num = 0;
188  int n_clients = 0;
189  int n_subnets = 0;
190  int n_errors = 0;
191  struct pf_set *pfs = NULL;
192  char line[PF_MAX_LINE_LEN];
193 
194  ALLOC_OBJ_CLEAR(pfs, struct pf_set);
195  if (bl)
196  {
197  struct pf_cn_elem **cl = &pfs->cns.list;
198  struct pf_subnet **sl = &pfs->sns.list;
199  struct buffer_entry *be;
200 
201  for (be = bl->head; be != NULL; be = be->next)
202  {
203  ++line_num;
204  strncpynt(line, BSTR(&be->buf), sizeof(line));
205  rm_trailing_chars(line, "\r\n\t ");
206  if (line[0] == '\0' || line[0] == '#')
207  {
208  }
209  else if (line[0] == '+' || line[0] == '-')
210  {
211  bool exclude = (line[0] == '-');
212 
213  if (line[1] =='\0')
214  {
215  msg(D_PF_INFO, "PF: %s/%d: no data after +/-: '%s'", prefix, line_num, line);
216  ++n_errors;
217  }
218  else if (mode == MODE_CLIENTS)
219  {
220  if (add_client(&line[1], prefix, line_num, &cl, exclude))
221  {
222  ++n_clients;
223  }
224  else
225  {
226  ++n_errors;
227  }
228  }
229  else if (mode == MODE_SUBNETS)
230  {
231  if (add_subnet(&line[1], prefix, line_num, &sl, exclude))
232  {
233  ++n_subnets;
234  }
235  else
236  {
237  ++n_errors;
238  }
239  }
240  else if (mode == MODE_UNDEF)
241  {
242  }
243  else
244  {
245  ASSERT(0);
246  }
247  }
248  else if (line[0] == '[')
249  {
250  if (!strcasecmp(line, "[clients accept]"))
251  {
252  mode = MODE_CLIENTS;
253  pfs->cns.default_allow = true;
254  }
255  else if (!strcasecmp(line, "[clients drop]"))
256  {
257  mode = MODE_CLIENTS;
258  pfs->cns.default_allow = false;
259  }
260  else if (!strcasecmp(line, "[subnets accept]"))
261  {
262  mode = MODE_SUBNETS;
263  pfs->sns.default_allow = true;
264  }
265  else if (!strcasecmp(line, "[subnets drop]"))
266  {
267  mode = MODE_SUBNETS;
268  pfs->sns.default_allow = false;
269  }
270  else if (!strcasecmp(line, "[end]"))
271  {
272  goto done;
273  }
274  else if (allow_kill && !strcasecmp(line, "[kill]"))
275  {
276  goto kill;
277  }
278  else
279  {
280  mode = MODE_UNDEF;
281  msg(D_PF_INFO, "PF: %s/%d unknown tag: '%s'", prefix, line_num, line);
282  ++n_errors;
283  }
284  }
285  else
286  {
287  msg(D_PF_INFO, "PF: %s/%d line must begin with '+', '-', or '[' : '%s'", prefix, line_num, line);
288  ++n_errors;
289  }
290  }
291  ++n_errors;
292  msg(D_PF_INFO, "PF: %s: missing [end]", prefix);
293  }
294  else
295  {
296  msg(D_PF_INFO, "PF: %s: cannot open", prefix);
297  ++n_errors;
298  }
299 
300 done:
301  if (bl)
302  {
303  if (!n_errors)
304  {
305  if (!genhash(&pfs->cns, prefix, n_clients))
306  {
307  ++n_errors;
308  }
309  }
310  if (n_errors)
311  {
312  msg(D_PF_INFO, "PF: %s rejected due to %d error(s)", prefix, n_errors);
313  }
314  }
315  if (n_errors)
316  {
317  pf_destroy(pfs);
318  pfs = NULL;
319  }
320  return pfs;
321 
322 kill:
323  pf_destroy(pfs);
324  ALLOC_OBJ_CLEAR(pfs, struct pf_set);
325  pfs->kill = true;
326  return pfs;
327 }
328 
329 #ifdef PLUGIN_PF
330 static struct pf_set *
331 pf_init_from_file(const char *fn)
332 {
333  struct buffer_list *bl = buffer_list_file(fn, PF_MAX_LINE_LEN);
334  if (bl)
335  {
336  struct pf_set *pfs = pf_init(bl, fn, true);
337  buffer_list_free(bl);
338  return pfs;
339  }
340  else
341  {
342  msg(D_PF_INFO|M_ERRNO, "PF: %s: cannot open", fn);
343  return NULL;
344  }
345 }
346 #endif
347 
348 #ifdef ENABLE_DEBUG
349 
350 static const char *
351 drop_accept(const bool accept)
352 {
353  return accept ? "ACCEPT" : "DROP";
354 }
355 
356 static const char *
357 pct_name(const int type)
358 {
359  switch (type)
360  {
361  case PCT_SRC:
362  return "SRC";
363 
364  case PCT_DEST:
365  return "DEST";
366 
367  default:
368  return "???";
369  }
370 }
371 
372 static void
373 pf_cn_test_print(const char *prefix,
374  const int type,
375  const char *prefix2,
376  const char *cn,
377  const bool allow,
378  const struct pf_cn *rule)
379 {
380  if (rule)
381  {
382  dmsg(D_PF_DEBUG, "PF: %s/%s/%s %s %s rule=[%s %s]",
383  prefix, prefix2, pct_name(type),
384  cn, drop_accept(allow),
385  rule->cn, drop_accept(!rule->exclude));
386  }
387  else
388  {
389  dmsg(D_PF_DEBUG, "PF: %s/%s/%s %s %s",
390  prefix, prefix2, pct_name(type),
391  cn, drop_accept(allow));
392  }
393 }
394 
395 static void
396 pf_addr_test_print(const char *prefix,
397  const char *prefix2,
398  const struct context *src,
399  const struct mroute_addr *dest,
400  const bool allow,
401  const struct ipv4_subnet *rule)
402 {
403  struct gc_arena gc = gc_new();
404  if (rule)
405  {
406  dmsg(D_PF_DEBUG, "PF: %s/%s %s %s %s rule=[%s/%s %s]",
407  prefix,
408  prefix2,
409  tls_common_name(src->c2.tls_multi, false),
411  drop_accept(allow),
412  print_in_addr_t(rule->network, 0, &gc),
413  print_in_addr_t(rule->netmask, 0, &gc),
414  drop_accept(!rule->exclude));
415  }
416  else
417  {
418  dmsg(D_PF_DEBUG, "PF: %s/%s %s %s %s",
419  prefix,
420  prefix2,
421  tls_common_name(src->c2.tls_multi, false),
423  drop_accept(allow));
424  }
425  gc_free(&gc);
426 }
427 
428 #endif /* ifdef ENABLE_DEBUG */
429 
430 static inline struct pf_cn *
431 lookup_cn_rule(struct hash *h, const char *cn, const uint32_t cn_hash)
432 {
433  struct hash_element *he = hash_lookup_fast(h, hash_bucket(h, cn_hash), cn, cn_hash);
434  if (he)
435  {
436  return (struct pf_cn *) he->value;
437  }
438  else
439  {
440  return NULL;
441  }
442 }
443 
444 bool
445 pf_cn_test(struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix)
446 {
447  if (pfs && !pfs->kill)
448  {
449  const char *cn;
450  uint32_t cn_hash;
451  if (tls_common_name_hash(tm, &cn, &cn_hash))
452  {
453  const struct pf_cn *rule = lookup_cn_rule(pfs->cns.hash_table, cn, cn_hash);
454  if (rule)
455  {
456 #ifdef ENABLE_DEBUG
458  {
459  pf_cn_test_print("PF_CN_MATCH", type, prefix, cn, !rule->exclude, rule);
460  }
461 #endif
462  if (!rule->exclude)
463  {
464  return true;
465  }
466  else
467  {
468  return false;
469  }
470  }
471  else
472  {
473 #ifdef ENABLE_DEBUG
475  {
476  pf_cn_test_print("PF_CN_DEFAULT", type, prefix, cn, pfs->cns.default_allow, NULL);
477  }
478 #endif
479  if (pfs->cns.default_allow)
480  {
481  return true;
482  }
483  else
484  {
485  return false;
486  }
487  }
488  }
489  }
490 #ifdef ENABLE_DEBUG
492  {
493  pf_cn_test_print("PF_CN_FAULT", type, prefix, tls_common_name(tm, false), false, NULL);
494  }
495 #endif
496  return false;
497 }
498 
499 bool
500 pf_addr_test_dowork(const struct context *src, const struct mroute_addr *dest, const char *prefix)
501 {
502  struct pf_set *pfs = src->c2.pf.pfs;
503  if (pfs && !pfs->kill)
504  {
505  const in_addr_t addr = in_addr_t_from_mroute_addr(dest);
506  const struct pf_subnet *se = pfs->sns.list;
507  while (se)
508  {
509  if ((addr & se->rule.netmask) == se->rule.network)
510  {
511 #ifdef ENABLE_DEBUG
513  {
514  pf_addr_test_print("PF_ADDR_MATCH", prefix, src, dest, !se->rule.exclude, &se->rule);
515  }
516 #endif
517  return !se->rule.exclude;
518  }
519  se = se->next;
520  }
521 #ifdef ENABLE_DEBUG
523  {
524  pf_addr_test_print("PF_ADDR_DEFAULT", prefix, src, dest, pfs->sns.default_allow, NULL);
525  }
526 #endif
527  return pfs->sns.default_allow;
528  }
529  else
530  {
531 #ifdef ENABLE_DEBUG
533  {
534  pf_addr_test_print("PF_ADDR_FAULT", prefix, src, dest, false, NULL);
535  }
536 #endif
537  return false;
538  }
539 }
540 
541 #ifdef PLUGIN_PF
542 void
543 pf_check_reload(struct context *c)
544 {
545  const int slow_wakeup = 15;
546  const int fast_wakeup = 1;
547  const int wakeup_transition = 60;
548  bool reloaded = false;
549 
550  if (c->c2.pf.enabled
551  && c->c2.pf.filename
552  && event_timeout_trigger(&c->c2.pf.reload, &c->c2.timeval, ETT_DEFAULT))
553  {
554  platform_stat_t s;
555  if (!platform_stat(c->c2.pf.filename, &s))
556  {
557  if (s.st_mtime > c->c2.pf.file_last_mod)
558  {
559  struct pf_set *pfs = pf_init_from_file(c->c2.pf.filename);
560  if (pfs)
561  {
562  if (c->c2.pf.pfs)
563  {
564  pf_destroy(c->c2.pf.pfs);
565  }
566  c->c2.pf.pfs = pfs;
567  reloaded = true;
568  if (pf_kill_test(pfs))
569  {
571  c->sig->signal_text = "pf-kill";
572  }
573  }
574  c->c2.pf.file_last_mod = s.st_mtime;
575  }
576  }
577  {
578  int wakeup = slow_wakeup;
579  if (!c->c2.pf.pfs && c->c2.pf.n_check_reload < wakeup_transition)
580  {
581  wakeup = fast_wakeup;
582  }
583  event_timeout_init(&c->c2.pf.reload, wakeup, now);
585  c->c2.pf.n_check_reload++;
586  }
587  }
588 #ifdef ENABLE_DEBUG
589  if (reloaded && check_debug_level(D_PF_DEBUG))
590  {
591  pf_context_print(&c->c2.pf, "pf_check_reload", D_PF_DEBUG);
592  }
593 #endif
594 }
595 #endif /* ifdef PLUGIN_PF */
596 
597 #ifdef MANAGEMENT_PF
598 bool
599 pf_load_from_buffer_list(struct context *c, const struct buffer_list *config)
600 {
601  struct pf_set *pfs = pf_init(config, "[SERVER-PF]", false);
602  if (pfs)
603  {
604  if (c->c2.pf.pfs)
605  {
606  pf_destroy(c->c2.pf.pfs);
607  }
608  c->c2.pf.pfs = pfs;
609  return true;
610  }
611  else
612  {
613  return false;
614  }
615 }
616 #endif
617 
618 void
619 pf_init_context(struct context *c)
620 {
621 #ifdef PLUGIN_PF
623  {
624  c->c2.pf.filename = platform_create_temp_file(c->options.tmp_dir, "pf",
625  &c->c2.gc);
626  if (c->c2.pf.filename)
627  {
628  setenv_str(c->c2.es, "pf_file", c->c2.pf.filename);
629 
631  {
632  event_timeout_init(&c->c2.pf.reload, 1, now);
633  c->c2.pf.enabled = true;
634 #ifdef ENABLE_DEBUG
636  {
637  pf_context_print(&c->c2.pf, "pf_init_context#1", D_PF_DEBUG);
638  }
639 #endif
640  }
641  }
642  if (!c->c2.pf.enabled)
643  {
644  msg(M_WARN, "WARNING: failed to init PF plugin, rejecting client.");
645  register_signal(c, SIGUSR1, "plugin-pf-init-failed");
646  return;
647  }
648  }
649 #endif /* ifdef PLUGIN_PF */
650 #ifdef MANAGEMENT_PF
651  if (!c->c2.pf.enabled && management_enable_pf(management))
652  {
653  c->c2.pf.enabled = true;
654 #ifdef ENABLE_DEBUG
656  {
657  pf_context_print(&c->c2.pf, "pf_init_context#2", D_PF_DEBUG);
658  }
659 #endif
660  }
661 #endif
662 }
663 
664 void
665 pf_destroy_context(struct pf_context *pfc)
666 {
667 #ifdef PLUGIN_PF
668  if (pfc->filename)
669  {
670  platform_unlink(pfc->filename);
671  }
672 #endif
673  if (pfc->pfs)
674  {
675  pf_destroy(pfc->pfs);
676  }
677 }
678 
679 #ifdef ENABLE_DEBUG
680 
681 static void
682 pf_subnet_set_print(const struct pf_subnet_set *s, const int lev)
683 {
684  struct gc_arena gc = gc_new();
685  if (s)
686  {
687  struct pf_subnet *e;
688 
689  msg(lev, " ----- struct pf_subnet_set -----");
690  msg(lev, " default_allow=%s", drop_accept(s->default_allow));
691 
692  for (e = s->list; e != NULL; e = e->next)
693  {
694  msg(lev, " %s/%s %s",
695  print_in_addr_t(e->rule.network, 0, &gc),
696  print_in_addr_t(e->rule.netmask, 0, &gc),
697  drop_accept(!e->rule.exclude));
698  }
699  }
700  gc_free(&gc);
701 }
702 
703 static void
704 pf_cn_set_print(const struct pf_cn_set *s, const int lev)
705 {
706  if (s)
707  {
708  struct hash_iterator hi;
709  struct hash_element *he;
710 
711  msg(lev, " ----- struct pf_cn_set -----");
712  msg(lev, " default_allow=%s", drop_accept(s->default_allow));
713 
714  if (s->hash_table)
715  {
716  hash_iterator_init(s->hash_table, &hi);
717  while ((he = hash_iterator_next(&hi)))
718  {
719  struct pf_cn *e = (struct pf_cn *)he->value;
720  msg(lev, " %s %s",
721  e->cn,
722  drop_accept(!e->exclude));
723  }
724 
725  msg(lev, " ----------");
726 
727  {
728  struct pf_cn_elem *ce;
729  for (ce = s->list; ce != NULL; ce = ce->next)
730  {
731  struct pf_cn *e = lookup_cn_rule(s->hash_table, ce->rule.cn, cn_hash_function(ce->rule.cn, 0));
732  if (e)
733  {
734  msg(lev, " %s %s",
735  e->cn,
736  drop_accept(!e->exclude));
737  }
738  else
739  {
740  msg(lev, " %s LOOKUP FAILED", ce->rule.cn);
741  }
742  }
743  }
744  }
745  }
746 }
747 
748 static void
749 pf_set_print(const struct pf_set *pfs, const int lev)
750 {
751  if (pfs)
752  {
753  msg(lev, " ----- struct pf_set -----");
754  msg(lev, " kill=%d", pfs->kill);
755  pf_subnet_set_print(&pfs->sns, lev);
756  pf_cn_set_print(&pfs->cns, lev);
757  }
758 }
759 
760 void
761 pf_context_print(const struct pf_context *pfc, const char *prefix, const int lev)
762 {
763  msg(lev, "----- %s : struct pf_context -----", prefix);
764  if (pfc)
765  {
766  msg(lev, "enabled=%d", pfc->enabled);
767 #ifdef PLUGIN_PF
768  msg(lev, "filename='%s'", np(pfc->filename));
769  msg(lev, "file_last_mod=%u", (unsigned int)pfc->file_last_mod);
770  msg(lev, "n_check_reload=%u", pfc->n_check_reload);
771  msg(lev, "reload=[%d,%u,%u]", pfc->reload.defined, pfc->reload.n, (unsigned int)pfc->reload.last);
772 #endif
773  pf_set_print(pfc->pfs, lev);
774  }
775  msg(lev, "--------------------");
776 }
777 
778 #endif /* ifdef ENABLE_DEBUG */
779 
780 #endif /* if defined(ENABLE_PF) */
struct env_set * es
Definition: openvpn.h:427
#define ETT_DEFAULT
Definition: interval.h:213
static void strncpynt(char *dest, const char *src, size_t maxlen)
Definition: buffer.h:348
struct options options
Options loaded from command line or configuration file.
Definition: openvpn.h:502
char * string_alloc(const char *str, struct gc_arena *gc)
Definition: buffer.c:688
struct buffer_list * buffer_list_file(const char *fn, int max_line_len)
Definition: buffer.c:1379
void hash_free(struct hash *hash)
Definition: list.c:66
Contains all state information for one tunnel.
Definition: openvpn.h:500
struct buffer_entry * head
Definition: buffer.h:1112
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1023
static int plugin_call(const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, struct env_set *es)
Definition: plugin.h:201
#define dmsg
Definition: error.h:174
Security parameter state for a single VPN tunnel.
Definition: ssl_common.h:503
#define SIGUSR1
Definition: config-msvc.h:116
void buffer_list_free(struct buffer_list *ol)
Frees a buffer list and all the buffers in it.
Definition: buffer.c:1211
static in_addr_t netbits_to_netmask(const int netbits)
Definition: route.h:369
int openvpn_inet_aton(const char *dotted_quad, struct in_addr *addr)
Definition: socket.c:665
const char * mroute_addr_print_ex(const struct mroute_addr *ma, const unsigned int flags, struct gc_arena *gc)
Definition: mroute.c:431
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition: env_set.c:285
#define in_addr_t
Definition: config-msvc.h:104
struct signal_info * sig
Internal error signaling object.
Definition: openvpn.h:525
#define SIGTERM
Definition: config-msvc.h:118
#define ASSERT(x)
Definition: error.h:221
#define OPENVPN_PLUGIN_ENABLE_PF
struct gc_arena gc
Garbage collection arena for allocations done in the level 2 scope of this context_2 structure...
Definition: openvpn.h:226
static bool check_debug_level(unsigned int level)
Definition: error.h:245
#define OPENVPN_PLUGIN_FUNC_SUCCESS
bool platform_unlink(const char *filename)
Definition: platform.c:287
#define strcasecmp
Definition: config-msvc.h:94
struct hash * hash_init(const int n_buckets, const uint32_t iv, uint32_t(*hash_function)(const void *key, uint32_t iv), bool(*compare_function)(const void *key1, const void *key2))
Definition: list.c:41
bool hash_add(struct hash *hash, const void *key, void *value, bool replace)
Definition: list.c:150
#define OIA_IP
Definition: socket.h:461
#define D_PF_DEBUG
Definition: errlevel.h:147
bool event_timeout_trigger(struct event_timeout *et, struct timeval *tv, const int et_const_retry)
Definition: interval.c:45
#define MAPF_SHOW_ARP
Definition: mroute.h:158
static const char * np(const char *str)
Definition: simple.c:108
void rm_trailing_chars(char *str, const char *what_to_delete)
Definition: buffer.c:662
static struct gc_arena gc_new(void)
Definition: buffer.h:1015
time_t now
Definition: otime.c:36
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1050
const char * print_in_addr_t(in_addr_t addr, unsigned int flags, struct gc_arena *gc)
Definition: socket.c:2972
#define D_PF_INFO
Definition: errlevel.h:93
void hash_iterator_init(struct hash *hash, struct hash_iterator *hi)
Definition: list.c:249
struct timeval timeval
Definition: openvpn.h:401
unsigned __int32 uint32_t
Definition: config-msvc.h:121
static SERVICE_STATUS status
Definition: automatic.c:43
struct buffer buf
Definition: buffer.h:1106
#define M_ERRNO
Definition: error.h:99
#define msg
Definition: error.h:173
void reset_coarse_timers(struct context *c)
Definition: init.c:1305
struct context_2 c2
Level 2 context.
Definition: openvpn.h:539
struct hash_element * hash_iterator_next(struct hash_iterator *hi)
Definition: list.c:292
int platform_stat(const char *path, platform_stat_t *buf)
Definition: platform.c:328
Container for bidirectional cipher and HMAC key material.
Definition: crypto.h:181
static struct hash_bucket * hash_bucket(struct hash *hash, uint32_t hv)
Definition: list.h:143
struct buffer_entry * next
Definition: buffer.h:1107
uint32_t hash_func(const uint8_t *k, uint32_t length, uint32_t initval)
Definition: list.c:590
unsigned __int8 uint8_t
Definition: config-msvc.h:123
const char * tmp_dir
Definition: options.h:392
volatile int signal_received
Definition: sig.h:45
bool plugin_defined(const struct plugin_list *pl, const int type)
Definition: plugin.c:894
void register_signal(struct context *c, int sig, const char *text)
Definition: sig.c:460
struct hash_element * hash_lookup_fast(struct hash *hash, struct hash_bucket *bucket, const void *key, uint32_t hv)
Definition: list.c:86
struct plugin_list * plugins
List of plug-ins.
Definition: openvpn.h:527
const char * tls_common_name(const struct tls_multi *multi, const bool null)
Returns the common name field for the given tunnel.
Definition: ssl_verify.c:147
#define M_WARN
Definition: error.h:96
static in_addr_t in_addr_t_from_mroute_addr(const struct mroute_addr *addr)
Definition: mroute.h:249
#define free
Definition: cmocka.c:1850
Definition: buffer.h:1104
void * value
Definition: list.h:49
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
const char * platform_create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
Create a temporary file in directory, returns the filename of the created file.
Definition: platform.c:342
#define BSTR(buf)
Definition: buffer.h:129
char * dest
Definition: compat-lz4.h:431
Definition: list.h:60
struct tls_multi * tls_multi
TLS state structure for this VPN tunnel.
Definition: openvpn.h:336
#define IPV4_NETMASK_HOST
Definition: basic.h:35
const char * signal_text
Definition: sig.h:47
struct _stat platform_stat_t
Definition: platform.h:141
static void event_timeout_init(struct event_timeout *et, interval_t n, const time_t local_now)
Definition: interval.h:166
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:151