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