X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=extensions%2Flibipt_string.c;fp=extensions%2Flibipt_string.c;h=508eb90b1eae53836e9b92ba7d5a50a466f48ee6;hb=6afea0b41dfbc3824956d11d960ad80097218feb;hp=b4710f9738edae0775919cb7be1950120a6bdcaa;hpb=f7b70cf9e00324b89b02de213bcd0dde7044d035;p=iptables.git diff --git a/extensions/libipt_string.c b/extensions/libipt_string.c index b4710f9..508eb90 100644 --- a/extensions/libipt_string.c +++ b/extensions/libipt_string.c @@ -3,6 +3,13 @@ * Copyright (C) 2000 Emmanuel Roger * * ChangeLog + * 29.12.2003: Michael Rash + * Fixed iptables save/restore for ascii strings + * that contain space chars, and hex strings that + * contain embedded NULL chars. Updated to print + * strings in hex mode if any non-printable char + * is contained within the string. + * * 27.01.2001: Gianni Tedesco * Changed --tos to --string in save(). Also * updated to work with slightly modified @@ -37,15 +44,6 @@ static struct option opts[] = { { .name = 0 } }; - -/* Initialize the match. */ -static void -init(struct ipt_entry_match *m, unsigned int *nfcache) -{ - *nfcache |= NFC_UNKNOWN; -} - - static void parse_string(const unsigned char *s, struct ipt_string_info *info) { @@ -77,8 +75,12 @@ parse_hex_string(const unsigned char *s, struct ipt_string_info *info) } else if (s[i] == '|') { if (hex_f) hex_f = 0; - else + else { hex_f = 1; + /* get past any initial whitespace just after the '|' */ + while (s[i+1] == ' ') + i++; + } if (i+1 >= slen) break; else @@ -178,9 +180,53 @@ final_check(unsigned int flags) { if (!flags) exit_error(PARAMETER_PROBLEM, - "STRING match: You must specify `--string'"); + "STRING match: You must specify `--string' or `--hex-string'"); } +/* Test to see if the string contains non-printable chars or quotes */ +static unsigned short int +is_hex_string(const char *str, const unsigned short int len) +{ + unsigned int i; + for (i=0; i < len; i++) + if (! isprint(str[i])) + return 1; /* string contains at least one non-printable char */ + /* use hex output if the last char is a "\" */ + if ((unsigned char) str[len-1] == 0x5c) + return 1; + return 0; +} + +/* Print string with "|" chars included as one would pass to --hex-string */ +static void +print_hex_string(const char *str, const unsigned short int len) +{ + unsigned int i; + /* start hex block */ + printf("\"|"); + for (i=0; i < len; i++) { + /* see if we need to prepend a zero */ + if ((unsigned char) str[i] <= 0x0F) + printf("0%x", (unsigned char) str[i]); + else + printf("%x", (unsigned char) str[i]); + } + /* close hex block */ + printf("|\" "); +} + +static void +print_string(const char *str, const unsigned short int len) +{ + unsigned int i; + printf("\""); + for (i=0; i < len; i++) { + if ((unsigned char) str[i] == 0x22) /* escape any embedded quotes */ + printf("%c", 0x5c); + printf("%c", (unsigned char) str[i]); + } + printf("\" "); /* closing space and quote */ +} /* Prints out the matchinfo. */ static void @@ -191,7 +237,13 @@ print(const struct ipt_ip *ip, const struct ipt_string_info *info = (const struct ipt_string_info*) match->data; - printf("STRING match %s%s ", (info->invert) ? "!" : "", info->string); + if (is_hex_string(info->string, info->len)) { + printf("STRING match %s", (info->invert) ? "!" : ""); + print_hex_string(info->string, info->len); + } else { + printf("STRING match %s", (info->invert) ? "!" : ""); + print_string(info->string, info->len); + } } @@ -202,7 +254,13 @@ save(const struct ipt_ip *ip, const struct ipt_entry_match *match) const struct ipt_string_info *info = (const struct ipt_string_info*) match->data; - printf("--string %s%s ", (info->invert) ? "! ": "", info->string); + if (is_hex_string(info->string, info->len)) { + printf("--hex-string %s", (info->invert) ? "! ": ""); + print_hex_string(info->string, info->len); + } else { + printf("--string %s", (info->invert) ? "! ": ""); + print_string(info->string, info->len); + } } @@ -212,7 +270,6 @@ static struct iptables_match string = { .size = IPT_ALIGN(sizeof(struct ipt_string_info)), .userspacesize = IPT_ALIGN(sizeof(struct ipt_string_info)), .help = &help, - .init = &init, .parse = &parse, .final_check = &final_check, .print = &print,