X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=iptables-restore.c;fp=iptables-restore.c;h=1cbade76202463e86cf070b2ba5aa11e14b4b4df;hb=a7620a02aaaddfaf83581aade872df16b8724c62;hp=95e2cbea6caf76ef70b0d1c7f99d32b5f6e3a100;hpb=34d283f916eeef73728a99668e40754f3961f580;p=iptables.git diff --git a/iptables-restore.c b/iptables-restore.c index 95e2cbe..1cbade7 100644 --- a/iptables-restore.c +++ b/iptables-restore.c @@ -4,7 +4,7 @@ * * This code is distributed under the terms of GNU GPL v2 * - * $Id: iptables-restore.c 3980 2005-06-12 15:54:15Z /C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=kaber/emailAddress=kaber@netfilter.org $ + * $Id: iptables-restore.c 6828 2007-05-10 15:00:39Z /C=EU/ST=EU/CN=Patrick McHardy/emailAddress=kaber@trash.net $ */ #include @@ -59,19 +59,19 @@ iptc_handle_t create_handle(const char *tablename, const char* modprobe ) if (!handle) { /* try to insmod the module if iptc_init failed */ - iptables_insmod("ip_tables", modprobe); + iptables_insmod("ip_tables", modprobe, 0); handle = iptc_init(tablename); } if (!handle) { - exit_error(PARAMETER_PROBLEM, "%s: unable to initialize" + exit_error(PARAMETER_PROBLEM, "%s: unable to initialize " "table '%s'\n", program_name, tablename); exit(1); } return handle; } -int parse_counters(char *string, struct ipt_counters *ctr) +static int parse_counters(char *string, struct ipt_counters *ctr) { return (sscanf(string, "[%llu:%llu]", (unsigned long long *)&ctr->pcnt, (unsigned long long *)&ctr->bcnt) == 2); } @@ -157,13 +157,13 @@ main(int argc, char *argv[]) if (optind == argc - 1) { in = fopen(argv[optind], "r"); if (!in) { - fprintf(stderr, "Can't open %s: %s", argv[optind], + fprintf(stderr, "Can't open %s: %s\n", argv[optind], strerror(errno)); exit(1); } } else if (optind < argc) { - fprintf(stderr, "Unknown arguments found on commandline"); + fprintf(stderr, "Unknown arguments found on commandline\n"); exit(1); } else in = stdin; @@ -269,7 +269,10 @@ main(int argc, char *argv[]) char *ctrs; ctrs = strtok(NULL, " \t\n"); - parse_counters(ctrs, &count); + if (!ctrs || !parse_counters(ctrs, &count)) + exit_error(PARAMETER_PROBLEM, + "invalid policy counters " + "for chain '%s'\n", chain); } else { memset(&count, 0, @@ -298,8 +301,9 @@ main(int argc, char *argv[]) char *parsestart; /* the parser */ - char *param_start, *curchar; + char *curchar; int quote_open; + int param_len; /* reset the newargv */ newargc = 0; @@ -346,9 +350,11 @@ main(int argc, char *argv[]) * longer a real hacker, but I can live with that */ quote_open = 0; - param_start = parsestart; + param_len = 0; for (curchar = parsestart; *curchar; curchar++) { + char param_buffer[1024]; + if (*curchar == '"') { /* quote_open cannot be true if there * was no previous character. Thus, @@ -357,30 +363,27 @@ main(int argc, char *argv[]) *(curchar-1) != '\\') { quote_open = 0; *curchar = ' '; - } else { + } else if (!quote_open) { quote_open = 1; - param_start++; + continue; } } if (*curchar == ' ' || *curchar == '\t' || * curchar == '\n') { - char param_buffer[1024]; - int param_len = curchar-param_start; - if (quote_open) + if (quote_open) { + param_buffer[param_len++] = + *curchar; continue; + } if (!param_len) { /* two spaces? */ - param_start++; continue; } - - /* end of one parameter */ - strncpy(param_buffer, param_start, - param_len); - *(param_buffer+param_len) = '\0'; + + param_buffer[param_len] = '\0'; /* check if table name specified */ if (!strncmp(param_buffer, "-t", 3) @@ -392,9 +395,26 @@ main(int argc, char *argv[]) } add_argv(param_buffer); - param_start += param_len + 1; + param_len = 0; } else { - /* regular character, skip */ + /* Skip backslash that escapes quote: + * the standard input does not require + * escaping. However, the output + * generated by iptables-save + * introduces bashlash to keep + * consistent with iptables + */ + if (quote_open && + *curchar == '\\' && + *(curchar+1) == '"') + continue; + + /* regular character, copy to buffer */ + param_buffer[param_len++] = *curchar; + + if (param_len >= sizeof(param_buffer)) + exit_error(PARAMETER_PROBLEM, + "Parameter too long!"); } }