Introduce new enum values for zone src policies and map src policy to dst_flags bitfi...
[project/firewall3.git] / includes.c
1 /*
2  * firewall3 - 3rd OpenWrt UCI firewall implementation
3  *
4  *   Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #include "includes.h"
20
21
22 const struct fw3_option fw3_include_opts[] = {
23         FW3_OPT("enabled",             bool,           include,     enabled),
24
25         FW3_OPT("path",                string,         include,     path),
26         FW3_OPT("type",                include_type,   include,     type),
27         FW3_OPT("family",              family,         include,     family),
28
29         { }
30 };
31
32
33 void
34 fw3_load_includes(struct fw3_state *state, struct uci_package *p)
35 {
36         struct uci_section *s;
37         struct uci_element *e;
38         struct fw3_include *include;
39
40         INIT_LIST_HEAD(&state->includes);
41
42         uci_foreach_element(&p->sections, e)
43         {
44                 s = uci_to_section(e);
45
46                 if (strcmp(s->type, "include"))
47                         continue;
48
49                 include = malloc(sizeof(*include));
50
51                 if (!include)
52                         continue;
53
54                 memset(include, 0, sizeof(*include));
55
56                 include->name = e->name;
57                 include->enabled = true;
58
59                 fw3_parse_options(include, fw3_include_opts, s);
60
61                 if (!include->enabled)
62                 {
63                         fw3_free_include(include);
64                         continue;
65                 }
66
67                 if (!include->path)
68                 {
69                         warn_elem(e, "must specify a path");
70                         fw3_free_include(include);
71                         continue;
72                 }
73
74                 if (include->type == FW3_INC_TYPE_RESTORE && !include->family)
75                         warn_elem(e, "does not specify a family, include will get loaded "
76                                      "with both iptables-restore and ip6tables-restore!");
77
78                 list_add_tail(&include->list, &state->includes);
79                 continue;
80         }
81 }
82
83
84 static void
85 print_include(enum fw3_family family, struct fw3_include *include)
86 {
87         FILE *f;
88         char line[1024];
89
90         if (!fw3_is_family(include, family))
91                 return;
92
93         info(" * Loading include '%s'", include->path);
94
95         if (!(f = fopen(include->path, "r")))
96         {
97                 info("   ! Skipping due to open error: %s", strerror(errno));
98                 return;
99         }
100
101         while (fgets(line, sizeof(line), f))
102                 fw3_pr(line);
103
104         fclose(f);
105 }
106
107 void
108 fw3_print_includes(enum fw3_family family, struct fw3_state *state)
109 {
110         struct fw3_include *include;
111
112         list_for_each_entry(include, &state->includes, list)
113                 if (include->type == FW3_INC_TYPE_RESTORE)
114                         print_include(family, include);
115 }
116
117
118 static void
119 run_include(struct fw3_include *include)
120 {
121         int rv;
122         struct stat s;
123         const char *tmpl =
124                 "config() { "
125                         "echo \"You cannot use UCI in firewall includes!\" >&2; "
126                         "exit 1; "
127                 "}; . %s";
128
129         char buf[PATH_MAX + sizeof(tmpl)];
130
131         info(" * Running script '%s'", include->path);
132
133         if (stat(include->path, &s))
134         {
135                 info("   ! Skipping due to path error: %s", strerror(errno));
136                 return;
137         }
138
139         snprintf(buf, sizeof(buf), tmpl, include->path);
140         rv = system(buf);
141
142         if (rv)
143                 info("   ! Failed with exit code %u", WEXITSTATUS(rv));
144 }
145
146 void
147 fw3_run_includes(struct fw3_state *state)
148 {
149         struct fw3_include *include;
150
151         list_for_each_entry(include, &state->includes, list)
152                 if (include->type == FW3_INC_TYPE_SCRIPT)
153                         run_include(include);
154 }