diff -up firewalld-0.3.9/doc/xml/firewall-cmd.xml.RHBZ#993650_add firewalld-0.3.9/doc/xml/firewall-cmd.xml --- firewalld-0.3.9/doc/xml/firewall-cmd.xml.RHBZ#993650_add 2014-10-20 22:03:54.453869807 +0200 +++ firewalld-0.3.9/doc/xml/firewall-cmd.xml 2014-10-20 22:03:54.460869767 +0200 @@ -943,16 +943,16 @@ - Get all permanent passthrough as a newline separated list of the ipv value and arguments. + Get all passthrough rules as a newline separated list of the ipv value and arguments. - { ipv4 | ipv6 | eb } + { ipv4 | ipv6 | eb } - Get all permanent passthrough rules for the ipv value as a newline separated list of the priority and arguments. + Get all passthrough rules for the ipv value as a newline separated list of the priority and arguments. @@ -961,7 +961,7 @@ { ipv4 | ipv6 | eb } args - Add a permanent passthrough rule with the arguments args for the ipv value. + Add a passthrough rule with the arguments args for the ipv value. @@ -970,7 +970,7 @@ { ipv4 | ipv6 | eb } args - Remove a permanent passthrough rule with the arguments args for the ipv value. + Remove a passthrough rule with the arguments args for the ipv value. @@ -979,7 +979,7 @@ { ipv4 | ipv6 | eb } args - Return whether a permanent passthrough rule with the arguments args exists for the ipv value. Returns 0 if true, 1 otherwise. + Return whether a passthrough rule with the arguments args exists for the ipv value. Returns 0 if true, 1 otherwise. diff -up firewalld-0.3.9/src/firewall/client.py.RHBZ#993650_add firewalld-0.3.9/src/firewall/client.py --- firewalld-0.3.9/src/firewall/client.py.RHBZ#993650_add 2014-10-20 22:03:54.447869842 +0200 +++ firewalld-0.3.9/src/firewall/client.py 2014-10-20 22:03:54.461869762 +0200 @@ -1314,7 +1314,7 @@ class FirewallClientDirect(object): self.settings[2] = passthroughs @handle_exceptions def removeAllPassthroughs(self): - self.settings[2] = passthroughs + self.settings[2] = [] @handle_exceptions def getPassthroughs(self, ipv): return [ entry[1] for entry in self.settings[2] \ diff -up firewalld-0.3.9/src/firewall/core/fw_direct.py.RHBZ#993650_add firewalld-0.3.9/src/firewall/core/fw_direct.py --- firewalld-0.3.9/src/firewall/core/fw_direct.py.RHBZ#993650_add 2014-10-20 22:03:54.392870157 +0200 +++ firewalld-0.3.9/src/firewall/core/fw_direct.py 2014-10-20 22:04:44.901595326 +0200 @@ -280,7 +280,7 @@ class FirewallDirect: r.append((ipv, table, chain, priority, list(args))) return r - # DIRECT PASSTROUGH (untracked) + # DIRECT PASSTHROUGH (untracked) def passthrough(self, ipv, args): try: @@ -289,7 +289,7 @@ class FirewallDirect: log.debug2(msg) raise FirewallError(COMMAND_FAILED, msg) - # DIRECT PASSTROUGH (tracked) + # DIRECT PASSTHROUGH (tracked) def _check_ipv(self, ipv): ipvs = [ 'ipv4', 'ipv6', 'eb' ] @@ -311,8 +311,14 @@ class FirewallDirect: raise FirewallError(NOT_ENABLED, "passthrough '%s', '%s'" % (ipv, args)) + if enable: + self.check_passthrough(args) + _args = args + else: + _args = self.reverse_passthrough(args) + try: - self._fw.rule(ipv, args) + self._fw.rule(ipv, _args) except Exception as msg: log.debug2(msg) raise FirewallError(COMMAND_FAILED, msg) @@ -349,3 +355,74 @@ class FirewallDirect: for args in self._passthroughs[ipv]: r.append(list(args)) return r + + def check_passthrough(self, args): + """ Check if passthough rule is valid (only add, insert and new chain + rules are allowed) """ + + args = set(args) + not_allowed = set(["-C", "--check", # check rule + "-D", "--delete", # delete rule + "-R", "--replace", # replace rule + "-L", "--list", # list rule + "-S", "--list-rules", # print rules + "-F", "--flush", # flush rules + "-Z", "--zero", # zero rules + "-X", "--delete-chain", # delete chain + "-P", "--policy", # policy + "-E", "--rename-chain"]) # rename chain) + # intersection of args and not_allowed is not empty, i.e. + # something from args is not allowed + if len(args & not_allowed) > 0: + raise FirewallError(INVALID_PASSTHROUGH, + "arg '%s' is not allowed" % + list(args & not_allowed)[0] ) + + # args need to contain one of -A, -I, -N + needed = set(["-A", "--append", + "-I", "--insert", + "-N", "--new-chain"]) + # empty intersection of args and needed, i.e. + # none from args contains any needed command + if len(args & needed) == 0: + raise FirewallError(INVALID_PASSTHROUGH, + "no '-A', '-I' or '-N' arg") + + def reverse_passthrough(self, args): + """ Reverse valid passthough rule """ + + replace_args = { + # Append + "-A": "-D", + "--append": "--delete", + # Insert + "-I": "-D", + "--insert": "--delete", + # New chain + "-N": "-X", + "--new-chain": "--delete-chain", + } + + ret_args = args[:] + + for x in replace_args: + try: + idx = ret_args.index(x) + except: + continue + + if x in [ "-I", "--insert" ]: + # With insert rulenum, then remove it if it is a number + # Opt at position idx, chain at position idx+1, [rulenum] at + # position idx+2 + try: + int(ret_args[idx+2]) + except: + pass + else: + ret_args.pop(idx+2) + + ret_args[idx] = replace_args[x] + return ret_args + + raise FirewallError(INVALID_PASSTHROUGH, "no '-A', '-I' or '-N' arg") diff -up firewalld-0.3.9/src/firewall/errors.py.RHBZ#993650_add firewalld-0.3.9/src/firewall/errors.py --- firewalld-0.3.9/src/firewall/errors.py.RHBZ#993650_add 2014-10-20 22:03:54.448869836 +0200 +++ firewalld-0.3.9/src/firewall/errors.py 2014-10-20 22:03:54.461869762 +0200 @@ -74,6 +74,7 @@ INVALID_COMMAND = 129 INVALID_USER = 130 INVALID_UID = 131 INVALID_MODULE = 132 +INVALID_PASSTHROUGH = 133 MISSING_TABLE = 200 MISSING_CHAIN = 201 diff -up firewalld-0.3.9/src/firewall/server/config.py.RHBZ#993650_add firewalld-0.3.9/src/firewall/server/config.py --- firewalld-0.3.9/src/firewall/server/config.py.RHBZ#993650_add 2014-10-20 22:03:54.449869830 +0200 +++ firewalld-0.3.9/src/firewall/server/config.py 2014-10-20 22:03:54.461869762 +0200 @@ -897,6 +897,19 @@ class FirewallDConfig(slip.dbus.service. idx = (ipv, table, chain, priority, args) return idx in self.getSettings()[1] + @dbus_service_method(DBUS_INTERFACE_CONFIG_DIRECT, in_signature='sss') + @dbus_handle_exceptions + def removeRules(self, ipv, table, chain, sender=None): + ipv = dbus_to_python(ipv) + table = dbus_to_python(table) + chain = dbus_to_python(chain) + log.debug1("config.direct.removeRules('%s', '%s', '%s')" % + (ipv, table, chain, )) + self.accessCheck(sender) + settings = list(self.getSettings()) + settings[1] = [] + self.update(tuple(settings)) + @dbus_service_method(DBUS_INTERFACE_CONFIG_DIRECT, in_signature='sss', out_signature='a(ias)') @dbus_handle_exceptions