Repository :
http://git.fedorahosted.org/cgit/firewalld-recode.git
On branch : master
---------------------------------------------------------------
commit 99fa453cccd526c24fb7092da104eb86e49abd6b
Author: Daniel Kopecek <dkopecek(a)redhat.com>
Date: Mon Oct 20 14:07:34 2014 +0200
Use a transaction based backend abstraction
- use a simple transaction protocol for interacting with
the system firewall via a firewall backend implementation
(initial implementation)
- got rid of useless methods in XTables derived classes
- require implementation of getTableRef, listTables and the
execute methods in XTables derived classes
- Adapt EB/IPTables code
---------------------------------------------------------------
CMakeLists.txt | 3 +-
src/Daemon/Backends/Linux/EBTables.cpp | 66 +--------
src/Daemon/Backends/Linux/EBTables.hpp | 16 +--
src/Daemon/Backends/Linux/IPTables.cpp | 138 +++++-------------
src/Daemon/Backends/Linux/IPTables.hpp | 31 +---
src/Daemon/Backends/Linux/XTables.hpp | 54 +++++--
src/Daemon/Backends/LinuxXTables.cpp | 255 ++++++++++++++++++++++++++++++++
src/Daemon/Backends/LinuxXTables.hpp | 38 +++++
src/Daemon/Firewall/Backend.cpp | 12 ++-
src/Daemon/Firewall/Backend.hpp | 10 +-
src/Daemon/Firewall/BackendOpTable.hpp | 30 ++++
src/Daemon/Firewall/Firewall.cpp | 25 +--
src/Daemon/Firewall/Firewall.hpp | 9 +-
src/Daemon/Firewall/Transaction.cpp | 4 +-
src/Daemon/Firewall/Transaction.hpp | 6 +-
tests/iptables/test_iptables.cpp | 4 +-
16 files changed, 448 insertions(+), 253 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 90c5357..9233894 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,7 @@ file(GLOB daemon_dbus_methods_SOURCES
file(GLOB daemon_SOURCES
"src/Daemon/*.cpp"
"src/Daemon/*.hpp"
+ "src/Daemon/Backends/*.[ch]pp"
"src/Daemon/Backends/Linux/*.cpp"
"src/Daemon/Backends/Linux/*.hpp"
"src/Daemon/Firewall/*.cpp"
@@ -49,7 +50,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src/)
add_executable(glib-vgsupp-helper glib-vgsupp-helper.cpp)
target_link_libraries(glib-vgsupp-helper ${GLIBMM_LIBRARIES} ${GIOMM_LIBRARIES})
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNITTEST")
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNITTEST")
# Compile test: sysctl
add_executable(test_sysctl
diff --git a/src/Daemon/Backends/Linux/EBTables.cpp
b/src/Daemon/Backends/Linux/EBTables.cpp
index f25b960..c7b80fa 100644
--- a/src/Daemon/Backends/Linux/EBTables.cpp
+++ b/src/Daemon/Backends/Linux/EBTables.cpp
@@ -33,10 +33,10 @@ namespace firewalld
setChainPolicy("filter", "OUTPUT", "ACCEPT");
}
- int EBTables::listTables(StringVector &tables) const
+ const StringVector EBTables::listTables() const
{
- tables = { "filter", "nat", "broute" };
- return 0;
+ const StringVector tables({ "filter", "nat", "broute"
});
+ return tables;
}
XTable& EBTables::getTableRef(const String& table)
@@ -47,66 +47,6 @@ namespace firewalld
throw std::runtime_error("Unknown EBtables table name");
}
- int EBTables::appendRule(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::appendRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int EBTables::deleteRule(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::deleteRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- bool EBTables::ruleExists(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::ruleExists(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int EBTables::insertRule(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::insertRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int EBTables::listRules(const String& table, const String& chain,
StringVectorMap<int>& rule_specs)
- {
- return XTables::listRules(getTableRef(table), chain, rule_specs);
- }
-
- int EBTables::newChain(const String& table, const String& chain, bool
user_defined)
- {
- return XTables::newChain(getTableRef(table), chain, user_defined);
- }
-
- int EBTables::setChainPolicy(const String& table, const String& chain, const
String& policy)
- {
- return XTables::setChainPolicy(getTableRef(table), chain, policy);
- }
-
- int EBTables::renameChain(const String& table, const String& old_chain_name,
const String& new_chain_name)
- {
- return XTables::renameChain(getTableRef(table), old_chain_name, new_chain_name);
- }
-
- int EBTables::deleteChain(const String& table, const String& chain)
- {
- return XTables::deleteChain(getTableRef(table), chain);
- }
-
- int EBTables::listChains(const String& table, StringVector& chains)
- {
- return XTables::listChains(getTableRef(table), chains);
- }
-
- bool EBTables::chainExists(const String& table, const String& chain)
- {
- return XTables::chainExists(getTableRef(table), chain);
- }
-
- int EBTables::passthrough(const String& table, const String&
direct_specification)
- {
- return XTables::direct(getTableRef(table), direct_specification);
- }
-
int EBTables::execute(const XTables::Operation &op)
{
StringVector args;
diff --git a/src/Daemon/Backends/Linux/EBTables.hpp
b/src/Daemon/Backends/Linux/EBTables.hpp
index c1dd93e..1398ab4 100644
--- a/src/Daemon/Backends/Linux/EBTables.hpp
+++ b/src/Daemon/Backends/Linux/EBTables.hpp
@@ -34,21 +34,7 @@ namespace firewalld
public:
EBTables();
- int listTables(StringVector& tables) const;
-
- int appendRule(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- int deleteRule(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- bool ruleExists(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- int insertRule(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- int listRules(const String& table, const String& chain,
StringVectorMap<int>& rule_specs);
-
- int newChain(const String& table, const String& chain, bool user_defined =
true);
- int setChainPolicy(const String& table, const String& chain, const
String& policy);
- int renameChain(const String& table, const String& old_chain_name, const
String& new_chain_name);
- int deleteChain(const String& table, const String& chain);
- int listChains(const String& table, StringVector& chains);
- bool chainExists(const String& table, const String& chain);
- int passthrough(const String& table, const String& direct_specification);
+ const StringVector listTables() const;
protected:
XTable& getTableRef(const String& table);
diff --git a/src/Daemon/Backends/Linux/IPTables.cpp
b/src/Daemon/Backends/Linux/IPTables.cpp
index 84fa330..f6d36ee 100644
--- a/src/Daemon/Backends/Linux/IPTables.cpp
+++ b/src/Daemon/Backends/Linux/IPTables.cpp
@@ -27,122 +27,52 @@ namespace firewalld
: _filter("filter"),
_nat("nat"),
_mangle("mangle"),
+ _security("security"),
+ _raw("raw"),
_ipXtables_path(ipXtables_path)
{
- XTables::newChain(_filter, "INPUT", false, true);
- XTables::setChainPolicy(_filter, "INPUT", "ACCEPT");
- XTables::newChain(_filter, "FORWARD", false, true);
- XTables::setChainPolicy(_filter, "FORWARD", "ACCEPT");
- XTables::newChain(_filter, "OUTPUT", false, true);
- XTables::setChainPolicy(_filter, "OUTPUT", "ACCEPT");
-
- XTables::newChain(_nat, "PREROUTING", false, true);
- XTables::setChainPolicy(_nat, "PREROUTING", "ACCEPT");
- XTables::newChain(_nat, "INPUT", false, true);
- XTables::setChainPolicy(_nat, "INPUT", "ACCEPT");
- XTables::newChain(_nat, "OUTPUT", false, true);
- XTables::setChainPolicy(_nat, "OUTPUT", "ACCEPT");
- XTables::newChain(_nat, "POSTROUTING", false, true);
- XTables::setChainPolicy(_nat, "POSTROUTING", "ACCEPT");
-
- XTables::newChain(_mangle, "PREROUTING", false, true);
- XTables::setChainPolicy(_mangle, "PREROUTING", "ACCEPT");
- XTables::newChain(_mangle, "INPUT", false, true);
- XTables::setChainPolicy(_mangle, "INPUT", "ACCEPT");
- XTables::newChain(_mangle, "FORWARD", false, true);
- XTables::setChainPolicy(_mangle, "FORWARD", "ACCEPT");
- XTables::newChain(_mangle, "OUTPUT", false, true);
- XTables::setChainPolicy(_mangle, "OUTPUT", "ACCEPT");
- XTables::newChain(_mangle, "POSTROUTING", false, true);
- XTables::setChainPolicy(_mangle, "POSTROUTING", "ACCEPT");
- }
-
- XTable& IPTables::getTableRef(Table table)
- {
- switch(table) {
- case Table::Filter: return _filter;
- case Table::NAT: return _nat;
- case Table::Mangle: return _mangle;
- }
+ newChain("filter", "INPUT", false, true);
+ setChainPolicy("filter", "INPUT", "ACCEPT");
+ newChain("filter", "FORWARD", false, true);
+ setChainPolicy("filter", "FORWARD", "ACCEPT");
+ newChain("filter", "OUTPUT", false, true);
+ setChainPolicy("filter", "OUTPUT", "ACCEPT");
+
+ newChain("nat", "PREROUTING", false, true);
+ setChainPolicy("nat", "PREROUTING", "ACCEPT");
+ newChain("nat", "INPUT", false, true);
+ setChainPolicy("nat", "INPUT", "ACCEPT");
+ newChain("nat", "OUTPUT", false, true);
+ setChainPolicy("nat", "OUTPUT", "ACCEPT");
+ newChain("nat", "POSTROUTING", false, true);
+ setChainPolicy("nat", "POSTROUTING", "ACCEPT");
+
+ newChain("mangle", "PREROUTING", false, true);
+ setChainPolicy("mangle", "PREROUTING", "ACCEPT");
+ newChain("mangle", "INPUT", false, true);
+ setChainPolicy("mangle", "INPUT", "ACCEPT");
+ newChain("mangle", "FORWARD", false, true);
+ setChainPolicy("mangle", "FORWARD", "ACCEPT");
+ newChain("mangle", "OUTPUT", false, true);
+ setChainPolicy("mangle", "OUTPUT", "ACCEPT");
+ newChain("mangle", "POSTROUTING", false, true);
+ setChainPolicy("mangle", "POSTROUTING", "ACCEPT");
}
XTable& IPTables::getTableRef(const String& table)
{
+ if (table == "security") return _security;
+ if (table == "raw") return _raw;
if (table == "filter") return _filter;
if (table == "nat") return _nat;
if (table == "mangle") return _mangle;
throw std::runtime_error("Unknown IPTables table name");
}
- int IPTables::listTables(StringVector &tables) const
- {
- tables = { "filter", "nat", "mangle" };
- return 0;
- }
-
- int IPTables::appendRule(Table table, const String& chain, const String&
rule_spec, int rule_priority)
- {
- return XTables::appendRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int IPTables::appendRule(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::appendRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int IPTables::deleteRule(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::deleteRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- bool IPTables::ruleExists(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::ruleExists(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int IPTables::insertRule(const String& table, const String& chain, const
String& rule_spec, int rule_priority)
- {
- return XTables::insertRule(getTableRef(table), chain, rule_spec, rule_priority);
- }
-
- int IPTables::listRules(const String& table, const String& chain,
StringVectorMap<int>& rule_specs)
- {
- return XTables::listRules(getTableRef(table), chain, rule_specs);
- }
-
- int IPTables::newChain(const String& table, const String& chain, bool
user_defined)
- {
- return XTables::newChain(getTableRef(table), chain, user_defined);
- }
-
- int IPTables::setChainPolicy(const String& table, const String& chain, const
String& policy)
- {
- return XTables::setChainPolicy(getTableRef(table), chain, policy);
- }
-
- int IPTables::renameChain(const String& table, const String& old_chain_name,
const String& new_chain_name)
- {
- return XTables::renameChain(getTableRef(table), old_chain_name, new_chain_name);
- }
-
- int IPTables::deleteChain(const String& table, const String& chain)
- {
- return XTables::deleteChain(getTableRef(table), chain);
- }
-
- int IPTables::listChains(const String& table, StringVector& chains)
- {
- return XTables::listChains(getTableRef(table), chains);
- }
-
- bool IPTables::chainExists(const String& table, const String& chain)
- {
- return XTables::chainExists(getTableRef(table), chain);
- }
-
- int IPTables::passthrough(const String& table, const String&
direct_specification)
+ const StringVector IPTables::listTables() const
{
- return XTables::direct(getTableRef(table), direct_specification);
+ StringVector tables({"security", "raw", "nat",
"mangle", "filter"});
+ return tables;
}
int IPTables::execute(const XTables::Operation& op)
@@ -239,8 +169,8 @@ namespace firewalld
int IPTables::execute(const StringVector& args)
{
-#ifdef UNITTEST
LOG(DEBUG) << _ipXtables_path << " " << args;
+#ifdef UNITTEST
return 0;
#else
return runCommand(_ipXtables_path, args);
diff --git a/src/Daemon/Backends/Linux/IPTables.hpp
b/src/Daemon/Backends/Linux/IPTables.hpp
index 16263e6..81b0881 100644
--- a/src/Daemon/Backends/Linux/IPTables.hpp
+++ b/src/Daemon/Backends/Linux/IPTables.hpp
@@ -34,42 +34,23 @@ namespace firewalld
class IPTables : public XTables
{
public:
- enum class Table {
- Filter,
- NAT,
- Mangle
- };
-
IPTables(const char * const ipXtables_path);
- int listTables(StringVector& tables) const;
-
- int appendRule(Table table, const String& chain, const String& rule_spec, int
rule_priority);
- int appendRule(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- int deleteRule(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- bool ruleExists(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- int insertRule(const String& table, const String& chain, const String&
rule_spec, int rule_priority);
- int listRules(const String& table, const String& chain,
StringVectorMap<int>& rule_specs);
-
- int newChain(const String& table, const String& chain, bool user_defined =
true);
- int setChainPolicy(const String& table, const String& chain, const
String& policy);
- int renameChain(const String& table, const String& old_chain_name, const
String& new_chain_name);
- int deleteChain(const String& table, const String& chain);
- int listChains(const String& table, StringVector& chains);
- bool chainExists(const String& table, const String& chain);
- int passthrough(const String& table, const String& direct_specification);
+ const StringVector listTables() const;
protected:
- XTable& getTableRef(Table table);
XTable& getTableRef(const String& table);
int execute(const XTables::Operation& op);
int execute(const StringVector& args);
private:
const char * const _ipXtables_path;
- XTable _filter;
- XTable _nat;
+
+ XTable _security;
+ XTable _raw;
XTable _mangle;
+ XTable _nat;
+ XTable _filter;
};
class IP4Tables : public IPTables
diff --git a/src/Daemon/Backends/Linux/XTables.hpp
b/src/Daemon/Backends/Linux/XTables.hpp
index 62ff2f1..6994300 100644
--- a/src/Daemon/Backends/Linux/XTables.hpp
+++ b/src/Daemon/Backends/Linux/XTables.hpp
@@ -38,14 +38,16 @@ namespace firewalld
void deleteRule(const String& chain, const String& rule_spec, int
rule_priority);
bool ruleExists(const String& name, const String& rule_spec, int
rule_priority);
void insertRule(const String& chain, const String& rule_spec, int
rule_priority);
- //void replaceRule(const String& chain, int old_rule_num, const String&
rule_spec);
void listRules(const String& chain, StringVectorMap<int>& rules);
+
void newChain(const String& chain, bool user_defined = true);
void setChainPolicy(const String& chain, const String& policy);
void renameChain(const String& old_chain_name, const String&
new_chain_name);
+ void flushChain(const String& name);
void deleteChain(const String& name);
void listChains(StringVector& chains);
bool chainExists(const String& chain);
+
void addDirect(const String& direct_specification);
private:
@@ -139,10 +141,11 @@ namespace firewalld
Glib::Threads::Mutex::Lock _lock;
};
- virtual int listTables(StringVector& tables) const = 0;
+ virtual const StringVector listTables() const = 0;
- virtual int appendRule(XTable& table, const String& chain, const String&
rule_spec, int rule_priority)
+ int appendRule(const String& table_name, const String& chain, const
String& rule_spec, int rule_priority)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::Append, rule_spec, rule_priority);
int return_code = execute(op);
if (return_code == 0) {
@@ -151,14 +154,16 @@ namespace firewalld
return return_code;
}
- virtual int checkRule(XTable& table, const String& chain, const String&
rule_spec)
+ int checkRule(const String& table_name, const String& chain, const
String& rule_spec)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::Check, rule_spec);
return execute(op);
}
- virtual int deleteRule(XTable& table, const String& chain, const String&
rule_spec, int rule_priority)
+ int deleteRule(const String& table_name, const String& chain, const
String& rule_spec, int rule_priority)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::Delete, rule_spec, rule_priority);
int return_code = execute(op);
if (return_code == 0) {
@@ -167,14 +172,16 @@ namespace firewalld
return return_code;
}
- virtual bool ruleExists(XTable& table, const String& chain, const String&
rule_spec, int rule_priority)
+ bool ruleExists(const String& table_name, const String& chain, const
String& rule_spec, int rule_priority)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::ListRules, rule_spec, rule_priority);
return table.ruleExists(chain, rule_spec, rule_priority);
}
- virtual int insertRule(XTable& table, const String& chain, const String&
rule_spec, int rule_priority)
+ int insertRule(const String& table_name, const String& chain, const
String& rule_spec, int rule_priority)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::Insert, rule_spec, rule_priority);
int return_code = execute(op);
if (return_code == 0) {
@@ -183,15 +190,17 @@ namespace firewalld
return return_code;
}
- virtual int listRules(XTable& table, const String& chain,
StringVectorMap<int>& rule_specs)
+ int listRules(const String& table_name, const String& chain,
StringVectorMap<int>& rule_specs)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::ListRules);
table.listRules(chain, rule_specs);
return 0;
}
- virtual int newChain(XTable& table, const String& chain, bool user_defined =
true, bool builtin = false)
+ int newChain(const String& table_name, const String& chain, bool user_defined
= true, bool builtin = false)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::New);
int return_code;
if (!builtin) {
@@ -206,8 +215,9 @@ namespace firewalld
return return_code;
}
- virtual int setChainPolicy(XTable& table, const String& chain, const
String& policy)
+ int setChainPolicy(const String& table_name, const String& chain, const
String& policy)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::SetPolicy, policy);
int return_code = execute(op);
if (return_code == 0) {
@@ -216,8 +226,9 @@ namespace firewalld
return return_code;
}
- virtual int renameChain(XTable& table, const String& old_chain_name, const
String& new_chain_name)
+ int renameChain(const String& table_name, const String& old_chain_name, const
String& new_chain_name)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, old_chain_name, Command::Rename, new_chain_name);
int return_code = execute(op);
if (return_code == 0) {
@@ -226,8 +237,9 @@ namespace firewalld
return return_code;
}
- virtual int deleteChain(XTable& table, const String& chain)
+ int deleteChain(const String& table_name, const String& chain)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, chain, Command::Delete);
int return_code = execute(op);
if (return_code == 0) {
@@ -236,21 +248,32 @@ namespace firewalld
return return_code;
}
- virtual int listChains(XTable& table, StringVector& chains)
+ int listChains(const String& table_name, StringVector& chains)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, Command::ListChains);
table.listChains(chains);
return 0;
}
- virtual int chainExists(XTable& table, const String& chain)
+ StringVector listChains(const String& table_name)
+ {
+ XTable& table = getTableRef(table_name);
+ StringVector chains;
+ table.listChains(chains);
+ return std::move(chains);
+ }
+
+ int chainExists(const String& table_name, const String& chain)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, Command::ListChains);
return table.chainExists(chain);
}
- virtual int direct(XTable& table, const String& args)
+ int direct(const String& table_name, const String& args)
{
+ XTable& table = getTableRef(table_name);
Operation op(table, Command::Direct, args);
int return_code = execute(op);
if (return_code == 0) {
@@ -262,6 +285,7 @@ namespace firewalld
protected:
virtual int execute(const Operation& op) = 0;
virtual int execute(const StringVector& args) = 0;
+ virtual XTable& getTableRef(const String& table) = 0;
};
} /* namespace firewalld */
diff --git a/src/Daemon/Backends/LinuxXTables.cpp b/src/Daemon/Backends/LinuxXTables.cpp
new file mode 100644
index 0000000..782172f
--- /dev/null
+++ b/src/Daemon/Backends/LinuxXTables.cpp
@@ -0,0 +1,255 @@
+#include "LinuxXTables.hpp"
+#include "Common/Types.hpp"
+#include "Common/Logging.hpp"
+
+namespace firewalld
+{
+ LinuxXTables::LinuxXTables()
+ : Backend("LinuxXTables"),
+ _ip4tables(FIREWALLD_IP4TABLES_PATH),
+ _ip6tables(FIREWALLD_IP6TABLES_PATH)
+ {
+ initDefaultChains();
+
+ registerOperationHandler("ZONE", &LinuxXTables::opZone);
+ registerOperationHandler("ZONE_INTERFACE",
&LinuxXTables::opZoneInterface);
+ registerOperationHandler("ZONE_PORT", &LinuxXTables::opZonePort);
+ registerOperationHandler("ZONE_PORT_FORWARD",
&LinuxXTables::opZonePortForward);
+ registerOperationHandler("ZONE_ICMP_BLOCK",
&LinuxXTables::opZoneICMPBlock);
+ registerOperationHandler("ZONE_MASQUERADE",
&LinuxXTables::opZoneMasquerade);
+ registerOperationHandler("LOAD_HELPER", &LinuxXTables::opLoadHelper);
+ }
+
+ void LinuxXTables::initDefaultChains()
+ {
+ for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) {
+ String icmp, reject;
+
+ if (ipXtables == &_ip4tables) {
+ icmp = "icmp";
+ reject = "REJECT --reject-with icmp-host-prohibited";
+ } else {
+ icmp = "ipv6-icmp";
+ reject = "REJECT --reject-with icmp6-adm-prohibited";
+ }
+
+ //
+ // Initialize _direct chains
+ //
+ // <CHAIN>_direct chains are used for rules added via the
+ // direct interface. If a built-in chain named `CHAIN` is
+ // used, it is replaced with `CHAIN_direct` before executing
+ // the requested {ip,ip6,eb}tables command.
+ //
+ for (const String& table : ipXtables->listTables()) {
+ for (const String& chain : ipXtables->listChains(table)) {
+ ipXtables->newChain(table, chain + "_direct");
+ ipXtables->appendRule(table, chain, "-j " + chain + "_direct",
0);
+ }
+ }
+
+ //
+ // Initialize -t filter chains
+ //
+ ipXtables->newChain("filter", "INPUT_ZONES");
+ ipXtables->newChain("filter", "INPUT_ZONES_SOURCE");
+
+ ipXtables->insertRule("filter", "INPUT", "-m conntrack
--ctstate RELATED,ESTABLISHED -j ACCEPT", 1);
+ ipXtables->insertRule("filter", "INPUT", "-i lo -j
ACCEPT", 3);
+ ipXtables->insertRule("filter", "INPUT", "-j
INPUT_ZONES_SOURCE", 4);
+ ipXtables->insertRule("filter", "INPUT", "-j
INPUT_ZONES", 5);
+ ipXtables->insertRule("filter", "INPUT", "-p " +
icmp + " -j ACCEPT", 6);
+ ipXtables->insertRule("filter", "INPUT", "-j " +
reject, 7);
+
+ ipXtables->newChain("filter", "FORWARD_IN_ZONES");
+ ipXtables->newChain("filter", "FORWARD_IN_ZONES_SOURCE");
+ ipXtables->newChain("filter", "FORWARD_OUT_ZONES");
+ ipXtables->newChain("filter", "FORWARD_OUT_ZONES_SOURCE");
+
+ ipXtables->insertRule("filter", "FORWARD", "-m
conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", 1);
+ ipXtables->insertRule("filter", "FORWARD", "-i lo -j
ACCEPT", 3);
+ ipXtables->insertRule("filter", "FORWARD", "-j
FORWARD_IN_ZONES_SOURCE", 4);
+ ipXtables->insertRule("filter", "FORWARD", "-j
FORWARD_IN_ZONES", 5);
+ ipXtables->insertRule("filter", "FORWARD", "-j
FORWARD_OUT_ZONES_SOURCE", 6);
+ ipXtables->insertRule("filter", "FORWARD", "-j
FORWARD_OUT_ZONES", 7);
+ ipXtables->insertRule("filter", "FORWARD", "-p " +
icmp + " -j ACCEPT", 8);
+ ipXtables->insertRule("filter", "FORWARD", "-j " +
reject, 9);
+
+ //
+ // Initialize -t mangle chains
+ //
+ ipXtables->newChain("mangle", "PREROUTING_ZONES");
+ ipXtables->newChain("mangle", "PREROUTING_ZONES_SOURCE");
+
+ ipXtables->insertRule("mangle", "PREROUTING", "-j
PREROUTING_ZONES_SOURCE", 1);
+ ipXtables->insertRule("mangle", "PREROUTING", "-j
PREROUTING_ZONES", 2);
+
+ //
+ // Initialize -t nat chains
+ //
+
+ }
+ }
+
+ void LinuxXTables::cleanup()
+ {
+ }
+
+ void LinuxXTables::processOperation(const UStringVector& op, bool undo)
+ {
+ if (op.size() < 1) {
+ /* NOOP */
+ return;
+ }
+
+ auto op_handler = operationHandler(op.front());
+
+ if (op_handler) {
+ VLOG(4) << "OP: " << (undo ? "-" : "+")
<< op;
+ (*this.*op_handler)(op, undo);
+ }
+
+ return;
+ }
+
+ void LinuxXTables::opZone(const UStringVector& op, bool undo)
+ {
+ String zone_name = op[1];
+
+ // XXX: Do we trust the input values?
+
+ for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) {
+ for (const String& prefix : { "IN_", "FWDI_",
"FWDO_" }) {
+ for (const String& suffix : { "", "_allow", "_deny",
"_log" }) {
+ if (!undo) {
+ ipXtables->newChain("filter", prefix + zone_name + suffix);
+ } else {
+ ipXtables->deleteChain("filter", prefix + zone_name + suffix);
+ }
+ }
+ }
+
+ if (!undo) {
+ for (const String& prefix : { "IN_", "FWDI_", "FWDO_"
}) {
+ for (const String& suffix : { "_log", "_deny",
"_allow" }) {
+ ipXtables->appendRule("filter", prefix + zone_name, "-j " +
prefix + zone_name + suffix, 0);
+ }
+ }
+ }
+
+ for (const String& prefix : { "PRE_" }) {
+ for (const String& suffix : { "", "_allow", "_deny",
"_log" }) {
+ if (!undo) {
+ ipXtables->newChain("mangle", prefix + zone_name + suffix);
+ } else {
+ ipXtables->deleteChain("mangle", prefix + zone_name + suffix);
+ }
+ }
+ }
+
+ if (!undo) {
+ for (const String& prefix : { "PRE_" }) {
+ for (const String& suffix : { "_log", "_deny",
"_allow" }) {
+ ipXtables->appendRule("mangle", prefix + zone_name, "-j " +
prefix + zone_name + suffix, 0);
+ }
+ }
+ }
+ }
+
+ return;
+ }
+
+ void LinuxXTables::opZoneInterface(const UStringVector& op, bool undo)
+ {
+ String zone_name = op[1];
+ String interface = op[2];
+
+ for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) {
+ if (!undo) {
+ ipXtables->appendRule("filter", "INPUT_ZONES", "-i " +
interface + " -g IN_" + zone_name, 0);
+ ipXtables->appendRule("filter", "FORWARD_IN_ZONES", "-i
" + interface + " -g FWDI_" + zone_name, 0);
+ ipXtables->appendRule("filter", "FORWARD_OUT_ZONES", "-o
" + interface + " -g FWDO_" + zone_name, 0);
+ } else {
+ ipXtables->deleteRule("filter", "INPUT_ZONES", "-i " +
interface + " -g IN_" + zone_name, 0);
+ ipXtables->deleteRule("filter", "FORWARD_IN_ZONES", "-i
" + interface + " -g FWDI_" + zone_name, 0);
+ ipXtables->deleteRule("filter", "FORWARD_OUT_ZONES", "-o
" + interface + " -g FWDO_" + zone_name, 0);
+ }
+ }
+
+ return;
+ }
+
+ void LinuxXTables::opZonePort(const UStringVector& op, bool undo)
+ {
+ String zone_name = op[1];
+ String protocol = op[2];
+ String port_from = op[3];
+ String port_to;
+
+ if (op.size() == 5) {
+ port_to = op[4];
+ } else {
+ port_to = op[3];
+ }
+
+ String rule_spec;
+
+ if (protocol == "tcp") {
+ rule_spec = "-p tcp -m tcp --dport ";
+ }
+ else if (protocol == "udp") {
+ rule_spec = "-p udp -m udp --dport ";
+ }
+
+ rule_spec += port_from + (port_from != port_to ? ":" + port_to :
"");
+ rule_spec += " -m conntrack --ctstate NEW -j ACCEPT";
+
+ for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) {
+ if (!undo) {
+ ipXtables->appendRule("filter", "IN_" + zone_name +
"_allow", rule_spec, 0);
+ } else {
+ ipXtables->deleteRule("filter", "IN_" + zone_name +
"_allow", rule_spec, 0);
+ }
+ }
+
+ return;
+ }
+
+ void LinuxXTables::opZonePortForward(const UStringVector& op, bool undo)
+ {
+ }
+
+ void LinuxXTables::opZoneICMPBlock(const UStringVector& op, bool undo)
+ {
+ String zone_name = op[1];
+ String icmptype = op[2];
+ String protocol = op[3];
+ String rule_spec;
+ IPTables * ipXtables;
+
+ if (protocol == "ipv4") {
+ rule_spec = "-p icmp -m icmp --icmp-type " + icmptype;
+ rule_spec += " -j REJECT --reject-with icmp-host-prohibited";
+ ipXtables = &_ip4tables;
+ }
+ else if (protocol == "ipv6") {
+ rule_spec = "-p ipv6-icmp -m icmp6 --icmpv6-type " + icmptype;
+ rule_spec += " -j REJECT --reject-with icmp6-adm-prohibited";
+ ipXtables = &_ip6tables;
+ }
+
+ ipXtables->appendRule("filter", "IN_" + zone_name +
"_deny", rule_spec, 0);
+ ipXtables->appendRule("filter", "FWDI_" + zone_name +
"_deny", rule_spec, 0);
+
+ return;
+ }
+
+ void LinuxXTables::opZoneMasquerade(const UStringVector& op, bool undo)
+ {
+ }
+
+ void LinuxXTables::opLoadHelper(const UStringVector& op, bool undo)
+ {
+ }
+
+} /* namespace firewalld */
diff --git a/src/Daemon/Backends/LinuxXTables.hpp b/src/Daemon/Backends/LinuxXTables.hpp
new file mode 100644
index 0000000..4abc9ab
--- /dev/null
+++ b/src/Daemon/Backends/LinuxXTables.hpp
@@ -0,0 +1,38 @@
+#ifndef FIREWALLD_BACKENDS_LINUXXTABLES_HPP
+#define FIREWALLD_BACKENDS_LINUXXTABLES_HPP
+
+#include "Daemon/Backends/Linux/IPTables.hpp"
+#include "Daemon/Backends/Linux/EBTables.hpp"
+
+#include "Daemon/Firewall/Backend.hpp"
+#include "Daemon/Firewall/BackendOpTable.hpp"
+
+namespace firewalld
+{
+ class LinuxXTables : public Backend, private BackendOpTable<LinuxXTables>
+ {
+ public:
+ LinuxXTables();
+
+ protected:
+ void processOperation(const UStringVector& op, bool undo = false);
+
+ void initDefaultChains();
+ void cleanup();
+
+ void opZone(const UStringVector& op, bool undo);
+ void opZoneInterface(const UStringVector& op, bool undo);
+ void opZonePort(const UStringVector& op, bool undo);
+ void opZonePortForward(const UStringVector& op, bool undo);
+ void opZoneICMPBlock(const UStringVector& op, bool undo);
+ void opZoneMasquerade(const UStringVector& op, bool undo);
+ void opLoadHelper(const UStringVector& op, bool undo);
+
+ private:
+ IPTables _ip4tables;
+ IPTables _ip6tables;
+ EBTables _ebtables;
+ };
+} /* namespace firewalld */
+
+#endif /* FIREWALLD_BACKENDS_LINUXXTABLES_HPP */
diff --git a/src/Daemon/Firewall/Backend.cpp b/src/Daemon/Firewall/Backend.cpp
index cab311e..0ece111 100644
--- a/src/Daemon/Firewall/Backend.cpp
+++ b/src/Daemon/Firewall/Backend.cpp
@@ -25,11 +25,21 @@
namespace firewalld
{
- Backend::Backend()
+ Backend::Backend(const UString& identifier)
{
+ _identifier = identifier;
_transaction_counter = 0;
}
+ Backend::~Backend()
+ {
+ }
+
+ const UString& Backend::identifier() const
+ {
+ return _identifier;
+ }
+
Pointer<Transaction> Backend::createTransaction()
{
std::lock_guard<std::mutex> backend_lock(_backend_mutex);
diff --git a/src/Daemon/Firewall/Backend.hpp b/src/Daemon/Firewall/Backend.hpp
index 109520a..d227733 100644
--- a/src/Daemon/Firewall/Backend.hpp
+++ b/src/Daemon/Firewall/Backend.hpp
@@ -30,18 +30,22 @@ namespace firewalld
class Backend
{
public:
- Backend();
- virtual const UString& identifier() const = 0;
+ Backend(const UString& identifier);
+ virtual ~Backend();
+
+ const UString& identifier() const;
+
Pointer<Transaction> createTransaction();
void commitTransaction(Pointer<Transaction> transaction);
void removeTransaction(const String& identifier);
size_t countTransactions() const;
protected:
- virtual void processOperation(const UStringList& op, bool undo = false) = 0;
+ virtual void processOperation(const UStringVector& op, bool undo = false) = 0;
void removeTransactionUnlocked(const String& identifier);
private:
+ UString _identifier;
PointerVector<Transaction> _transactions;
mutable std::mutex _backend_mutex;
uint64_t _transaction_counter;
diff --git a/src/Daemon/Firewall/BackendOpTable.hpp
b/src/Daemon/Firewall/BackendOpTable.hpp
new file mode 100644
index 0000000..97bb6a8
--- /dev/null
+++ b/src/Daemon/Firewall/BackendOpTable.hpp
@@ -0,0 +1,30 @@
+#ifndef FIREWALLD_FIREWALL_BACKENDOPTABLE_HPP
+#define FIREWALLD_FIREWALL_BACKENDOPTABLE_HPP
+
+#include "Common/Types.hpp"
+
+namespace firewalld
+{
+ template<class C>
+ class BackendOpTable
+ {
+ public:
+ typedef void(C::*OpMethodPointer)(const UStringVector&, bool);
+
+ void registerOperationHandler(const UString& name, OpMethodPointer
method_pointer)
+ {
+ _op_method_table[name] = method_pointer;
+ }
+
+ OpMethodPointer operationHandler(const UString& name) const
+ {
+ return MapOp::findOne(_op_method_table, name);
+ }
+
+ private:
+ typedef std::map<UString, OpMethodPointer> OpMethodTable;
+ OpMethodTable _op_method_table;
+ };
+}
+
+#endif /* FIREWALLD_FIREWALL_BACKENDOPTABLE_HPP */
diff --git a/src/Daemon/Firewall/Firewall.cpp b/src/Daemon/Firewall/Firewall.cpp
index fa626c1..18a2c35 100644
--- a/src/Daemon/Firewall/Firewall.cpp
+++ b/src/Daemon/Firewall/Firewall.cpp
@@ -18,44 +18,37 @@
//
#include "Daemon/FirewallD.hpp"
#include "Daemon/Firewall/Firewall.hpp"
+#include "Daemon/Firewall/Backend.hpp"
+#include "Daemon/Backends/LinuxXTables.hpp"
#include "Common/Types.hpp"
namespace firewalld
{
-
Firewall::Firewall()
{
- // Insert the default zones
- addZoneName("block");
- addZoneName("home");
- addZoneName("public");
- addZoneName("work");
- addZoneName("trusted");
- addZoneName("drop");
- // Initialize the default zone name
- _default_zone = "public";
-
- addInterfaceToZone("public", "eth0");
+ _backend = new LinuxXTables();
}
bool Firewall::directIPv4getTables(StringVector& tables)
{
- return (_ip4tables.listTables(tables) == 0);
+ tables = _ip4tables.listTables();
+ return true;
}
bool Firewall::directIPv6getTables(StringVector& tables)
{
- return (_ip6tables.listTables(tables) == 0);
+ tables = _ip6tables.listTables();
+ return true;
}
bool Firewall::directIPv4Passthrough(const String& direct_specification)
{
- return (_ip4tables.passthrough("filter", direct_specification) == 0);
+ return (_ip4tables.direct("filter", direct_specification) == 0);
}
bool Firewall::directIPv6Passthrough(const String& direct_specification)
{
- return (_ip6tables.passthrough("filter", direct_specification) == 0);
+ return (_ip6tables.direct("filter", direct_specification) == 0);
}
bool Firewall::directIPv4AddChain(const String& table, const String& chain)
diff --git a/src/Daemon/Firewall/Firewall.hpp b/src/Daemon/Firewall/Firewall.hpp
index 3a4ab5d..7fa1115 100644
--- a/src/Daemon/Firewall/Firewall.hpp
+++ b/src/Daemon/Firewall/Firewall.hpp
@@ -20,11 +20,13 @@
#define _FIREWALL_H_
#include "Common/Types.hpp"
-#include "Daemon/Backends/Linux/IPTables.hpp"
-#include "Daemon/Backends/Linux/EBTables.hpp"
#include "Daemon/Firewall/Zone.hpp"
#include "Daemon/Firewall/Service.hpp"
#include "Daemon/Firewall/ICMPType.hpp"
+#include "Daemon/Firewall/Backend.hpp"
+
+#include "Daemon/Backends/Linux/IPTables.hpp"
+#include "Daemon/Backends/Linux/EBTables.hpp"
#include <glibmm.h>
#include <giomm.h>
@@ -33,7 +35,6 @@
namespace firewalld
{
-
class Firewall
{
public:
@@ -95,6 +96,8 @@ namespace firewalld
UString _default_zone;
PointerMap<UString,Zone> _zone_map;
+ Backend *_backend;
+
IP4Tables _ip4tables;
IP6Tables _ip6tables;
EBTables _ebtables;
diff --git a/src/Daemon/Firewall/Transaction.cpp b/src/Daemon/Firewall/Transaction.cpp
index b9f59f4..73be1d2 100644
--- a/src/Daemon/Firewall/Transaction.cpp
+++ b/src/Daemon/Firewall/Transaction.cpp
@@ -32,7 +32,7 @@ namespace firewalld
return _identifier;
}
- const UStringList& Transaction::operation(size_t index) const
+ const UStringVector& Transaction::operation(size_t index) const
{
return _operations.at(index);
}
@@ -42,7 +42,7 @@ namespace firewalld
return _operations.size();
}
- size_t Transaction::appendOperation(const UStringList& op)
+ size_t Transaction::appendOperation(const UStringVector& op)
{
_operations.push_back(op);
return (_operations.size() - 1);
diff --git a/src/Daemon/Firewall/Transaction.hpp b/src/Daemon/Firewall/Transaction.hpp
index 5b23a48..07b49fb 100644
--- a/src/Daemon/Firewall/Transaction.hpp
+++ b/src/Daemon/Firewall/Transaction.hpp
@@ -33,17 +33,17 @@ namespace firewalld
const String& identifier() const;
- const UStringList& operation(size_t index) const;
+ const UStringVector& operation(size_t index) const;
size_t countOperations() const;
- size_t appendOperation(const UStringList& op);
+ size_t appendOperation(const UStringVector& op);
void removeOperation(size_t index);
bool operator==(const Transaction& rhs) const;
private:
String _identifier;
- std::vector<UStringList> _operations;
+ std::vector<UStringVector> _operations;
};
class TransactionError : public std::runtime_error
diff --git a/tests/iptables/test_iptables.cpp b/tests/iptables/test_iptables.cpp
index e79ef12..99d6610 100644
--- a/tests/iptables/test_iptables.cpp
+++ b/tests/iptables/test_iptables.cpp
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
IP4Tables iptables;
IP6Tables ip6tables;
- iptables.appendRule(IP4Tables::Table::Filter, "INPUT", "-s 127.0.0.1 -j
DROP", 1);
+ iptables.appendRule("filter", "INPUT", "-s 127.0.0.1 -j
DROP", 1);
iptables.appendRule("filter", "INPUT", "-s 127.0.0.1 -j
DROP", 1);
iptables.deleteRule("filter", "INPUT", "-s 127.0.0.1 -j
DROP", 1);
iptables.insertRule("filter", "INPUT", "-s 127.0.0.2 -j
DROP", 1);
@@ -37,7 +37,7 @@ int main(int argc, char *argv[])
iptables.setChainPolicy("filter", "FOOchain", "RETURN");
iptables.renameChain("filter", "FOOchain", "BARchain");
iptables.deleteChain("filter", "BARchain");
- iptables.passthrough("filter", "-A OUTPUT -d 1.2.3.4 -j RETURN");
+ iptables.direct("filter", "-A OUTPUT -d 1.2.3.4 -j RETURN");
return 0;
}