• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firewall3/includes.c

  1 /*
  2  * firewall3 - 3rd OpenWrt UCI firewall implementation
  3  *
  4  *   Copyright (C) 2013 Jo-Philipp Wich <jo@mein.io>
  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         FW3_OPT("reload",              bool,           include,     reload),
 29 
 30         { }
 31 };
 32 
 33 static bool
 34 check_include(struct fw3_state *state, struct fw3_include *include, struct uci_element *e)
 35 {
 36         if (!include->enabled)
 37                 return false;
 38 
 39         if (!include->path)
 40         {
 41                 warn_section("include", include, e, "must specify a path");
 42                 return false;
 43         }
 44 
 45         if (include->type == FW3_INC_TYPE_RESTORE && !include->family)
 46                 warn_section("include", include, e, "does not specify a family, include will get"
 47                                 "loaded with both iptables-restore and ip6tables-restore!");
 48 
 49         return true;
 50 }
 51 
 52 static struct fw3_include *
 53 fw3_alloc_include(struct fw3_state *state)
 54 {
 55         struct fw3_include *include;
 56 
 57         include = calloc(1, sizeof(*include));
 58         if (!include)
 59                 return NULL;
 60 
 61         include->enabled = true;
 62 
 63         list_add_tail(&include->list, &state->includes);
 64 
 65         return include;
 66 }
 67 
 68 void
 69 fw3_load_includes(struct fw3_state *state, struct uci_package *p,
 70                 struct blob_attr *a)
 71 {
 72         struct uci_section *s;
 73         struct uci_element *e;
 74         struct fw3_include *include;
 75         struct blob_attr *entry;
 76         unsigned rem;
 77 
 78         INIT_LIST_HEAD(&state->includes);
 79 
 80         blob_for_each_attr(entry, a, rem)
 81         {
 82                 const char *type;
 83                 const char *name = "ubus include";
 84 
 85                 if (!fw3_attr_parse_name_type(entry, &name, &type))
 86                         continue;
 87 
 88                 if (strcmp(type, "script") && strcmp(type, "restore"))
 89                         continue;
 90 
 91                 include = fw3_alloc_include(state);
 92                 if (!include)
 93                         continue;
 94 
 95                 if (!fw3_parse_blob_options(include, fw3_include_opts, entry, name))
 96                 {
 97                         warn_section("include", include, NULL, "skipped due to invalid options");
 98                         fw3_free_include(include);
 99                         continue;
100                 }
101 
102                 if (!check_include(state, include, NULL))
103                         fw3_free_include(include);
104         }
105 
106         uci_foreach_element(&p->sections, e)
107         {
108                 s = uci_to_section(e);
109 
110                 if (strcmp(s->type, "include"))
111                         continue;
112 
113                 include = fw3_alloc_include(state);
114                 if (!include)
115                         continue;
116 
117                 include->name = e->name;
118 
119                 if (!fw3_parse_options(include, fw3_include_opts, s))
120                         warn_elem(e, "has invalid options");
121 
122                 if (!check_include(state, include, e))
123                         fw3_free_include(include);
124         }
125 }
126 
127 
128 static void
129 print_include(struct fw3_include *include)
130 {
131         FILE *f;
132         char line[1024];
133 
134         info(" * Loading include '%s'", include->path);
135 
136         if (!(f = fopen(include->path, "r")))
137         {
138                 info("   ! Skipping due to open error: %s", strerror(errno));
139                 return;
140         }
141 
142         while (fgets(line, sizeof(line), f))
143                 fw3_pr("%s", line);
144 
145         fclose(f);
146 }
147 
148 void
149 fw3_print_includes(struct fw3_state *state, enum fw3_family family, bool reload)
150 {
151         struct fw3_include *include;
152 
153         bool exec = false;
154         const char *restore = "iptables-restore";
155 
156         if (family == FW3_FAMILY_V6)
157                 restore = "ip6tables-restore";
158 
159         list_for_each_entry(include, &state->includes, list)
160         {
161                 if (reload && !include->reload)
162                         continue;
163 
164                 if (include->type != FW3_INC_TYPE_RESTORE)
165                         continue;
166 
167                 if (!fw3_is_family(include, family))
168                         continue;
169 
170                 if (!exec)
171                 {
172                         exec = fw3_command_pipe(false, restore, "--noflush");
173 
174                         if (!exec)
175                                 return;
176                 }
177 
178                 print_include(include);
179         }
180 
181         if (exec)
182                 fw3_command_close();
183 }
184 
185 #define TEMPLATE "config() { echo \"You cannot use UCI in firewall includes!\" >&2; exit 1; }; . %s"
186 
187 static void
188 run_include(struct fw3_include *include)
189 {
190         int rv;
191         struct stat s;
192         char buf[PATH_MAX + sizeof(TEMPLATE)];
193 
194         info(" * Running script '%s'", include->path);
195 
196         if (stat(include->path, &s))
197         {
198                 info("   ! Skipping due to path error: %s", strerror(errno));
199                 return;
200         }
201 
202         snprintf(buf, sizeof(buf), TEMPLATE, include->path);
203         rv = system(buf);
204 
205         if (rv)
206                 info("   ! Failed with exit code %u", WEXITSTATUS(rv));
207 }
208 
209 void
210 fw3_run_includes(struct fw3_state *state, bool reload)
211 {
212         struct fw3_include *include;
213 
214         list_for_each_entry(include, &state->includes, list)
215         {
216                 if (reload && !include->reload)
217                         continue;
218 
219                 if (include->type == FW3_INC_TYPE_SCRIPT)
220                         run_include(include);
221         }
222 }
223 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt