V2 changes:
following Eric's comments:
- commands in the script are assigned using cmd='...' rather than
cmd="..."
- invoke commands using eval res=... rather than res=eval ...
- rewrote function escaping ` and single quotes (which became more tricky)
In this patch I am extending the rule instantiator to create the comment
node where supported, which is the case for iptables and ip6tables.
Since commands are written in the format
cmd='iptables ...-m comment --comment \"\" '
certain characters ('`) in the comment need to be escaped to
prevent comments from becoming commands themselves or cause other
forms of (bash) substitutions. I have tested this with various input and in
my tests the input made it straight into the comment. A test case for TCK
will be provided separately that tests this.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
src/nwfilter/nwfilter_ebiptables_driver.c | 57 ++++++++++++++++++++++++++++--
src/nwfilter/nwfilter_ebiptables_driver.h | 2 +
2 files changed, 56 insertions(+), 3 deletions(-)
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -23,6 +23,7 @@
#include <config.h>
+#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -52,10 +53,10 @@
#define CMD_SEPARATOR "\n"
-#define CMD_DEF_PRE "cmd=\""
-#define CMD_DEF_POST "\""
+#define CMD_DEF_PRE "cmd='"
+#define CMD_DEF_POST "'"
#define CMD_DEF(X) CMD_DEF_PRE X CMD_DEF_POST
-#define CMD_EXEC "res=`${cmd}`" CMD_SEPARATOR
+#define CMD_EXEC "eval res=\\`\"${cmd}\"\\`" CMD_SEPARATOR
#define CMD_STOPONERR(X) \
X ? "if [ $? -ne 0 ]; then" \
" echo \"Failure to execute command '${cmd}'.\";" \
@@ -291,6 +292,46 @@ printDataTypeAsHex(virNWFilterHashTableP
}
+static char *
+escapeComment(const char *buf)
+{
+ char *res;
+ size_t i, j, add = 0, len = strlen(buf);
+
+ static const char SINGLEQUOTE_REPLACEMENT[12] =
"'\\'\\\"\\'\\\"\\''";
+
+ if (len > IPTABLES_MAX_COMMENT_SIZE)
+ len = IPTABLES_MAX_COMMENT_SIZE;
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] == '`')
+ add++;
+ else if (buf[i] == '\'')
+ add += sizeof(SINGLEQUOTE_REPLACEMENT);
+ }
+
+ if (VIR_ALLOC_VAR(res, char, len+add+1) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ j = 0;
+ for (i = 0; i < len; i++) {
+ if (buf[i] == '`')
+ res[j++] = '\\';
+ else if (buf[i] == '\'') {
+ strcpy(&res[j], SINGLEQUOTE_REPLACEMENT);
+ j += sizeof(SINGLEQUOTE_REPLACEMENT);
+ continue;
+ }
+ res[j++] = buf[i];
+ }
+ res[j] = 0;
+
+ return res;
+}
+
+
static void
ebiptablesRuleInstFree(ebiptablesRuleInstPtr inst)
{
@@ -993,6 +1034,16 @@ iptablesHandleIpHdr(virBufferPtr buf,
}
}
+ if (HAS_ENTRY_ITEM(&ipHdr->dataComment)) {
+ char *cmt = escapeComment(ipHdr->dataComment.u.string);
+ if (!cmt)
+ goto err_exit;
+ virBufferVSprintf(buf,
+ " -m comment --comment
'\\''%s'\\''",
+ cmt);
+ VIR_FREE(cmt);
+ }
+
return 0;
err_exit:
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.h
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.h
@@ -45,4 +45,6 @@ extern virNWFilterTechDriver ebiptables_
# define EBIPTABLES_DRIVER_ID "ebiptables"
+# define IPTABLES_MAX_COMMENT_SIZE 256
+
#endif