OpenVPN: Update to version 2.3.2. Solves TLS security bug.
[tomato.git] / release / src / router / openvpn / src / openvpn / pf.c
blob461beed75e435eb4fc522f792c075b6fe6d76b8e
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.
8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
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.
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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 /* packet filter functions */
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #elif defined(_MSC_VER)
30 #include "config-msvc.h"
31 #endif
33 #include "syshead.h"
35 #if defined(ENABLE_PF)
37 #include "init.h"
39 #include "memdbg.h"
41 #include "pf-inline.h"
43 static void
44 pf_destroy (struct pf_set *pfs)
46 if (pfs)
48 if (pfs->cns.hash_table)
49 hash_free (pfs->cns.hash_table);
52 struct pf_cn_elem *l = pfs->cns.list;
53 while (l)
55 struct pf_cn_elem *next = l->next;
56 free (l->rule.cn);
57 free (l);
58 l = next;
62 struct pf_subnet *l = pfs->sns.list;
63 while (l)
65 struct pf_subnet *next = l->next;
66 free (l);
67 l = next;
70 free (pfs);
74 static bool
75 add_client (const char *line, const char *prefix, const int line_num, struct pf_cn_elem ***next, const bool exclude)
77 struct pf_cn_elem *e;
78 ALLOC_OBJ_CLEAR (e, struct pf_cn_elem);
79 e->rule.exclude = exclude;
80 e->rule.cn = string_alloc (line, NULL);
81 **next = e;
82 *next = &e->next;
83 return true;
86 static bool
87 add_subnet (const char *line, const char *prefix, const int line_num, struct pf_subnet ***next, const bool exclude)
89 struct in_addr network;
90 in_addr_t netmask = 0;
92 if (strcmp (line, "unknown"))
94 int netbits = 32;
95 char *div = strchr (line, '/');
97 if (div)
99 *div++ = '\0';
100 if (sscanf (div, "%d", &netbits) != 1)
102 msg (D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: '%s'", prefix, line_num, div);
103 return false;
105 if (netbits < 0 || netbits > 32)
107 msg (D_PF_INFO, "PF: %s/%d: bad '/n' subnet specifier: must be between 0 and 32: '%s'", prefix, line_num, div);
108 return false;
112 if (openvpn_inet_aton (line, &network) != OIA_IP)
114 msg (D_PF_INFO, "PF: %s/%d: bad network address: '%s'", prefix, line_num, line);
115 return false;
117 netmask = netbits_to_netmask (netbits);
118 if ((network.s_addr & htonl (netmask)) != network.s_addr)
120 network.s_addr &= htonl (netmask);
121 msg (M_WARN, "WARNING: PF: %s/%d: incorrect subnet %s/%d changed to %s/%d", prefix, line_num, line, netbits, inet_ntoa (network), netbits);
124 else
126 /* match special "unknown" tag for addresses unrecognized by mroute */
127 network.s_addr = htonl(0);
128 netmask = IPV4_NETMASK_HOST;
132 struct pf_subnet *e;
133 ALLOC_OBJ_CLEAR (e, struct pf_subnet);
134 e->rule.exclude = exclude;
135 e->rule.network = ntohl (network.s_addr);
136 e->rule.netmask = netmask;
137 **next = e;
138 *next = &e->next;
139 return true;
143 static uint32_t
144 cn_hash_function (const void *key, uint32_t iv)
146 return hash_func ((uint8_t *)key, strlen ((char *)key) + 1, iv);
149 static bool
150 cn_compare_function (const void *key1, const void *key2)
152 return !strcmp((const char *)key1, (const char *)key2);
155 static bool
156 genhash (struct pf_cn_set *cns, const char *prefix, const int n_clients)
158 struct pf_cn_elem *e;
159 bool status = true;
160 int n_buckets = n_clients;
162 if (n_buckets < 16)
163 n_buckets = 16;
164 cns->hash_table = hash_init (n_buckets, 0, cn_hash_function, cn_compare_function);
165 for (e = cns->list; e != NULL; e = e->next)
167 if (!hash_add (cns->hash_table, e->rule.cn, &e->rule, false))
169 msg (D_PF_INFO, "PF: %s: duplicate common name in [clients] section: '%s'", prefix, e->rule.cn);
170 status = false;
174 return status;
177 static struct pf_set *
178 pf_init (const struct buffer_list *bl, const char *prefix, const bool allow_kill)
180 # define MODE_UNDEF 0
181 # define MODE_CLIENTS 1
182 # define MODE_SUBNETS 2
183 int mode = MODE_UNDEF;
184 int line_num = 0;
185 int n_clients = 0;
186 int n_subnets = 0;
187 int n_errors = 0;
188 struct pf_set *pfs = NULL;
189 char line[PF_MAX_LINE_LEN];
191 ALLOC_OBJ_CLEAR (pfs, struct pf_set);
192 if (bl)
194 struct pf_cn_elem **cl = &pfs->cns.list;
195 struct pf_subnet **sl = &pfs->sns.list;
196 struct buffer_entry *be;
198 for (be = bl->head; be != NULL; be = be->next)
200 ++line_num;
201 strncpynt (line, BSTR(&be->buf), sizeof(line));
202 rm_trailing_chars (line, "\r\n\t ");
203 if (line[0] == '\0' || line[0] == '#')
205 else if (line[0] == '+' || line[0] == '-')
207 bool exclude = (line[0] == '-');
209 if (line[1] =='\0')
211 msg (D_PF_INFO, "PF: %s/%d: no data after +/-: '%s'", prefix, line_num, line);
212 ++n_errors;
214 else if (mode == MODE_CLIENTS)
216 if (add_client (&line[1], prefix, line_num, &cl, exclude))
217 ++n_clients;
218 else
219 ++n_errors;
221 else if (mode == MODE_SUBNETS)
223 if (add_subnet (&line[1], prefix, line_num, &sl, exclude))
224 ++n_subnets;
225 else
226 ++n_errors;
228 else if (mode == MODE_UNDEF)
230 else
232 ASSERT (0);
235 else if (line[0] == '[')
237 if (!strcasecmp (line, "[clients accept]"))
239 mode = MODE_CLIENTS;
240 pfs->cns.default_allow = true;
242 else if (!strcasecmp (line, "[clients drop]"))
244 mode = MODE_CLIENTS;
245 pfs->cns.default_allow = false;
247 else if (!strcasecmp (line, "[subnets accept]"))
249 mode = MODE_SUBNETS;
250 pfs->sns.default_allow = true;
252 else if (!strcasecmp (line, "[subnets drop]"))
254 mode = MODE_SUBNETS;
255 pfs->sns.default_allow = false;
257 else if (!strcasecmp (line, "[end]"))
258 goto done;
259 else if (allow_kill && !strcasecmp (line, "[kill]"))
260 goto kill;
261 else
263 mode = MODE_UNDEF;
264 msg (D_PF_INFO, "PF: %s/%d unknown tag: '%s'", prefix, line_num, line);
265 ++n_errors;
268 else
270 msg (D_PF_INFO, "PF: %s/%d line must begin with '+', '-', or '[' : '%s'", prefix, line_num, line);
271 ++n_errors;
274 ++n_errors;
275 msg (D_PF_INFO, "PF: %s: missing [end]", prefix);
277 else
279 msg (D_PF_INFO, "PF: %s: cannot open", prefix);
280 ++n_errors;
283 done:
284 if (bl)
286 if (!n_errors)
288 if (!genhash (&pfs->cns, prefix, n_clients))
289 ++n_errors;
291 if (n_errors)
292 msg (D_PF_INFO, "PF: %s rejected due to %d error(s)", prefix, n_errors);
294 if (n_errors)
296 pf_destroy (pfs);
297 pfs = NULL;
299 return pfs;
301 kill:
302 pf_destroy (pfs);
303 ALLOC_OBJ_CLEAR (pfs, struct pf_set);
304 pfs->kill = true;
305 return pfs;
308 #ifdef PLUGIN_PF
309 static struct pf_set *
310 pf_init_from_file (const char *fn)
312 struct buffer_list *bl = buffer_list_file (fn, PF_MAX_LINE_LEN);
313 if (bl)
315 struct pf_set *pfs = pf_init (bl, fn, true);
316 buffer_list_free (bl);
317 return pfs;
319 else
321 msg (D_PF_INFO|M_ERRNO, "PF: %s: cannot open", fn);
322 return NULL;
325 #endif
327 #ifdef ENABLE_DEBUG
329 static const char *
330 drop_accept (const bool accept)
332 return accept ? "ACCEPT" : "DROP";
335 static const char *
336 pct_name (const int type)
338 switch (type)
340 case PCT_SRC:
341 return "SRC";
342 case PCT_DEST:
343 return "DEST";
344 default:
345 return "???";
349 static void
350 pf_cn_test_print (const char *prefix,
351 const int type,
352 const char *prefix2,
353 const char *cn,
354 const bool allow,
355 const struct pf_cn *rule)
357 if (rule)
359 dmsg (D_PF_DEBUG, "PF: %s/%s/%s %s %s rule=[%s %s]",
360 prefix, prefix2, pct_name (type),
361 cn, drop_accept (allow),
362 rule->cn, drop_accept (!rule->exclude));
364 else
366 dmsg (D_PF_DEBUG, "PF: %s/%s/%s %s %s",
367 prefix, prefix2, pct_name (type),
368 cn, drop_accept (allow));
372 static void
373 pf_addr_test_print (const char *prefix,
374 const char *prefix2,
375 const struct context *src,
376 const struct mroute_addr *dest,
377 const bool allow,
378 const struct ipv4_subnet *rule)
380 struct gc_arena gc = gc_new ();
381 if (rule)
383 dmsg (D_PF_DEBUG, "PF: %s/%s %s %s %s rule=[%s/%s %s]",
384 prefix,
385 prefix2,
386 tls_common_name (src->c2.tls_multi, false),
387 mroute_addr_print_ex (dest, MAPF_SHOW_ARP, &gc),
388 drop_accept (allow),
389 print_in_addr_t (rule->network, 0, &gc),
390 print_in_addr_t (rule->netmask, 0, &gc),
391 drop_accept (!rule->exclude));
393 else
395 dmsg (D_PF_DEBUG, "PF: %s/%s %s %s %s",
396 prefix,
397 prefix2,
398 tls_common_name (src->c2.tls_multi, false),
399 mroute_addr_print_ex (dest, MAPF_SHOW_ARP, &gc),
400 drop_accept (allow));
402 gc_free (&gc);
405 #endif
407 static inline struct pf_cn *
408 lookup_cn_rule (struct hash *h, const char *cn, const uint32_t cn_hash)
410 struct hash_element *he = hash_lookup_fast (h, hash_bucket (h, cn_hash), cn, cn_hash);
411 if (he)
412 return (struct pf_cn *) he->value;
413 else
414 return NULL;
417 bool
418 pf_cn_test (struct pf_set *pfs, const struct tls_multi *tm, const int type, const char *prefix)
420 if (pfs && !pfs->kill)
422 const char *cn;
423 uint32_t cn_hash;
424 if (tls_common_name_hash (tm, &cn, &cn_hash))
426 const struct pf_cn *rule = lookup_cn_rule (pfs->cns.hash_table, cn, cn_hash);
427 if (rule)
429 #ifdef ENABLE_DEBUG
430 if (check_debug_level (D_PF_DEBUG))
431 pf_cn_test_print ("PF_CN_MATCH", type, prefix, cn, !rule->exclude, rule);
432 #endif
433 if (!rule->exclude)
434 return true;
435 else
436 return false;
438 else
440 #ifdef ENABLE_DEBUG
441 if (check_debug_level (D_PF_DEBUG))
442 pf_cn_test_print ("PF_CN_DEFAULT", type, prefix, cn, pfs->cns.default_allow, NULL);
443 #endif
444 if (pfs->cns.default_allow)
445 return true;
446 else
447 return false;
451 #ifdef ENABLE_DEBUG
452 if (check_debug_level (D_PF_DEBUG))
453 pf_cn_test_print ("PF_CN_FAULT", type, prefix, tls_common_name (tm, false), false, NULL);
454 #endif
455 return false;
458 bool
459 pf_addr_test_dowork (const struct context *src, const struct mroute_addr *dest, const char *prefix)
461 struct pf_set *pfs = src->c2.pf.pfs;
462 if (pfs && !pfs->kill)
464 const in_addr_t addr = in_addr_t_from_mroute_addr (dest);
465 const struct pf_subnet *se = pfs->sns.list;
466 while (se)
468 if ((addr & se->rule.netmask) == se->rule.network)
470 #ifdef ENABLE_DEBUG
471 if (check_debug_level (D_PF_DEBUG))
472 pf_addr_test_print ("PF_ADDR_MATCH", prefix, src, dest, !se->rule.exclude, &se->rule);
473 #endif
474 return !se->rule.exclude;
476 se = se->next;
478 #ifdef ENABLE_DEBUG
479 if (check_debug_level (D_PF_DEBUG))
480 pf_addr_test_print ("PF_ADDR_DEFAULT", prefix, src, dest, pfs->sns.default_allow, NULL);
481 #endif
482 return pfs->sns.default_allow;
484 else
486 #ifdef ENABLE_DEBUG
487 if (check_debug_level (D_PF_DEBUG))
488 pf_addr_test_print ("PF_ADDR_FAULT", prefix, src, dest, false, NULL);
489 #endif
490 return false;
494 #ifdef PLUGIN_PF
495 void
496 pf_check_reload (struct context *c)
498 const int slow_wakeup = 15;
499 const int fast_wakeup = 1;
500 const int wakeup_transition = 60;
501 bool reloaded = false;
503 if (c->c2.pf.enabled
504 && c->c2.pf.filename
505 && event_timeout_trigger (&c->c2.pf.reload, &c->c2.timeval, ETT_DEFAULT))
507 platform_stat_t s;
508 if (!platform_stat (c->c2.pf.filename, &s))
510 if (s.st_mtime > c->c2.pf.file_last_mod)
512 struct pf_set *pfs = pf_init_from_file (c->c2.pf.filename);
513 if (pfs)
515 if (c->c2.pf.pfs)
516 pf_destroy (c->c2.pf.pfs);
517 c->c2.pf.pfs = pfs;
518 reloaded = true;
519 if (pf_kill_test (pfs))
521 c->sig->signal_received = SIGTERM;
522 c->sig->signal_text = "pf-kill";
525 c->c2.pf.file_last_mod = s.st_mtime;
529 int wakeup = slow_wakeup;
530 if (!c->c2.pf.pfs && c->c2.pf.n_check_reload < wakeup_transition)
531 wakeup = fast_wakeup;
532 event_timeout_init (&c->c2.pf.reload, wakeup, now);
533 reset_coarse_timers (c);
534 c->c2.pf.n_check_reload++;
537 #ifdef ENABLE_DEBUG
538 if (reloaded && check_debug_level (D_PF_DEBUG))
539 pf_context_print (&c->c2.pf, "pf_check_reload", D_PF_DEBUG);
540 #endif
542 #endif
544 #ifdef MANAGEMENT_PF
545 bool
546 pf_load_from_buffer_list (struct context *c, const struct buffer_list *config)
548 struct pf_set *pfs = pf_init (config, "[SERVER-PF]", false);
549 if (pfs)
551 if (c->c2.pf.pfs)
552 pf_destroy (c->c2.pf.pfs);
553 c->c2.pf.pfs = pfs;
554 return true;
556 else
557 return false;
559 #endif
561 void
562 pf_init_context (struct context *c)
564 struct gc_arena gc = gc_new ();
565 #ifdef PLUGIN_PF
566 if (plugin_defined (c->plugins, OPENVPN_PLUGIN_ENABLE_PF))
568 const char *pf_file = create_temp_file (c->options.tmp_dir, "pf", &gc);
569 if( pf_file ) {
570 setenv_str (c->c2.es, "pf_file", pf_file);
572 if (plugin_call (c->plugins, OPENVPN_PLUGIN_ENABLE_PF, NULL, NULL, c->c2.es) == OPENVPN_PLUGIN_FUNC_SUCCESS)
574 event_timeout_init (&c->c2.pf.reload, 1, now);
575 c->c2.pf.filename = string_alloc (pf_file, &c->c2.gc);
576 c->c2.pf.enabled = true;
577 #ifdef ENABLE_DEBUG
578 if (check_debug_level (D_PF_DEBUG))
579 pf_context_print (&c->c2.pf, "pf_init_context#1", D_PF_DEBUG);
580 #endif
582 else
584 msg (M_WARN, "WARNING: OPENVPN_PLUGIN_ENABLE_PF disabled");
588 #endif
589 #ifdef MANAGEMENT_PF
590 if (!c->c2.pf.enabled && management_enable_pf (management))
592 c->c2.pf.enabled = true;
593 #ifdef ENABLE_DEBUG
594 if (check_debug_level (D_PF_DEBUG))
595 pf_context_print (&c->c2.pf, "pf_init_context#2", D_PF_DEBUG);
596 #endif
598 #endif
599 gc_free (&gc);
602 void
603 pf_destroy_context (struct pf_context *pfc)
605 #ifdef PLUGIN_PF
606 if (pfc->filename)
608 platform_unlink (pfc->filename);
610 #endif
611 if (pfc->pfs)
612 pf_destroy (pfc->pfs);
615 #ifdef ENABLE_DEBUG
617 static void
618 pf_subnet_set_print (const struct pf_subnet_set *s, const int lev)
620 struct gc_arena gc = gc_new ();
621 if (s)
623 struct pf_subnet *e;
625 msg (lev, " ----- struct pf_subnet_set -----");
626 msg (lev, " default_allow=%s", drop_accept (s->default_allow));
628 for (e = s->list; e != NULL; e = e->next)
630 msg (lev, " %s/%s %s",
631 print_in_addr_t (e->rule.network, 0, &gc),
632 print_in_addr_t (e->rule.netmask, 0, &gc),
633 drop_accept (!e->rule.exclude));
636 gc_free (&gc);
639 static void
640 pf_cn_set_print (const struct pf_cn_set *s, const int lev)
642 if (s)
644 struct hash_iterator hi;
645 struct hash_element *he;
647 msg (lev, " ----- struct pf_cn_set -----");
648 msg (lev, " default_allow=%s", drop_accept (s->default_allow));
650 if (s->hash_table)
652 hash_iterator_init (s->hash_table, &hi);
653 while ((he = hash_iterator_next (&hi)))
655 struct pf_cn *e = (struct pf_cn *)he->value;
656 msg (lev, " %s %s",
657 e->cn,
658 drop_accept (!e->exclude));
661 msg (lev, " ----------");
664 struct pf_cn_elem *ce;
665 for (ce = s->list; ce != NULL; ce = ce->next)
667 struct pf_cn *e = lookup_cn_rule (s->hash_table, ce->rule.cn, cn_hash_function (ce->rule.cn, 0));
668 if (e)
670 msg (lev, " %s %s",
671 e->cn,
672 drop_accept (!e->exclude));
674 else
676 msg (lev, " %s LOOKUP FAILED", ce->rule.cn);
684 static void
685 pf_set_print (const struct pf_set *pfs, const int lev)
687 if (pfs)
689 msg (lev, " ----- struct pf_set -----");
690 msg (lev, " kill=%d", pfs->kill);
691 pf_subnet_set_print (&pfs->sns, lev);
692 pf_cn_set_print (&pfs->cns, lev);
696 void
697 pf_context_print (const struct pf_context *pfc, const char *prefix, const int lev)
699 msg (lev, "----- %s : struct pf_context -----", prefix);
700 if (pfc)
702 msg (lev, "enabled=%d", pfc->enabled);
703 #ifdef PLUGIN_PF
704 msg (lev, "filename='%s'", np(pfc->filename));
705 msg (lev, "file_last_mod=%u", (unsigned int)pfc->file_last_mod);
706 msg (lev, "n_check_reload=%u", pfc->n_check_reload);
707 msg (lev, "reload=[%d,%u,%u]", pfc->reload.defined, pfc->reload.n, (unsigned int)pfc->reload.last);
708 #endif
709 pf_set_print (pfc->pfs, lev);
711 msg (lev, "--------------------");
714 #endif
716 #endif