All of lore.kernel.org
 help / color / mirror / Atom feed
* [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv()
@ 2019-10-18 15:53 Phil Sutter
  2019-10-18 15:53 ` [iptables PATCH 2/2] xshared: Introduce struct argv_store Phil Sutter
  2019-10-26 10:56 ` [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv() Pablo Neira Ayuso
  0 siblings, 2 replies; 4+ messages in thread
From: Phil Sutter @ 2019-10-18 15:53 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Extend the shared argv parser by storing whether a given argument was
quoted or not, then use it in iptables-xml. One remaining extra bit is
extraction of chain name in -A commands, do that afterwards in a loop.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/iptables-xml.c                       |  78 +-
 .../testcases/ipt-save/0006iptables-xml_0     |  13 +
 .../ipt-save/dumps/fedora27-iptables.xml      | 925 ++++++++++++++++++
 iptables/xshared.c                            |   6 +-
 4 files changed, 949 insertions(+), 73 deletions(-)
 create mode 100755 iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0
 create mode 100644 iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml

diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
index 5255e097eba88..eafee64f5e954 100644
--- a/iptables/iptables-xml.c
+++ b/iptables/iptables-xml.c
@@ -647,78 +647,8 @@ iptables_xml_main(int argc, char *argv[])
 			char *parsestart = buffer;
 			char *chain = NULL;
 
-			/* the parser */
-			char *param_start, *curchar;
-			int quote_open, quoted;
-			char param_buffer[1024];
-
 			tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
-
-			/* This is a 'real' parser crafted in artist mode
-			 * not hacker mode. If the author can live with that
-			 * then so can everyone else */
-
-			quote_open = 0;
-			/* We need to know which args were quoted so we 
-			   can preserve quote */
-			quoted = 0;
-			param_start = parsestart;
-
-			for (curchar = parsestart; *curchar; curchar++) {
-				if (*curchar == '"') {
-					/* quote_open cannot be true if there
-					 * was no previous character.  Thus, 
-					 * curchar-1 has to be within bounds */
-					if (quote_open &&
-					    *(curchar - 1) != '\\') {
-						quote_open = 0;
-						*curchar = ' ';
-					} else {
-						quote_open = 1;
-						quoted = 1;
-						param_start++;
-					}
-				}
-				if (*curchar == ' '
-				    || *curchar == '\t' || *curchar == '\n') {
-					int param_len = curchar - param_start;
-
-					if (quote_open)
-						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';
-
-					/* check if table name specified */
-					if ((param_buffer[0] == '-' &&
-					     param_buffer[1] != '-' &&
-					     strchr(param_buffer, 't')) ||
-					    (!strncmp(param_buffer, "--t", 3) &&
-					     !strncmp(param_buffer, "--table", strlen(param_buffer))))
-						xtables_error(PARAMETER_PROBLEM,
-							   "Line %u seems to have a "
-							   "-t table option.\n",
-							   line);
-
-					add_argv(param_buffer, quoted);
-					if (newargc >= 2
-					    && 0 ==
-					    strcmp(newargv[newargc - 2], "-A"))
-						chain = newargv[newargc - 1];
-					quoted = 0;
-					param_start += param_len + 1;
-				} else {
-					/* regular character, skip */
-				}
-			}
+			add_param_to_argv(parsestart, line);
 
 			DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
 			       newargc, curTable);
@@ -726,6 +656,12 @@ iptables_xml_main(int argc, char *argv[])
 			for (a = 0; a < newargc; a++)
 				DEBUGP("argv[%u]: %s\n", a, newargv[a]);
 
+			for (a = 1; a < newargc; a++) {
+				if (strcmp(newargv[a - 1], "-A"))
+					continue;
+				chain = newargv[a];
+				break;
+			}
 			if (!chain) {
 				fprintf(stderr, "%s: line %u failed - no chain found\n",
 					prog_name, line);
diff --git a/iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0 b/iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0
new file mode 100755
index 0000000000000..50c0cae888341
--- /dev/null
+++ b/iptables/tests/shell/testcases/ipt-save/0006iptables-xml_0
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+case "$(basename $XT_MULTI)" in
+	xtables-legacy-multi)
+		;;
+	*)
+		echo "skip $XT_MULTI"
+		exit 0
+		;;
+esac
+
+dump=$(dirname $0)/dumps/fedora27-iptables
+diff -u -Z <(cat ${dump}.xml) <($XT_MULTI iptables-xml <$dump)
diff --git a/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml b/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml
new file mode 100644
index 0000000000000..400be032fbd20
--- /dev/null
+++ b/iptables/tests/shell/testcases/ipt-save/dumps/fedora27-iptables.xml
@@ -0,0 +1,925 @@
+<iptables-rules version="1.0">
+<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
+<!-- # Generated by iptables*-save v1.6.1 on Sat Feb 17 10:50:33 2018 -->
+  <table name="mangle" >
+    <chain name="PREROUTING" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="1" byte-count="2" >
+       <actions>
+        <call >
+          <PREROUTING_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="3" byte-count="4" >
+       <actions>
+        <call >
+          <PREROUTING_ZONES_SOURCE />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PREROUTING_ZONES />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="INPUT" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <INPUT_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FORWARD" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FORWARD_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="OUTPUT" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <OUTPUT_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="POSTROUTING" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <o >virbr0</o>
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >68</dport>
+        </udp>
+       </conditions>
+       <actions>
+        <CHECKSUM >
+          <checksum-fill  />
+        </CHECKSUM>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <POSTROUTING_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="PREROUTING_ZONES" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >wlp58s0</i>
+        </match>
+       </conditions>
+       <actions>
+        <goto >
+          <PRE_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <goto >
+          <PRE_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="PRE_FedoraWorkstation" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PRE_FedoraWorkstation_log />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PRE_FedoraWorkstation_deny />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PRE_FedoraWorkstation_allow />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FORWARD_direct" packet-count="0" byte-count="0" />
+    <chain name="INPUT_direct" packet-count="0" byte-count="0" />
+    <chain name="OUTPUT_direct" packet-count="0" byte-count="0" />
+    <chain name="POSTROUTING_direct" packet-count="0" byte-count="0" />
+    <chain name="PREROUTING_ZONES_SOURCE" packet-count="0" byte-count="0" />
+    <chain name="PREROUTING_direct" packet-count="0" byte-count="0" />
+    <chain name="PRE_FedoraWorkstation_allow" packet-count="0" byte-count="0" />
+    <chain name="PRE_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
+    <chain name="PRE_FedoraWorkstation_log" packet-count="0" byte-count="0" />
+  </table>
+<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
+<!-- # Generated by iptables*-save v1.6.1 on Sat Feb 17 10:50:33 2018 -->
+  <table name="raw" >
+    <chain name="PREROUTING" policy="ACCEPT" packet-count="1681" byte-count="2620433" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PREROUTING_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PREROUTING_ZONES_SOURCE />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PREROUTING_ZONES />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="OUTPUT" policy="ACCEPT" packet-count="1619" byte-count="171281" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <OUTPUT_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="PREROUTING_ZONES" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >wlp58s0</i>
+        </match>
+       </conditions>
+       <actions>
+        <goto >
+          <PRE_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <goto >
+          <PRE_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="PRE_FedoraWorkstation" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PRE_FedoraWorkstation_log />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PRE_FedoraWorkstation_deny />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <PRE_FedoraWorkstation_allow />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="PRE_FedoraWorkstation_allow" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >137</dport>
+        </udp>
+       </conditions>
+       <actions>
+        <CT >
+          <helper >netbios-ns</helper>
+        </CT>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="OUTPUT_direct" packet-count="0" byte-count="0" />
+    <chain name="PREROUTING_ZONES_SOURCE" packet-count="0" byte-count="0" />
+    <chain name="PREROUTING_direct" packet-count="0" byte-count="0" />
+    <chain name="PRE_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
+    <chain name="PRE_FedoraWorkstation_log" packet-count="0" byte-count="0" />
+  </table>
+<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
+<!-- # Generated by iptables*-save v1.6.1 on Sat Feb 17 10:50:33 2018 -->
+  <table name="filter" >
+    <chain name="INPUT" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="5" byte-count="6" >
+       <conditions>
+        <match >
+          <i >virbr0</i>
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >53</dport>
+        </udp>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="123456789" >
+       <conditions>
+        <match >
+          <i >virbr0</i>
+          <p >tcp</p>
+        </match>
+        <tcp >
+          <dport >53</dport>
+        </tcp>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >virbr0</i>
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >67</dport>
+        </udp>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >virbr0</i>
+          <p >tcp</p>
+        </match>
+        <tcp >
+          <dport >67</dport>
+        </tcp>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <conntrack >
+          <ctstate >RELATED,ESTABLISHED</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >lo</i>
+        </match>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <INPUT_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <INPUT_ZONES_SOURCE />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <INPUT_ZONES />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <conntrack >
+          <ctstate >INVALID</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <DROP  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <REJECT >
+          <reject-with >icmp-host-prohibited</reject-with>
+        </REJECT>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FORWARD" policy="ACCEPT" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <d >192.168.122.0/24</d>
+          <o >virbr0</o>
+        </match>
+        <conntrack >
+          <ctstate >RELATED,ESTABLISHED</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <s >192.168.122.0/24</s>
+          <i >virbr0</i>
+        </match>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >virbr0</i>
+          <o >virbr0</o>
+        </match>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <o >virbr0</o>
+        </match>
+       </conditions>
+       <actions>
+        <REJECT >
+          <reject-with >icmp-port-unreachable</reject-with>
+        </REJECT>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >virbr0</i>
+        </match>
+       </conditions>
+       <actions>
+        <REJECT >
+          <reject-with >icmp-port-unreachable</reject-with>
+        </REJECT>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <conntrack >
+          <ctstate >RELATED,ESTABLISHED</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >lo</i>
+        </match>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FORWARD_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FORWARD_IN_ZONES_SOURCE />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FORWARD_IN_ZONES />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FORWARD_OUT_ZONES_SOURCE />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FORWARD_OUT_ZONES />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <conntrack >
+          <ctstate >INVALID</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <DROP  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <REJECT >
+          <reject-with >icmp-host-prohibited</reject-with>
+        </REJECT>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="OUTPUT" policy="ACCEPT" packet-count="1619" byte-count="171281" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <o >virbr0</o>
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >68</dport>
+        </udp>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <OUTPUT_direct />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FORWARD_IN_ZONES" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >wlp58s0</i>
+        </match>
+       </conditions>
+       <actions>
+        <goto >
+          <FWDI_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <goto >
+          <FWDI_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FORWARD_OUT_ZONES" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <o >wlp58s0</o>
+        </match>
+       </conditions>
+       <actions>
+        <goto >
+          <FWDO_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <goto >
+          <FWDO_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FWDI_FedoraWorkstation" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FWDI_FedoraWorkstation_log />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FWDI_FedoraWorkstation_deny />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FWDI_FedoraWorkstation_allow />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >icmp</p>
+        </match>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FWDO_FedoraWorkstation" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FWDO_FedoraWorkstation_log />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FWDO_FedoraWorkstation_deny />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <FWDO_FedoraWorkstation_allow />
+        </call>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="INPUT_ZONES" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <i >wlp58s0</i>
+        </match>
+       </conditions>
+       <actions>
+        <goto >
+          <IN_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <goto >
+          <IN_FedoraWorkstation />
+        </goto>
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="IN_FedoraWorkstation" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <IN_FedoraWorkstation_log />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <IN_FedoraWorkstation_deny />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <actions>
+        <call >
+          <IN_FedoraWorkstation_allow />
+        </call>
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >icmp</p>
+        </match>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="IN_FedoraWorkstation_allow" packet-count="0" byte-count="0" >
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >137</dport>
+        </udp>
+        <conntrack >
+          <ctstate >NEW</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >138</dport>
+        </udp>
+        <conntrack >
+          <ctstate >NEW</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >tcp</p>
+        </match>
+        <tcp >
+          <dport >22</dport>
+        </tcp>
+        <conntrack >
+          <ctstate >NEW</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <d >224.0.0.251/32</d>
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >5353</dport>
+        </udp>
+        <conntrack >
+          <ctstate >NEW</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="0" byte-count="0" >
+       <conditions>
+        <match >
+          <p >udp</p>
+        </match>
+        <udp >
+          <dport >1025:65535</dport>
+        </udp>
+        <conntrack >
+          <ctstate >NEW</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+      <rule packet-count="7" byte-count="8" >
+       <conditions>
+        <match >
+          <p >tcp</p>
+        </match>
+        <tcp >
+          <dport >1025:65535</dport>
+        </tcp>
+        <conntrack >
+          <ctstate >NEW</ctstate>
+        </conntrack>
+       </conditions>
+       <actions>
+        <ACCEPT  />
+       </actions>
+
+      </rule>
+
+    </chain>
+    <chain name="FORWARD_IN_ZONES_SOURCE" packet-count="0" byte-count="0" />
+    <chain name="FORWARD_OUT_ZONES_SOURCE" packet-count="0" byte-count="0" />
+    <chain name="FORWARD_direct" packet-count="0" byte-count="0" />
+    <chain name="FWDI_FedoraWorkstation_allow" packet-count="0" byte-count="0" />
+    <chain name="FWDI_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
+    <chain name="FWDI_FedoraWorkstation_log" packet-count="0" byte-count="0" />
+    <chain name="FWDO_FedoraWorkstation_allow" packet-count="0" byte-count="0" />
+    <chain name="FWDO_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
+    <chain name="FWDO_FedoraWorkstation_log" packet-count="0" byte-count="0" />
+    <chain name="INPUT_ZONES_SOURCE" packet-count="0" byte-count="0" />
+    <chain name="INPUT_direct" packet-count="0" byte-count="0" />
+    <chain name="IN_FedoraWorkstation_deny" packet-count="0" byte-count="0" />
+    <chain name="IN_FedoraWorkstation_log" packet-count="0" byte-count="0" />
+    <chain name="OUTPUT_direct" packet-count="0" byte-count="0" />
+  </table>
+<!-- # Completed on Sat Feb 17 10:50:33 2018 -->
+</iptables-rules>
diff --git a/iptables/xshared.c b/iptables/xshared.c
index ba723f59dbaad..4c012e32c775f 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -484,7 +484,7 @@ static void add_param(struct xt_param_buf *param, const char *curchar)
 
 void add_param_to_argv(char *parsestart, int line)
 {
-	int quote_open = 0, escaped = 0;
+	int quote_open = 0, escaped = 0, quoted = 0;
 	struct xt_param_buf param = {};
 	char *curchar;
 
@@ -511,6 +511,7 @@ void add_param_to_argv(char *parsestart, int line)
 		} else {
 			if (*curchar == '"') {
 				quote_open = 1;
+				quoted = 1;
 				continue;
 			}
 		}
@@ -545,8 +546,9 @@ void add_param_to_argv(char *parsestart, int line)
 				      line, xt_params->program_name);
 		}
 
-		add_argv(param.buffer, 0);
+		add_argv(param.buffer, quoted);
 		param.len = 0;
+		quoted = 0;
 	}
 }
 
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [iptables PATCH 2/2] xshared: Introduce struct argv_store
  2019-10-18 15:53 [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv() Phil Sutter
@ 2019-10-18 15:53 ` Phil Sutter
  2019-10-26 10:56   ` Pablo Neira Ayuso
  2019-10-26 10:56 ` [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv() Pablo Neira Ayuso
  1 sibling, 1 reply; 4+ messages in thread
From: Phil Sutter @ 2019-10-18 15:53 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

Make add_argv() and related routines reentrant by introducing a data
structure to hold the stored arguments.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 iptables/iptables-restore.c | 28 +++++++-------
 iptables/iptables-xml.c     | 30 ++++++++-------
 iptables/xshared.c          | 76 +++++++++++++++++++------------------
 iptables/xshared.h          | 26 +++++++------
 iptables/xtables-restore.c  | 31 +++++++--------
 5 files changed, 96 insertions(+), 95 deletions(-)

diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c
index 50d0708eff1f3..b0a51d491c508 100644
--- a/iptables/iptables-restore.c
+++ b/iptables/iptables-restore.c
@@ -94,6 +94,7 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb,
 			int argc, char *argv[])
 {
 	struct xtc_handle *handle = NULL;
+	struct argv_store av_store = {};
 	char buffer[10240];
 	int c, lock;
 	char curtable[XT_TABLE_MAXNAMELEN + 1] = {};
@@ -311,34 +312,31 @@ ip46tables_restore_main(const struct iptables_restore_cb *cb,
 			ret = 1;
 
 		} else if (in_table) {
-			int a;
 			char *pcnt = NULL;
 			char *bcnt = NULL;
 			char *parsestart = buffer;
 
-			add_argv(argv[0], 0);
-			add_argv("-t", 0);
-			add_argv(curtable, 0);
+			add_argv(&av_store, argv[0], 0);
+			add_argv(&av_store, "-t", 0);
+			add_argv(&av_store, curtable, 0);
 
 			tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
 			if (counters && pcnt && bcnt) {
-				add_argv("--set-counters", 0);
-				add_argv(pcnt, 0);
-				add_argv(bcnt, 0);
+				add_argv(&av_store, "--set-counters", 0);
+				add_argv(&av_store, pcnt, 0);
+				add_argv(&av_store, bcnt, 0);
 			}
 
-			add_param_to_argv(parsestart, line);
+			add_param_to_argv(&av_store, parsestart, line);
 
 			DEBUGP("calling do_command(%u, argv, &%s, handle):\n",
-				newargc, curtable);
+				av_store.argc, curtable);
+			debug_print_argv(&av_store);
 
-			for (a = 0; a < newargc; a++)
-				DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+			ret = cb->do_command(av_store.argc, av_store.argv,
+					 &av_store.argv[2], &handle, true);
 
-			ret = cb->do_command(newargc, newargv,
-					 &newargv[2], &handle, true);
-
-			free_argv();
+			free_argv(&av_store);
 			fflush(stdout);
 		}
 		if (tablename && strcmp(tablename, curtable) != 0)
diff --git a/iptables/iptables-xml.c b/iptables/iptables-xml.c
index eafee64f5e954..98d03dda98d2b 100644
--- a/iptables/iptables-xml.c
+++ b/iptables/iptables-xml.c
@@ -440,7 +440,7 @@ do_rule_part(char *leveltag1, char *leveltag2, int part, int argc,
 }
 
 static int
-compareRules(void)
+compareRules(int newargc, char *newargv[], int oldargc, char *oldargv[])
 {
 	/* Compare arguments up to -j or -g for match.
 	 * NOTE: We don't want to combine actions if there were no criteria
@@ -489,11 +489,13 @@ compareRules(void)
 
 /* has a nice parsed rule starting with -A */
 static void
-do_rule(char *pcnt, char *bcnt, int argc, char *argv[], int argvattr[])
+do_rule(char *pcnt, char *bcnt, int argc, char *argv[], int argvattr[],
+	int oldargc, char *oldargv[])
 {
 	/* are these conditions the same as the previous rule?
 	 * If so, skip arg straight to -j or -g */
-	if (combine && argc > 2 && !isTarget(argv[2]) && compareRules()) {
+	if (combine && argc > 2 && !isTarget(argv[2]) &&
+	    compareRules(argc, argv, oldargc, oldargv)) {
 		xmlComment("Combine action from next rule");
 	} else {
 
@@ -539,6 +541,7 @@ do_rule(char *pcnt, char *bcnt, int argc, char *argv[], int argvattr[])
 int
 iptables_xml_main(int argc, char *argv[])
 {
+	struct argv_store last_rule = {}, cur_rule = {};
 	char buffer[10240];
 	int c;
 	FILE *in;
@@ -648,18 +651,16 @@ iptables_xml_main(int argc, char *argv[])
 			char *chain = NULL;
 
 			tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
-			add_param_to_argv(parsestart, line);
+			add_param_to_argv(&cur_rule, parsestart, line);
 
 			DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
-			       newargc, curTable);
+			       cur_rule.argc, curTable);
+			debug_print_argv(&cur_rule);
 
-			for (a = 0; a < newargc; a++)
-				DEBUGP("argv[%u]: %s\n", a, newargv[a]);
-
-			for (a = 1; a < newargc; a++) {
-				if (strcmp(newargv[a - 1], "-A"))
+			for (a = 1; a < cur_rule.argc; a++) {
+				if (strcmp(cur_rule.argv[a - 1], "-A"))
 					continue;
-				chain = newargv[a];
+				chain = cur_rule.argv[a];
 				break;
 			}
 			if (!chain) {
@@ -668,9 +669,10 @@ iptables_xml_main(int argc, char *argv[])
 				exit(1);
 			}
 			needChain(chain);// Should we explicitly look for -A
-			do_rule(pcnt, bcnt, newargc, newargv, newargvattr);
+			do_rule(pcnt, bcnt, cur_rule.argc, cur_rule.argv,
+				cur_rule.argvattr, last_rule.argc, last_rule.argv);
 
-			save_argv();
+			save_argv(&last_rule, &cur_rule);
 			ret = 1;
 		}
 		if (!ret) {
@@ -687,7 +689,7 @@ iptables_xml_main(int argc, char *argv[])
 
 	fclose(in);
 	printf("</iptables-rules>\n");
-	free_argv();
+	free_argv(&last_rule);
 
 	return 0;
 }
diff --git a/iptables/xshared.c b/iptables/xshared.c
index 4c012e32c775f..112b54e6bef55 100644
--- a/iptables/xshared.c
+++ b/iptables/xshared.c
@@ -417,56 +417,48 @@ inline bool xs_has_arg(int argc, char *argv[])
 	       argv[optind][0] != '!';
 }
 
-/* global new argv and argc */
-char *newargv[255];
-int newargc = 0;
-
-/* saved newargv and newargc from save_argv() */
-char *oldargv[255];
-int oldargc = 0;
-
-/* arg meta data, were they quoted, frinstance */
-int newargvattr[255];
-
-/* function adding one argument to newargv, updating newargc
- * returns true if argument added, false otherwise */
-int add_argv(const char *what, int quoted)
+/* function adding one argument to store, updating argc
+ * returns if argument added, does not return otherwise */
+void add_argv(struct argv_store *store, const char *what, int quoted)
 {
 	DEBUGP("add_argv: %s\n", what);
-	if (what && newargc + 1 < ARRAY_SIZE(newargv)) {
-		newargv[newargc] = strdup(what);
-		newargvattr[newargc] = quoted;
-		newargv[++newargc] = NULL;
-		return 1;
-	} else {
+
+	if (store->argc + 1 >= MAX_ARGC)
 		xtables_error(PARAMETER_PROBLEM,
 			      "Parser cannot handle more arguments\n");
-	}
+	if (!what)
+		xtables_error(PARAMETER_PROBLEM,
+			      "Trying to store NULL argument\n");
+
+	store->argv[store->argc] = strdup(what);
+	store->argvattr[store->argc] = quoted;
+	store->argv[++store->argc] = NULL;
 }
 
-void free_argv(void)
+void free_argv(struct argv_store *store)
 {
-	while (newargc)
-		free(newargv[--newargc]);
-	while (oldargc)
-		free(oldargv[--oldargc]);
+	while (store->argc) {
+		store->argc--;
+		free(store->argv[store->argc]);
+		store->argvattr[store->argc] = 0;
+	}
 }
 
 /* Save parsed rule for comparison with next rule to perform action aggregation
  * on duplicate conditions.
  */
-void save_argv(void)
+void save_argv(struct argv_store *dst, struct argv_store *src)
 {
-	unsigned int i;
+	int i;
 
-	while (oldargc)
-		free(oldargv[--oldargc]);
-
-	oldargc = newargc;
-	newargc = 0;
-	for (i = 0; i < oldargc; i++) {
-		oldargv[i] = newargv[i];
+	free_argv(dst);
+	for (i = 0; i < src->argc; i++) {
+		dst->argvattr[i] = src->argvattr[i];
+		dst->argv[i] = src->argv[i];
+		src->argv[i] = NULL;
 	}
+	dst->argc = src->argc;
+	src->argc = 0;
 }
 
 struct xt_param_buf {
@@ -482,7 +474,7 @@ static void add_param(struct xt_param_buf *param, const char *curchar)
 			      "Parameter too long!");
 }
 
-void add_param_to_argv(char *parsestart, int line)
+void add_param_to_argv(struct argv_store *store, char *parsestart, int line)
 {
 	int quote_open = 0, escaped = 0, quoted = 0;
 	struct xt_param_buf param = {};
@@ -546,12 +538,22 @@ void add_param_to_argv(char *parsestart, int line)
 				      line, xt_params->program_name);
 		}
 
-		add_argv(param.buffer, quoted);
+		add_argv(store, param.buffer, quoted);
 		param.len = 0;
 		quoted = 0;
 	}
 }
 
+#ifdef DEBUG
+void debug_print_argv(struct argv_store *store)
+{
+	int i;
+
+	for (i = 0; i < store->argc; i++)
+		fprintf(stderr, "argv[%d]: %s\n", i, store->argv[i]);
+}
+#endif
+
 static const char *ipv4_addr_to_string(const struct in_addr *addr,
 				       const struct in_addr *mask,
 				       unsigned int format)
diff --git a/iptables/xshared.h b/iptables/xshared.h
index 21f4e8fdee67c..64b7e8fc4b690 100644
--- a/iptables/xshared.h
+++ b/iptables/xshared.h
@@ -156,18 +156,22 @@ bool xs_has_arg(int argc, char *argv[]);
 
 extern const struct xtables_afinfo *afinfo;
 
-extern char *newargv[];
-extern int newargc;
-
-extern char *oldargv[];
-extern int oldargc;
-
-extern int newargvattr[];
+#define MAX_ARGC	255
+struct argv_store {
+	int argc;
+	char *argv[MAX_ARGC];
+	int argvattr[MAX_ARGC];
+};
 
-int add_argv(const char *what, int quoted);
-void free_argv(void);
-void save_argv(void);
-void add_param_to_argv(char *parsestart, int line);
+void add_argv(struct argv_store *store, const char *what, int quoted);
+void free_argv(struct argv_store *store);
+void save_argv(struct argv_store *dst, struct argv_store *src);
+void add_param_to_argv(struct argv_store *store, char *parsestart, int line);
+#ifdef DEBUG
+void debug_print_argv(struct argv_store *store);
+#else
+#  define debug_print_argv(...) /* nothing */
+#endif
 
 void print_ipv4_addresses(const struct ipt_entry *fw, unsigned int format);
 void print_ipv6_addresses(const struct ip6t_entry *fw6, unsigned int format);
diff --git a/iptables/xtables-restore.c b/iptables/xtables-restore.c
index 1c7d5da52df64..8d6cb7a97ea37 100644
--- a/iptables/xtables-restore.c
+++ b/iptables/xtables-restore.c
@@ -73,6 +73,7 @@ void xtables_restore_parse(struct nft_handle *h,
 			   const struct nft_xt_restore_cb *cb)
 {
 	const struct builtin_table *curtable = NULL;
+	struct argv_store av_store = {};
 	char buffer[10240];
 	int in_table = 0;
 
@@ -209,35 +210,29 @@ void xtables_restore_parse(struct nft_handle *h,
 			}
 			ret = 1;
 		} else if (in_table) {
-			int a;
 			char *pcnt = NULL;
 			char *bcnt = NULL;
 			char *parsestart = buffer;
 
-			/* reset the newargv */
-			newargc = 0;
-
-			add_argv(xt_params->program_name, 0);
-			add_argv("-t", 0);
-			add_argv(curtable->name, 0);
+			add_argv(&av_store, xt_params->program_name, 0);
+			add_argv(&av_store, "-t", 0);
+			add_argv(&av_store, curtable->name, 0);
 
 			tokenize_rule_counters(&parsestart, &pcnt, &bcnt, line);
 			if (counters && pcnt && bcnt) {
-				add_argv("--set-counters", 0);
-				add_argv(pcnt, 0);
-				add_argv(bcnt, 0);
+				add_argv(&av_store, "--set-counters", 0);
+				add_argv(&av_store, pcnt, 0);
+				add_argv(&av_store, bcnt, 0);
 			}
 
-			add_param_to_argv(parsestart, line);
+			add_param_to_argv(&av_store, parsestart, line);
 
 			DEBUGP("calling do_command4(%u, argv, &%s, handle):\n",
-				newargc, curtable->name);
-
-			for (a = 0; a < newargc; a++)
-				DEBUGP("argv[%u]: %s\n", a, newargv[a]);
+			       av_store.argc, curtable->name);
+			debug_print_argv(&av_store);
 
-			ret = cb->do_command(h, newargc, newargv,
-					    &newargv[2], true);
+			ret = cb->do_command(h, av_store.argc, av_store.argv,
+					    &av_store.argv[2], true);
 			if (ret < 0) {
 				if (cb->abort)
 					ret = cb->abort(h);
@@ -251,7 +246,7 @@ void xtables_restore_parse(struct nft_handle *h,
 				exit(1);
 			}
 
-			free_argv();
+			free_argv(&av_store);
 			fflush(stdout);
 		}
 		if (p->tablename && curtable &&
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv()
  2019-10-18 15:53 [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv() Phil Sutter
  2019-10-18 15:53 ` [iptables PATCH 2/2] xshared: Introduce struct argv_store Phil Sutter
@ 2019-10-26 10:56 ` Pablo Neira Ayuso
  1 sibling, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-10-26 10:56 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netfilter-devel

On Fri, Oct 18, 2019 at 05:53:08PM +0200, Phil Sutter wrote:
> Extend the shared argv parser by storing whether a given argument was
> quoted or not, then use it in iptables-xml. One remaining extra bit is
> extraction of chain name in -A commands, do that afterwards in a loop.
> 
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [iptables PATCH 2/2] xshared: Introduce struct argv_store
  2019-10-18 15:53 ` [iptables PATCH 2/2] xshared: Introduce struct argv_store Phil Sutter
@ 2019-10-26 10:56   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-10-26 10:56 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netfilter-devel

On Fri, Oct 18, 2019 at 05:53:09PM +0200, Phil Sutter wrote:
> Make add_argv() and related routines reentrant by introducing a data
> structure to hold the stored arguments.
> 
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-26 10:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-18 15:53 [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv() Phil Sutter
2019-10-18 15:53 ` [iptables PATCH 2/2] xshared: Introduce struct argv_store Phil Sutter
2019-10-26 10:56   ` Pablo Neira Ayuso
2019-10-26 10:56 ` [iptables PATCH 1/2] iptables-xml: Use add_param_to_argv() Pablo Neira Ayuso

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.