From: Jo-Philipp Wich Date: Fri, 22 Feb 2013 00:41:53 +0000 (+0100) Subject: add support for includes X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=bd574af529c0661c125336bdd9d0d1f2e09287c3;p=oweals%2Ffirewall3.git add support for includes --- diff --git a/CMakeLists.txt b/CMakeLists.txt index e944949..01d2c7c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ IF(APPLE) LINK_DIRECTORIES(/opt/local/lib) ENDIF() -ADD_EXECUTABLE(firewall3 main.c options.c defaults.c zones.c forwards.c rules.c redirects.c utils.c ubus.c ipsets.c) +ADD_EXECUTABLE(firewall3 main.c options.c defaults.c zones.c forwards.c rules.c redirects.c utils.c ubus.c ipsets.c includes.c) TARGET_LINK_LIBRARIES(firewall3 uci ubox ubus) SET(CMAKE_INSTALL_PREFIX /usr) diff --git a/includes.c b/includes.c new file mode 100644 index 0000000..40995ca --- /dev/null +++ b/includes.c @@ -0,0 +1,144 @@ +/* + * firewall3 - 3rd OpenWrt UCI firewall implementation + * + * Copyright (C) 2013 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + + +const struct fw3_option fw3_include_opts[] = { + FW3_OPT("path", string, include, path), + FW3_OPT("type", include_type, include, type), + FW3_OPT("family", family, include, family), + + { } +}; + + +void +fw3_load_includes(struct fw3_state *state, struct uci_package *p) +{ + struct uci_section *s; + struct uci_element *e; + struct fw3_include *include; + + INIT_LIST_HEAD(&state->includes); + + uci_foreach_element(&p->sections, e) + { + s = uci_to_section(e); + + if (strcmp(s->type, "include")) + continue; + + include = malloc(sizeof(*include)); + + if (!include) + continue; + + memset(include, 0, sizeof(*include)); + include->name = e->name; + + fw3_parse_options(include, fw3_include_opts, s); + + if (!include->path) + { + warn_elem(e, "must specify a path"); + fw3_free_include(include); + continue; + } + + if (include->type == FW3_INC_TYPE_RESTORE && !include->family) + warn_elem(e, "does not specify a family, include will get loaded " + "with both iptables-restore and ip6tables-restore!"); + + list_add_tail(&include->list, &state->includes); + continue; + } +} + + +static void +print_include(enum fw3_family family, struct fw3_include *include) +{ + FILE *f; + char line[1024]; + + if (!fw3_is_family(include, family)) + return; + + info(" * Loading include '%s'", include->path); + + if (!(f = fopen(include->path, "r"))) + { + info(" ! Skipping due to open error: %s", strerror(errno)); + return; + } + + while (fgets(line, sizeof(line), f)) + fw3_pr(line); + + fclose(f); +} + +void +fw3_print_includes(enum fw3_family family, struct fw3_state *state) +{ + struct fw3_include *include; + + list_for_each_entry(include, &state->includes, list) + if (include->type == FW3_INC_TYPE_RESTORE) + print_include(family, include); +} + + +static void +run_include(struct fw3_include *include) +{ + int rv; + struct stat s; + const char *tmpl = + "config() { " + "echo \"You cannot use UCI in firewall includes!\" >&2; " + "exit 1; " + "}; . %s"; + + char buf[PATH_MAX + sizeof(tmpl)]; + + info(" * Running script '%s'", include->path); + + if (stat(include->path, &s)) + { + info(" ! Skipping due to path error: %s", strerror(errno)); + return; + } + + snprintf(buf, sizeof(buf), tmpl, include->path); + rv = system(buf); + + if (rv) + info(" ! Failed with exit code %u", WEXITSTATUS(rv)); +} + +void +fw3_run_includes(struct fw3_state *state) +{ + struct fw3_include *include; + + list_for_each_entry(include, &state->includes, list) + if (include->type == FW3_INC_TYPE_SCRIPT) + run_include(include); +} diff --git a/includes.h b/includes.h new file mode 100644 index 0000000..5c091b7 --- /dev/null +++ b/includes.h @@ -0,0 +1,34 @@ +/* + * firewall3 - 3rd OpenWrt UCI firewall implementation + * + * Copyright (C) 2013 Jo-Philipp Wich + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __FW3_INCLUDES_H +#define __FW3_INCLUDES_H + +#include "options.h" +#include "utils.h" + +extern const struct fw3_option fw3_include_opts[]; + +void fw3_load_includes(struct fw3_state *state, struct uci_package *p); +void fw3_print_includes(enum fw3_family family, struct fw3_state *state); +void fw3_run_includes(struct fw3_state *state); + +#define fw3_free_include(include) \ + fw3_free_object(include, fw3_include_opts) + +#endif diff --git a/main.c b/main.c index 62f51e1..e584827 100644 --- a/main.c +++ b/main.c @@ -26,6 +26,7 @@ #include "redirects.h" #include "forwards.h" #include "ipsets.h" +#include "includes.h" #include "ubus.h" @@ -71,6 +72,7 @@ build_state(void) fw3_load_rules(state, p); fw3_load_redirects(state, p); fw3_load_forwards(state, p); + fw3_load_includes(state, p); state->statefile = fw3_read_statefile(state); @@ -97,6 +99,9 @@ free_state(struct fw3_state *state) list_for_each_safe(cur, tmp, &state->ipsets) fw3_free_ipset((struct fw3_ipset *)cur); + list_for_each_safe(cur, tmp, &state->includes) + fw3_free_include((struct fw3_include *)cur); + uci_free_context(state->uci); free(state); diff --git a/options.c b/options.c index d924a2a..3f8c977 100644 --- a/options.c +++ b/options.c @@ -672,6 +672,19 @@ fw3_parse_monthdays(void *ptr, const char *val) return true; } +bool +fw3_parse_include_type(void *ptr, const char *val) +{ + if (!strcmp(val, "script")) + *((enum fw3_include_type *)ptr) = FW3_INC_TYPE_SCRIPT; + else if (!strcmp(val, "restore")) + *((enum fw3_include_type *)ptr) = FW3_INC_TYPE_RESTORE; + else + return false; + + return true; +} + void fw3_parse_options(void *s, const struct fw3_option *opts, diff --git a/options.h b/options.h index fe9816e..a9257a3 100644 --- a/options.h +++ b/options.h @@ -110,6 +110,12 @@ enum fw3_ipset_type FW3_IPSET_TYPE_SET = 5, }; +enum fw3_include_type +{ + FW3_INC_TYPE_SCRIPT = 0, + FW3_INC_TYPE_RESTORE = 1, +}; + struct fw3_ipset_datatype { struct list_head list; @@ -385,6 +391,18 @@ struct fw3_ipset uint16_t flags; }; +struct fw3_include +{ + struct list_head list; + struct list_head running_list; + + const char *name; + enum fw3_family family; + + const char *path; + enum fw3_include_type type; +}; + struct fw3_state { struct uci_context *uci; @@ -394,6 +412,7 @@ struct fw3_state struct list_head redirects; struct list_head forwards; struct list_head ipsets; + struct list_head includes; struct fw3_defaults running_defaults; struct list_head running_zones; @@ -436,6 +455,8 @@ bool fw3_parse_protocol(void *ptr, const char *val); bool fw3_parse_ipset_method(void *ptr, const char *val); bool fw3_parse_ipset_datatype(void *ptr, const char *val); +bool fw3_parse_include_type(void *ptr, const char *val); + bool fw3_parse_date(void *ptr, const char *val); bool fw3_parse_time(void *ptr, const char *val); bool fw3_parse_weekdays(void *ptr, const char *val);