[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH v2 2/5] Instantiate comments in ip(6)tables rules



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 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]