1
0
mirror of https://github.com/fwbuilder/fwbuilder synced 2026-03-19 01:37:17 +01:00

fixes #614 Use FatalErrorInSingleRuleCompleMode in all compilers

This commit is contained in:
Vadim Kurland 2009-11-13 19:30:17 +00:00
parent 011ca8ca27
commit 301a4ed864
14 changed files with 1535 additions and 1411 deletions

View File

@ -1 +1 @@
#define BUILD_NUM 1747 #define BUILD_NUM 1748

View File

@ -135,217 +135,224 @@ string CompilerDriver_iosacl::run(const std::string &cluster_id,
objdb->findInIndex(objdb->getIntId(firewall_id))); objdb->findInIndex(objdb->getIntId(firewall_id)));
assert(fw); assert(fw);
// Copy rules from the cluster object try
populateClusterElements(cluster, fw);
commonChecks2(cluster, fw);
// Note that fwobjectname may be different from the name of the
// firewall fw This happens when we compile a member of a cluster
current_firewall_name = fw->getName().c_str();
QString ofname = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
FWOptions* options = fw->getOptionsObject();
string fwvers = fw->getStr("version");
if (fwvers == "") fw->setStr("version", "12.1");
if (fwvers == "12.x") fw->setStr("version", "12.1");
string platform = fw->getStr("platform");
string clearACLCmd = Resources::platform_res[platform]->getResourceStr(
string("/FWBuilderResources/Target/options/") +
"version_" + fwvers + "/iosacl_commands/clear_ip_acl");
if (clearACLCmd.empty())
{ {
// incorrect version. This could have happened if user converted // Copy rules from the cluster object
// firewall platform. See bug #2662290 populateClusterElements(cluster, fw);
fw->setStr("version", "12.1");
}
bool ios_acl_basic = options->getBool("ios_acl_basic"); commonChecks2(cluster, fw);
bool ios_acl_no_clear = options->getBool("ios_acl_no_clear");
bool ios_acl_substitution = options->getBool("ios_acl_substitution");
bool ios_add_clear_statements = options->getBool("ios_add_clear_statements");
if ( !ios_acl_basic && // Note that fwobjectname may be different from the name of the
!ios_acl_no_clear && // firewall fw This happens when we compile a member of a cluster
!ios_acl_substitution ) current_firewall_name = fw->getName().c_str();
{
if ( ios_add_clear_statements ) options->setBool("ios_acl_basic",true);
else options->setBool("ios_acl_no_clear",true);
}
std::auto_ptr<OSConfigurator_ios> oscnf(new OSConfigurator_ios(objdb, fw, false)); QString ofname = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
oscnf->prolog(); FWOptions* options = fw->getOptionsObject();
oscnf->processFirewallOptions();
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME); string fwvers = fw->getStr("version");
int policy_rules_count = 0; if (fwvers == "") fw->setStr("version", "12.1");
if (fwvers == "12.x") fw->setStr("version", "12.1");
vector<int> ipv4_6_runs; string platform = fw->getStr("platform");
string clearACLCmd = Resources::platform_res[platform]->getResourceStr(
if (!single_rule_compile_on) string("/FWBuilderResources/Target/options/") +
system_configuration_script = safetyNetInstall(fw); "version_" + fwvers + "/iosacl_commands/clear_ip_acl");
if (clearACLCmd.empty())
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
}
if (options->getStr("ipv4_6_order") == "ipv6_first")
{
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
for (vector<int>::iterator i=ipv4_6_runs.begin();
i!=ipv4_6_runs.end(); ++i)
{
int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
// Count rules for each address family
int policy_count = 0;
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p)
{ {
Policy *policy = Policy::cast(*p); // incorrect version. This could have happened if user converted
if (policy->matchingAddressFamily(policy_af)) policy_count++; // firewall platform. See bug #2662290
} fw->setStr("version", "12.1");
if (policy_count)
{
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb, fw, false));
prep->compile();
} }
for (list<FWObject*>::iterator p=all_policies.begin(); bool ios_acl_basic = options->getBool("ios_acl_basic");
p!=all_policies.end(); ++p ) bool ios_acl_no_clear = options->getBool("ios_acl_no_clear");
bool ios_acl_substitution = options->getBool("ios_acl_substitution");
bool ios_add_clear_statements = options->getBool("ios_add_clear_statements");
if ( !ios_acl_basic &&
!ios_acl_no_clear &&
!ios_acl_substitution )
{ {
Policy *policy = Policy::cast(*p); if ( ios_add_clear_statements ) options->setBool("ios_acl_basic",true);
else options->setBool("ios_acl_no_clear",true);
}
if (!policy->matchingAddressFamily(policy_af)) continue; std::auto_ptr<OSConfigurator_ios> oscnf(new OSConfigurator_ios(objdb, fw, false));
PolicyCompiler_iosacl c(objdb, fw, ipv6_policy, oscnf.get()); oscnf->prolog();
oscnf->processFirewallOptions();
c.setSourceRuleSet( policy ); list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
c.setRuleSetName(policy->getName()); int policy_rules_count = 0;
c.setSingleRuleCompileMode(single_rule_id); vector<int> ipv4_6_runs;
if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode();
c.setDebugLevel( dl );
if (rule_debug_on) c.setDebugRule( drp );
c.setVerbose( verbose );
if ( c.prolog() > 0 ) if (!single_rule_compile_on)
system_configuration_script = safetyNetInstall(fw);
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
}
if (options->getStr("ipv4_6_order") == "ipv6_first")
{
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
for (vector<int>::iterator i=ipv4_6_runs.begin();
i!=ipv4_6_runs.end(); ++i)
{
int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
// Count rules for each address family
int policy_count = 0;
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p)
{ {
c.compile(); Policy *policy = Policy::cast(*p);
c.epilog(); if (policy->matchingAddressFamily(policy_af)) policy_count++;
}
if (policy_count)
{
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb, fw, false));
prep->compile();
}
if (!single_rule_compile_on) for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p )
{
Policy *policy = Policy::cast(*p);
if (!policy->matchingAddressFamily(policy_af)) continue;
PolicyCompiler_iosacl c(objdb, fw, ipv6_policy, oscnf.get());
c.setSourceRuleSet( policy );
c.setRuleSetName(policy->getName());
c.setSingleRuleCompileMode(single_rule_id);
if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode();
c.setDebugLevel( dl );
if (rule_debug_on) c.setDebugRule( drp );
c.setVerbose( verbose );
if ( c.prolog() > 0 )
{ {
if (ipv6_policy) c.compile();
c.epilog();
if (!single_rule_compile_on)
{ {
policy_script += "\n\n"; if (ipv6_policy)
policy_script += "! ================ IPv6\n"; {
policy_script += "\n\n"; policy_script += "\n\n";
} else policy_script += "! ================ IPv6\n";
{ policy_script += "\n\n";
policy_script += "\n\n"; } else
policy_script += "! ================ IPv4\n"; {
policy_script += "\n\n"; policy_script += "\n\n";
policy_script += "! ================ IPv4\n";
policy_script += "\n\n";
}
} }
}
if (c.haveErrorsAndWarnings()) if (c.haveErrorsAndWarnings())
{ {
all_errors.push_back(c.getErrors("").c_str()); all_errors.push_back(c.getErrors("").c_str());
} }
policy_script += c.getCompiledScript(); policy_script += c.getCompiledScript();
} else } else
info(" Nothing to compile in Policy"); info(" Nothing to compile in Policy");
} }
if (!ipv6_policy) if (!ipv6_policy)
{
list<FWObject*> all_routing = fw->getByType(Routing::TYPENAME);
RuleSet *routing = RuleSet::cast(all_routing.front());
// currently routing is supported only for ipv4
RoutingCompiler_iosacl r(objdb, fw, false, oscnf.get());
r.setSourceRuleSet(routing);
r.setRuleSetName(routing->getName());
r.setSingleRuleCompileMode(single_rule_id);
if (inTestMode()) r.setTestMode();
if (inEmbeddedMode()) r.setEmbeddedMode();
r.setDebugLevel( dl );
if (rule_debug_on) r.setDebugRule( drp );
r.setVerbose( verbose );
if ( r.prolog() > 0 )
{ {
r.compile(); list<FWObject*> all_routing = fw->getByType(Routing::TYPENAME);
r.epilog(); RuleSet *routing = RuleSet::cast(all_routing.front());
if (r.haveErrorsAndWarnings()) // currently routing is supported only for ipv4
RoutingCompiler_iosacl r(objdb, fw, false, oscnf.get());
r.setSourceRuleSet(routing);
r.setRuleSetName(routing->getName());
r.setSingleRuleCompileMode(single_rule_id);
if (inTestMode()) r.setTestMode();
if (inEmbeddedMode()) r.setEmbeddedMode();
r.setDebugLevel( dl );
if (rule_debug_on) r.setDebugRule( drp );
r.setVerbose( verbose );
if ( r.prolog() > 0 )
{ {
all_errors.push_back(r.getErrors("").c_str()); r.compile();
} r.epilog();
routing_script += r.getCompiledScript(); if (r.haveErrorsAndWarnings())
} else {
info(" Nothing to compile in Routing"); all_errors.push_back(r.getErrors("").c_str());
}
routing_script += r.getCompiledScript();
} else
info(" Nothing to compile in Routing");
}
}
if (haveErrorsAndWarnings())
{
all_errors.push_front(getErrors("").c_str());
}
if (single_rule_compile_on)
{
return all_errors.join("\n").toStdString() +
policy_script + routing_script;
}
QString script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get());
info("Output file name: " + ofname.toStdString());
QFile fw_file(ofname);
if (fw_file.open(QIODevice::WriteOnly))
{
QTextStream fw_str(&fw_file);
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") +
fw_file_name.toStdString() +
" for writing");
} }
} }
catch (FatalErrorInSingleRuleCompileMode &ex)
if (haveErrorsAndWarnings())
{ {
all_errors.push_front(getErrors("").c_str()); return getErrors("");
}
if (single_rule_compile_on)
{
return all_errors.join("\n").toStdString() +
policy_script + routing_script;
}
QString script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get());
info("Output file name: " + ofname.toStdString());
QFile fw_file(ofname);
if (fw_file.open(QIODevice::WriteOnly))
{
QTextStream fw_str(&fw_file);
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") +
fw_file_name.toStdString() +
" for writing");
} }
return ""; return "";

View File

@ -557,41 +557,38 @@ string CompilerDriver_pix::run(const std::string &cluster_id,
script_buffer = assembleFwScript( script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get()); cluster, fw, !cluster_id.empty(), oscnf.get());
if (single_rule_compile_on)
{
return all_errors.join("\n").toStdString() +
policy_script + nat_script + routing_script;
}
info("Output file name: " + ofname.toStdString());
QFile fw_file(ofname);
if (fw_file.open(QIODevice::WriteOnly))
{
QTextStream fw_str(&fw_file);
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") +
fw_file_name.toStdString() +
" for writing");
}
} }
catch (FatalErrorInSingleRuleCompileMode &ex) catch (FatalErrorInSingleRuleCompileMode &ex)
{ {
if (haveErrorsAndWarnings()) return getErrors("");
{
all_errors.push_front(getErrors("").c_str());
}
}
if (single_rule_compile_on)
{
return all_errors.join("\n").toStdString() +
policy_script + nat_script + routing_script;
}
info("Output file name: " + ofname.toStdString());
QFile fw_file(ofname);
if (fw_file.open(QIODevice::WriteOnly))
{
QTextStream fw_str(&fw_file);
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") +
fw_file_name.toStdString() +
" for writing");
} }
return ""; return "";

View File

@ -266,16 +266,39 @@ void CompilerDriver::commonChecks(Firewall *fw)
if (ofname.empty()) continue; if (ofname.empty()) continue;
if (output_file_names.count(ofname) > 0) if (output_file_names.count(ofname) > 0)
{ {
string err = QString err("Member firewalls use the same output file name %1");
string("Member firewalls use the same output file name ") + error(cluster, NULL, NULL, err.arg(ofname.c_str()).toStdString());
ofname;
throw FWException(err);
} }
output_file_names.insert(ofname); output_file_names.insert(ofname);
} }
} }
} }
/*
* This method performs series of checks for the configuration
* consitency of clusters and cluster members as well as common
* problems with interfaces, addresses and their combinations. There
* are several possible levels of errors:
*
* - errors that can be worked around. Compiler makes minor changes
* to objects and continues. These are not warnings though, the user
* should fix these problems. Using Compiler::error() to report.
*
* - serious errors that should stop processing because generated file
* will be incorrect or inconsistent. However it is possible to
* continue in single rule compile mode because the error may not
* affect the rule being compiled. Using Compiler::abort() to
* report. Normally this method throws FWException() but in single
* rule compile mode or in testing mode it records the error and
* continues.
*
* - fatal errors that make it impossible to continue even in test or
* single rule compile modes. To report call Compiler::abort() and
* then throw FatalErrorInSingleRuleCompileMode exception. This
* exception should be caught in CompilerDriver::run() (virtual
* method) where recorded error can be shown to the user in the GUI.
*
*/
void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw) void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
{ {
QString current_firewall_name = fw->getName().c_str(); QString current_firewall_name = fw->getName().c_str();
@ -312,6 +335,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
"the wildcard's interface name: '%1'."); "the wildcard's interface name: '%1'.");
abort(fw, NULL, NULL, abort(fw, NULL, NULL,
err.arg(iface->getName().c_str()).toStdString()); err.arg(iface->getName().c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
/* /*
removed test to implement RFE #837238: "unnummbered wildcard interfaces" removed test to implement RFE #837238: "unnummbered wildcard interfaces"
@ -354,6 +378,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
"that is used in the firewall policy rule."); "that is used in the firewall policy rule.");
abort(fw, NULL, NULL, abort(fw, NULL, NULL,
err.arg(iface->getName().c_str()).toStdString()); err.arg(iface->getName().c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
QString err("Dynamic interface %1 should not have an " QString err("Dynamic interface %1 should not have an "
@ -397,6 +422,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
QString err("Missing IP address for interface %1"); QString err("Missing IP address for interface %1");
abort(fw, NULL, NULL, abort(fw, NULL, NULL,
err.arg(iface->getName().c_str()).toStdString()); err.arg(iface->getName().c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
for (list<FWObject*>::iterator j = all_addr.begin(); for (list<FWObject*>::iterator j = all_addr.begin();
@ -411,6 +437,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
.arg(FWObjectDatabase::getStringId( .arg(FWObjectDatabase::getStringId(
iface->getId()).c_str()) iface->getId()).c_str())
.arg(ip_addr->toString().c_str()).toStdString()); .arg(ip_addr->toString().c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
} }
} }
@ -430,7 +457,10 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
QString err; QString err;
if (!int_prop->validateInterface(parent, iface, true, err)) if (!int_prop->validateInterface(parent, iface, true, err))
{
abort(fw, NULL, NULL, err.toStdString()); abort(fw, NULL, NULL, err.toStdString());
throw FatalErrorInSingleRuleCompileMode();
}
string interface_type = iface->getOptionsObject()->getStr("type"); string interface_type = iface->getOptionsObject()->getStr("type");
if (interface_type.empty()) interface_type = "ethernet"; if (interface_type.empty()) interface_type = "ethernet";
@ -467,6 +497,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw)
); );
abort(fw, NULL, NULL, abort(fw, NULL, NULL,
err.arg(iface->getName().c_str()).toStdString()); err.arg(iface->getName().c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
} }
} }
@ -977,6 +1008,7 @@ int CompilerDriver::checkCluster(Cluster* cluster)
{ {
/* No configured cluster interface found */ /* No configured cluster interface found */
abort(cluster, NULL, NULL, "The cluster has no interfaces."); abort(cluster, NULL, NULL, "The cluster has no interfaces.");
throw FatalErrorInSingleRuleCompileMode();
} }
for (; cluster_ifaces != cluster_ifaces.end(); ++cluster_ifaces) for (; cluster_ifaces != cluster_ifaces.end(); ++cluster_ifaces)
@ -991,6 +1023,7 @@ int CompilerDriver::checkCluster(Cluster* cluster)
{ {
QString err("Found duplicate cluster interface %1"); QString err("Found duplicate cluster interface %1");
abort(cluster, NULL, NULL, err.arg(iface_name.c_str()).toStdString()); abort(cluster, NULL, NULL, err.arg(iface_name.c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
const InetAddr *other_iface_address = Interface::cast(*other_ifaces)->getAddressPtr(); const InetAddr *other_iface_address = Interface::cast(*other_ifaces)->getAddressPtr();
if (other_iface_address==NULL) continue; // cluster interface with no address if (other_iface_address==NULL) continue; // cluster interface with no address
@ -998,6 +1031,7 @@ int CompilerDriver::checkCluster(Cluster* cluster)
{ {
QString err("Found duplicate cluster interface address %1"); QString err("Found duplicate cluster interface address %1");
abort(cluster, NULL, NULL, err.arg(iface_address->toString().c_str()).toStdString()); abort(cluster, NULL, NULL, err.arg(iface_address->toString().c_str()).toStdString());
throw FatalErrorInSingleRuleCompileMode();
} }
} }
} }

View File

@ -113,580 +113,589 @@ string CompilerDriver_ipt::run(const std::string &cluster_id,
objdb->findInIndex(objdb->getIntId(firewall_id))); objdb->findInIndex(objdb->getIntId(firewall_id)));
assert(fw); assert(fw);
// Copy rules from the cluster object
populateClusterElements(cluster, fw);
commonChecks2(cluster, fw);
string fw_version = fw->getStr("version");
if (fw_version.empty()) fw_version = "(any version)";
string platform = fw->getStr("platform");
string host_os = fw->getStr("host_OS");
FWOptions* options = fw->getOptionsObject();
string s;
// Note that fwobjectname may be different from the name of the
// firewall fw This happens when we compile a member of a cluster
current_firewall_name = fw->getName().c_str();
fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" &&
fw->getOptionsObject()->getBool("use_iptables_restore"))
{
abort("Prolog place \"after policy reset\" can not be used"
" when policy is activated with iptables-restore");
}
string firewall_dir = options->getStr("firewall_dir");
if (firewall_dir=="") firewall_dir="/etc";
bool debug=options->getBool("debug");
QString shell_dbg = (debug)?"set -x":"" ;
std::auto_ptr<OSConfigurator_linux24> oscnf;
string platform_family = Resources::platform_res[platform]->
getResourceStr("/FWBuilderResources/Target/family");
string os_family = Resources::os_res[host_os]->
getResourceStr("/FWBuilderResources/Target/family");
bool supports_prolog_epilog = Resources::getTargetCapabilityBool(
platform, "supports_prolog_epilog");
if (!supports_prolog_epilog)
{
prolog_done = true;
epilog_done = true;
}
string os_variant = DISTRO;
/* minimal sanity checking */
if (os_family == "ipcop")
{
os_variant = "ipcop";
// can't use iptables-restore with ipcop
fw->getOptionsObject()->setBool("use_iptables_restore", false);
// ipcop has its own iptables commands that accept packets
// in states ESTABLISHED,RELATED
fw->getOptionsObject()->setBool("accept_established", false);
oscnf = std::auto_ptr<OSConfigurator_linux24>(
new OSConfigurator_ipcop(objdb , fw, false));
}
if (os_family == "linux24")
oscnf = std::auto_ptr<OSConfigurator_linux24>(
new OSConfigurator_linux24(objdb , fw, false));
if (os_family == "secuwall")
oscnf = std::auto_ptr<OSConfigurator_linux24>(
new OSConfigurator_secuwall(objdb , fw, false));
if (oscnf.get()==NULL)
{
abort("Unrecognized host OS " + fw->getStr("host_OS") +
" (family " + os_family+")");
return "";
}
if (inTestMode()) oscnf->setTestMode();
if (inEmbeddedMode()) oscnf->setEmbeddedMode();
oscnf->validateInterfaces();
oscnf->prolog();
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);
int routing_rules_count = 0;
bool have_ipv6 = false;
// track chains in each table separately. Can we have the same
// chain in filter and mangle tables ? Would it be the same
// chain, i.e. do we need to create it only once or do we create
// it twice, in each table separately ?
// Using separate trackers we track and create chain in each
// table separately.
std::map<const std::string, bool> minus_n_commands_filter;
std::map<const std::string, bool> minus_n_commands_mangle;
std::map<const std::string, bool> minus_n_commands_nat;
vector<int> ipv4_6_runs;
string generated_script; string generated_script;
findImportedRuleSets(fw, all_policies); try
findBranchesInMangleTable(fw, all_policies);
findImportedRuleSets(fw, all_nat);
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{ {
if (ipv4_run) ipv4_6_runs.push_back(AF_INET); // Copy rules from the cluster object
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); populateClusterElements(cluster, fw);
}
if (options->getStr("ipv4_6_order") == "ipv6_first") commonChecks2(cluster, fw);
{
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
for (vector<int>::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) string fw_version = fw->getStr("version");
{ if (fw_version.empty()) fw_version = "(any version)";
int policy_af = *i; string platform = fw->getStr("platform");
bool ipv6_policy = (policy_af == AF_INET6); string host_os = fw->getStr("host_OS");
/* FWOptions* options = fw->getOptionsObject();
clear chain tracker map only between ipv4/ipv6 runs string s;
Don't clear it between compiler runs for different
policy or nat objects for the same address family.
*/
minus_n_commands_filter.clear();
minus_n_commands_mangle.clear();
minus_n_commands_nat.clear();
/* // Note that fwobjectname may be different from the name of the
We need to create and run preprocessor for this address // firewall fw This happens when we compile a member of a cluster
family before nat and policy compilers, but if there are current_firewall_name = fw->getName().c_str();
no nat / policy rules for this address family, we do not
need preprocessor either.
*/
// Count rules for each address family fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
int nat_count = 0;
int policy_count = 0;
for (list<FWObject*>::iterator p=all_nat.begin(); if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" &&
p!=all_nat.end(); ++p) fw->getOptionsObject()->getBool("use_iptables_restore"))
{ {
NAT *nat = NAT::cast(*p); abort("Prolog place \"after policy reset\" can not be used"
if (nat->matchingAddressFamily(policy_af)) nat_count++; " when policy is activated with iptables-restore");
} }
for (list<FWObject*>::iterator p=all_policies.begin(); string firewall_dir = options->getStr("firewall_dir");
p!=all_policies.end(); ++p) if (firewall_dir=="") firewall_dir="/etc";
bool debug=options->getBool("debug");
QString shell_dbg = (debug)?"set -x":"" ;
std::auto_ptr<OSConfigurator_linux24> oscnf;
string platform_family = Resources::platform_res[platform]->
getResourceStr("/FWBuilderResources/Target/family");
string os_family = Resources::os_res[host_os]->
getResourceStr("/FWBuilderResources/Target/family");
bool supports_prolog_epilog = Resources::getTargetCapabilityBool(
platform, "supports_prolog_epilog");
if (!supports_prolog_epilog)
{ {
Policy *policy = Policy::cast(*p); prolog_done = true;
if (policy->matchingAddressFamily(policy_af)) policy_count++; epilog_done = true;
} }
if (nat_count || policy_count) string os_variant = DISTRO;
/* minimal sanity checking */
if (os_family == "ipcop")
{ {
Preprocessor* prep = new Preprocessor( os_variant = "ipcop";
objdb , fw, ipv6_policy);
if (inTestMode()) prep->setTestMode(); // can't use iptables-restore with ipcop
if (inEmbeddedMode()) prep->setEmbeddedMode(); fw->getOptionsObject()->setBool("use_iptables_restore", false);
prep->compile(); // ipcop has its own iptables commands that accept packets
delete prep; // in states ESTABLISHED,RELATED
fw->getOptionsObject()->setBool("accept_established", false);
oscnf = std::auto_ptr<OSConfigurator_linux24>(
new OSConfigurator_ipcop(objdb , fw, false));
} }
ostringstream automaitc_rules_stream; if (os_family == "linux24")
ostringstream filter_rules_stream; oscnf = std::auto_ptr<OSConfigurator_linux24>(
ostringstream mangle_rules_stream; new OSConfigurator_linux24(objdb , fw, false));
ostringstream nat_rules_stream;
bool empty_output = true; if (os_family == "secuwall")
oscnf = std::auto_ptr<OSConfigurator_linux24>(
new OSConfigurator_secuwall(objdb , fw, false));
// First, process branch NAT rulesets, then top NAT ruleset if (oscnf.get()==NULL)
NAT *top_nat = NULL;
for (list<FWObject*>::iterator p=all_nat.begin();
p!=all_nat.end(); ++p)
{ {
NAT *nat = NAT::cast(*p); abort("Unrecognized host OS " + fw->getStr("host_OS") +
if (!nat->matchingAddressFamily(policy_af)) continue; " (family " + os_family+")");
if (nat->isTop()) return "";
}
if (inTestMode()) oscnf->setTestMode();
if (inEmbeddedMode()) oscnf->setEmbeddedMode();
oscnf->validateInterfaces();
oscnf->prolog();
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);
int routing_rules_count = 0;
bool have_ipv6 = false;
// track chains in each table separately. Can we have the same
// chain in filter and mangle tables ? Would it be the same
// chain, i.e. do we need to create it only once or do we create
// it twice, in each table separately ?
// Using separate trackers we track and create chain in each
// table separately.
std::map<const std::string, bool> minus_n_commands_filter;
std::map<const std::string, bool> minus_n_commands_mangle;
std::map<const std::string, bool> minus_n_commands_nat;
vector<int> ipv4_6_runs;
findImportedRuleSets(fw, all_policies);
findBranchesInMangleTable(fw, all_policies);
findImportedRuleSets(fw, all_nat);
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
}
if (options->getStr("ipv4_6_order") == "ipv6_first")
{
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
for (vector<int>::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i)
{
int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
/*
clear chain tracker map only between ipv4/ipv6 runs
Don't clear it between compiler runs for different
policy or nat objects for the same address family.
*/
minus_n_commands_filter.clear();
minus_n_commands_mangle.clear();
minus_n_commands_nat.clear();
/*
We need to create and run preprocessor for this address
family before nat and policy compilers, but if there are
no nat / policy rules for this address family, we do not
need preprocessor either.
*/
// Count rules for each address family
int nat_count = 0;
int policy_count = 0;
for (list<FWObject*>::iterator p=all_nat.begin();
p!=all_nat.end(); ++p)
{ {
top_nat = nat; NAT *nat = NAT::cast(*p);
continue; if (nat->matchingAddressFamily(policy_af)) nat_count++;
} }
if (! processNatRuleSet(
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p)
{
Policy *policy = Policy::cast(*p);
if (policy->matchingAddressFamily(policy_af)) policy_count++;
}
if (nat_count || policy_count)
{
Preprocessor* prep = new Preprocessor(
objdb , fw, ipv6_policy);
if (inTestMode()) prep->setTestMode();
if (inEmbeddedMode()) prep->setEmbeddedMode();
prep->compile();
delete prep;
}
ostringstream automaitc_rules_stream;
ostringstream filter_rules_stream;
ostringstream mangle_rules_stream;
ostringstream nat_rules_stream;
bool empty_output = true;
// First, process branch NAT rulesets, then top NAT ruleset
NAT *top_nat = NULL;
for (list<FWObject*>::iterator p=all_nat.begin();
p!=all_nat.end(); ++p)
{
NAT *nat = NAT::cast(*p);
if (!nat->matchingAddressFamily(policy_af)) continue;
if (nat->isTop())
{
top_nat = nat;
continue;
}
if (! processNatRuleSet(
fw,
nat,
single_rule_id,
nat_rules_stream,
oscnf.get(),
policy_af,
minus_n_commands_nat)) empty_output = false;
}
if (top_nat &&
! processNatRuleSet(
fw, fw,
nat, top_nat,
single_rule_id, single_rule_id,
nat_rules_stream, nat_rules_stream,
oscnf.get(), oscnf.get(),
policy_af, policy_af,
minus_n_commands_nat)) empty_output = false; minus_n_commands_nat)) empty_output = false;
}
if (top_nat && for (int all_top = 0; all_top < 2; ++all_top)
! processNatRuleSet(
fw,
top_nat,
single_rule_id,
nat_rules_stream,
oscnf.get(),
policy_af,
minus_n_commands_nat)) empty_output = false;
for (int all_top = 0; all_top < 2; ++all_top)
{
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p )
{ {
Policy *policy = Policy::cast(*p); for (list<FWObject*>::iterator p=all_policies.begin();
if (!policy->matchingAddressFamily(policy_af)) continue; p!=all_policies.end(); ++p )
{
Policy *policy = Policy::cast(*p);
if (!policy->matchingAddressFamily(policy_af)) continue;
if (policy->isTop() && all_top == 0) continue; if (policy->isTop() && all_top == 0) continue;
if (!policy->isTop() && all_top == 1) continue; if (!policy->isTop() && all_top == 1) continue;
if (! processPolicyRuleSet( if (! processPolicyRuleSet(
fw, fw,
policy, policy,
single_rule_id, single_rule_id,
filter_rules_stream, filter_rules_stream,
mangle_rules_stream, mangle_rules_stream,
automaitc_rules_stream, automaitc_rules_stream,
oscnf.get(), oscnf.get(),
policy_af, policy_af,
minus_n_commands_filter, minus_n_commands_filter,
minus_n_commands_mangle)) empty_output = false; minus_n_commands_mangle)) empty_output = false;
}
} }
}
if (!empty_output && !single_rule_compile_on) if (!empty_output && !single_rule_compile_on)
{
if (ipv6_policy)
{ {
have_ipv6 = true; if (ipv6_policy)
generated_script += "\n\n"; {
generated_script += "# ================ IPv6\n"; have_ipv6 = true;
generated_script += "\n\n"; generated_script += "\n\n";
} else generated_script += "# ================ IPv6\n";
{ generated_script += "\n\n";
generated_script += "\n\n"; } else
generated_script += "# ================ IPv4\n"; {
generated_script += "\n\n"; generated_script += "\n\n";
generated_script += "# ================ IPv4\n";
generated_script += "\n\n";
}
} }
generated_script += dumpScript(fw,
automaitc_rules_stream.str(),
nat_rules_stream.str(),
mangle_rules_stream.str(),
filter_rules_stream.str(),
ipv6_policy);
} }
generated_script += dumpScript(fw, std::auto_ptr<RoutingCompiler_ipt> routing_compiler(
automaitc_rules_stream.str(), new RoutingCompiler_ipt(objdb, fw, false, oscnf.get()));
nat_rules_stream.str(),
mangle_rules_stream.str(),
filter_rules_stream.str(),
ipv6_policy);
}
std::auto_ptr<RoutingCompiler_ipt> routing_compiler( RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME));
new RoutingCompiler_ipt(objdb, fw, false, oscnf.get())); if (routing)
RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME));
if (routing)
{
routing_compiler->setSourceRuleSet(routing);
routing_compiler->setRuleSetName(routing->getName());
routing_compiler->setSingleRuleCompileMode(single_rule_id);
routing_compiler->setDebugLevel( dl );
if (rule_debug_on) routing_compiler->setDebugRule(drp);
routing_compiler->setVerbose( verbose );
if (inTestMode()) routing_compiler->setTestMode();
if (inEmbeddedMode()) routing_compiler->setEmbeddedMode();
if ( (routing_rules_count=routing_compiler->prolog()) > 0 )
{ {
routing_compiler->compile(); routing_compiler->setSourceRuleSet(routing);
routing_compiler->epilog(); routing_compiler->setRuleSetName(routing->getName());
routing_compiler->setSingleRuleCompileMode(single_rule_id);
routing_compiler->setDebugLevel( dl );
if (rule_debug_on) routing_compiler->setDebugRule(drp);
routing_compiler->setVerbose( verbose );
if (inTestMode()) routing_compiler->setTestMode();
if (inEmbeddedMode()) routing_compiler->setEmbeddedMode();
if ( (routing_rules_count=routing_compiler->prolog()) > 0 )
{
routing_compiler->compile();
routing_compiler->epilog();
}
if (routing_compiler->haveErrorsAndWarnings())
all_errors.push_back(routing_compiler->getErrors("").c_str());
} }
if (routing_compiler->haveErrorsAndWarnings()) if (single_rule_compile_on)
all_errors.push_back(routing_compiler->getErrors("").c_str()); {
} // in single rule compile mode just return the result Note
// that we do not return all_errors because all compilers
if (single_rule_compile_on) // include errors and warnings with generated code for each
{ // rule. CompilerDriver errors, however, need to be added on
// in single rule compile mode just return the result Note // top.
// that we do not return all_errors because all compilers return
// include errors and warnings with generated code for each getErrors("") +
// rule. CompilerDriver errors, however, need to be added on
// top.
return
getErrors("") +
// all_errors.join("\n").toStdString() + // all_errors.join("\n").toStdString() +
generated_script + routing_compiler->getCompiledScript(); generated_script + routing_compiler->getCompiledScript();
} }
if (haveErrorsAndWarnings()) if (haveErrorsAndWarnings())
{ {
all_errors.push_front(getErrors("").c_str()); all_errors.push_front(getErrors("").c_str());
} }
/* /*
* These store generated configuration internally, extract it later using * These store generated configuration internally, extract it later using
* OSConfiguration::getGeneratedFiles(); * OSConfiguration::getGeneratedFiles();
*/ */
oscnf->printChecksForRunTimeMultiAddress(); oscnf->printChecksForRunTimeMultiAddress();
oscnf->processFirewallOptions(); oscnf->processFirewallOptions();
/* /*
* now write generated scripts to files * now write generated scripts to files
*/ */
char *timestr; char *timestr;
time_t tm; time_t tm;
struct tm *stm; struct tm *stm;
tm = time(NULL); tm = time(NULL);
stm = localtime(&tm); stm = localtime(&tm);
timestr = strdup(ctime(&tm)); timestr = strdup(ctime(&tm));
timestr[strlen(timestr)-1] = '\0'; timestr[strlen(timestr)-1] = '\0';
#ifdef _WIN32 #ifdef _WIN32
char* user_name = getenv("USERNAME"); char* user_name = getenv("USERNAME");
#else #else
struct passwd *pwd = getpwuid(getuid()); struct passwd *pwd = getpwuid(getuid());
assert(pwd); assert(pwd);
char *user_name = pwd->pw_name; char *user_name = pwd->pw_name;
#endif #endif
if (user_name == NULL)
{
user_name = getenv("LOGNAME");
if (user_name == NULL) if (user_name == NULL)
abort("Can't figure out your user name"); {
user_name = getenv("LOGNAME");
if (user_name == NULL)
abort("Can't figure out your user name");
} }
/* /*
* assemble the script and then perhaps post-process it if it should * assemble the script and then perhaps post-process it if it should
* run on Linksys device with sveasoft firmware * run on Linksys device with sveasoft firmware
*/ */
Configlet script_skeleton(fw, "linux24", "script_skeleton"); Configlet script_skeleton(fw, "linux24", "script_skeleton");
script_skeleton.removeComments(); script_skeleton.removeComments();
QString script_buffer; QString script_buffer;
QTextStream script(&script_buffer, QIODevice::WriteOnly); QTextStream script(&script_buffer, QIODevice::WriteOnly);
script_buffer = ""; script_buffer = "";
script_skeleton.setVariable("shell_debug", shell_dbg); script_skeleton.setVariable("shell_debug", shell_dbg);
script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n"; script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n";
script << "export PATH" << "\n"; script << "export PATH" << "\n";
script_skeleton.setVariable("path", script_buffer); script_skeleton.setVariable("path", script_buffer);
script_buffer = ""; script_buffer = "";
Configlet script_constants(fw, "linux24", "constants"); Configlet script_constants(fw, "linux24", "constants");
script_skeleton.setVariable("constants", script_constants.expand()); script_skeleton.setVariable("constants", script_constants.expand());
/* /*
* print definitions for variables IPTABLES, IP, LOGGER. Some * print definitions for variables IPTABLES, IP, LOGGER. Some
* day we may add a choice of os_variant in the GUI. Right now * day we may add a choice of os_variant in the GUI. Right now
* paths are either default for a given os_variant, or custom * paths are either default for a given os_variant, or custom
* strings entered by user in the GUI and stored in firewall * strings entered by user in the GUI and stored in firewall
* options. * options.
*/ */
script_skeleton.setVariable("tools", script_skeleton.setVariable("tools",
oscnf->printPathForAllTools(os_variant).c_str()); oscnf->printPathForAllTools(os_variant).c_str());
script_skeleton.setVariable("shell_functions", script_skeleton.setVariable("shell_functions",
oscnf->printShellFunctions().c_str()); oscnf->printShellFunctions().c_str());
if (supports_prolog_epilog) if (supports_prolog_epilog)
{ {
//script_skeleton.setVariable("prolog_epilog", //script_skeleton.setVariable("prolog_epilog",
// oscnf->printPrologEpilogFunctions().c_str()); // oscnf->printPrologEpilogFunctions().c_str());
script_skeleton.setVariable(
"prolog_script",
fw->getOptionsObject()->getStr("prolog_script").c_str());
script_skeleton.setVariable(
"epilog_script",
fw->getOptionsObject()->getStr("epilog_script").c_str());
}
ostringstream ostr;
ostr << "# Configure interfaces" << endl;
if ( options->getBool("configure_bonding_interfaces") )
ostr << oscnf->printBondingInterfaceConfigurationCommands();
if ( options->getBool("configure_vlan_interfaces"))
ostr << oscnf->printVlanInterfaceConfigurationCommands();
if ( options->getBool("configure_bridge_interfaces") )
ostr << oscnf->printBridgeInterfaceConfigurationCommands();
if ( options->getBool("configure_interfaces") )
ostr << oscnf->printInterfaceConfigurationCommands();
ostr << oscnf->printDynamicAddressesConfigurationCommands();
script_skeleton.setVariable( script_skeleton.setVariable(
"prolog_script", "configure_interfaces", indent(4, QString(ostr.str().c_str())));
fw->getOptionsObject()->getStr("prolog_script").c_str());
script_skeleton.setVariable(
"epilog_script",
fw->getOptionsObject()->getStr("epilog_script").c_str());
}
ostringstream ostr;
ostr << "# Configure interfaces" << endl;
if ( options->getBool("configure_bonding_interfaces") )
ostr << oscnf->printBondingInterfaceConfigurationCommands();
if ( options->getBool("configure_vlan_interfaces"))
ostr << oscnf->printVlanInterfaceConfigurationCommands();
if ( options->getBool("configure_bridge_interfaces") )
ostr << oscnf->printBridgeInterfaceConfigurationCommands();
if ( options->getBool("configure_interfaces") )
ostr << oscnf->printInterfaceConfigurationCommands();
ostr << oscnf->printDynamicAddressesConfigurationCommands();
script_skeleton.setVariable(
"configure_interfaces", indent(4, QString(ostr.str().c_str())));
// verify_interfaces checks bridge interfaces so run it // verify_interfaces checks bridge interfaces so run it
// after those have been created // after those have been created
if (options->getBool("verify_interfaces")) if (options->getBool("verify_interfaces"))
{ {
list<FWObject*> l2=fw->getByType(Interface::TYPENAME); list<FWObject*> l2=fw->getByType(Interface::TYPENAME);
if (l2.empty() ) if (l2.empty() )
script_skeleton.setVariable("verify_interfaces", QString());
else
script_skeleton.setVariable("verify_interfaces",
oscnf->printVerifyInterfacesCommands().c_str());
} else
script_skeleton.setVariable("verify_interfaces", QString()); script_skeleton.setVariable("verify_interfaces", QString());
else
script_skeleton.setVariable("verify_interfaces",
oscnf->printVerifyInterfacesCommands().c_str());
} else
script_skeleton.setVariable("verify_interfaces", QString());
string prolog_place = fw->getOptionsObject()->getStr("prolog_place"); string prolog_place = fw->getOptionsObject()->getStr("prolog_place");
if (prolog_place == "") prolog_place="top"; if (prolog_place == "") prolog_place="top";
/* there is no way to stick prolog commands between iptables /* there is no way to stick prolog commands between iptables
* reset and iptables rules if we use iptables-restore to * reset and iptables rules if we use iptables-restore to
* activate policy. Therefore, if prolog needs to be ran after * activate policy. Therefore, if prolog needs to be ran after
* iptables flush and we use iptables-restore, we run prolog * iptables flush and we use iptables-restore, we run prolog
* on top of the script. * on top of the script.
*/ */
if (!prolog_done && if (!prolog_done &&
(prolog_place == "top" || (prolog_place == "top" ||
(prolog_place == "after_flush" && (prolog_place == "after_flush" &&
fw->getOptionsObject()->getBool("use_iptables_restore")))) fw->getOptionsObject()->getBool("use_iptables_restore"))))
{ {
script_skeleton.setVariable("prolog_top", 1); script_skeleton.setVariable("prolog_top", 1);
script_skeleton.setVariable("prolog_after_interfaces", 0); script_skeleton.setVariable("prolog_after_interfaces", 0);
script_skeleton.setVariable("prolog_after_flush", 0); script_skeleton.setVariable("prolog_after_flush", 0);
prolog_done = true; prolog_done = true;
} }
if (!prolog_done && prolog_place == "after_interfaces") if (!prolog_done && prolog_place == "after_interfaces")
{ {
script_skeleton.setVariable("prolog_top", 0); script_skeleton.setVariable("prolog_top", 0);
script_skeleton.setVariable("prolog_after_interfaces", 1); script_skeleton.setVariable("prolog_after_interfaces", 1);
script_skeleton.setVariable("prolog_after_flush", 0); script_skeleton.setVariable("prolog_after_flush", 0);
prolog_done = true; prolog_done = true;
} }
if (!prolog_done && prolog_place == "after_flush") if (!prolog_done && prolog_place == "after_flush")
{ {
script_skeleton.setVariable("prolog_top", 0); script_skeleton.setVariable("prolog_top", 0);
script_skeleton.setVariable("prolog_after_interfaces", 0); script_skeleton.setVariable("prolog_after_interfaces", 0);
script_skeleton.setVariable("prolog_after_flush", 1); script_skeleton.setVariable("prolog_after_flush", 1);
prolog_done = true; prolog_done = true;
} }
script_skeleton.setVariable("load_modules", script_skeleton.setVariable("load_modules",
oscnf->generateCodeForProtocolHandlers().c_str()); oscnf->generateCodeForProtocolHandlers().c_str());
script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"\"nat\"":""); script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"\"nat\"":"");
script_skeleton.setVariable("ip_forward_commands", script_skeleton.setVariable("ip_forward_commands",
oscnf->printIPForwardingCommands().c_str()); oscnf->printIPForwardingCommands().c_str());
/* /*
* script body begins here * script body begins here
*/ */
script_buffer = ""; script_buffer = "";
if (oscnf->haveErrorsAndWarnings()) if (oscnf->haveErrorsAndWarnings())
{ {
all_errors.push_back(oscnf->getErrors("").c_str()); all_errors.push_back(oscnf->getErrors("").c_str());
// script << "# OS configuration errors and warnings:" << "\n"; // script << "# OS configuration errors and warnings:" << "\n";
// script << oscnf->getErrors("# "); // script << oscnf->getErrors("# ");
}
script << oscnf->getCompiledScript();
script << generated_script;
script << routing_compiler->getCompiledScript();
script << endl;
script_skeleton.setVariable("script_body", indent(4, script_buffer));
script_skeleton.setVariable("timestamp", timestr);
script_skeleton.setVariable("tz", tzname[stm->tm_isdst]);
script_skeleton.setVariable("user", user_name);
/*
* Call reset_all function to flush and reset iptables, but only
* do this if we do not use iptables_restore. Reset is done as part
* of iptables-restore script in the latter case and commands are
* added in PolicyCompiler_ipt::flushAndSetDefaultPolicy()
*/
script_skeleton.setVariable("not_using_iptables_restore",
! fw->getOptionsObject()->getBool("use_iptables_restore"));
script_buffer = "";
script << " reset_iptables_v4" << endl;
if (have_ipv6) script << " reset_iptables_v6" << endl;
script_skeleton.setVariable("reset_all", script_buffer);
script_buffer = "";
Configlet top_comment(fw, "linux24", "top_comment");
top_comment.setVariable("version", VERSION);
QString build_num;
build_num.setNum(BUILD_NUM);
top_comment.setVariable("build", build_num);
top_comment.setVariable("timestamp", timestr);
top_comment.setVariable("tz", tzname[stm->tm_isdst]);
top_comment.setVariable("user", user_name);
QFileInfo fw_file_info(fw_file_name);
script_buffer = "";
script << MANIFEST_MARKER << "* " << fw_file_info.fileName();
string remote_name = fw->getOptionsObject()->getStr("script_name_on_firewall");
if (!remote_name.empty()) script << " " << remote_name;
script << "\n";
/* Add additional files to manifest if specified. Currently there
* are no GUI controls to let user provide alternative names for
* these on the firewall. See description of manifest format in
* comments in src/gui/FirewallInstaller.cpp
*/
list<string> file_list = oscnf->getGeneratedFiles();
if (!file_list.empty())
{
info(" Adding additional files to manifest");
list<string>::const_iterator c_iter = file_list.begin();
for (; c_iter != file_list.end(); ++c_iter)
{
string name = *c_iter;
script << MANIFEST_MARKER << name << "\n";
} }
script << oscnf->getCompiledScript();
script << generated_script;
script << routing_compiler->getCompiledScript();
script << endl;
script_skeleton.setVariable("script_body", indent(4, script_buffer));
script_skeleton.setVariable("timestamp", timestr);
script_skeleton.setVariable("tz", tzname[stm->tm_isdst]);
script_skeleton.setVariable("user", user_name);
/*
* Call reset_all function to flush and reset iptables, but only
* do this if we do not use iptables_restore. Reset is done as part
* of iptables-restore script in the latter case and commands are
* added in PolicyCompiler_ipt::flushAndSetDefaultPolicy()
*/
script_skeleton.setVariable("not_using_iptables_restore",
! fw->getOptionsObject()->getBool("use_iptables_restore"));
script_buffer = "";
script << " reset_iptables_v4" << endl;
if (have_ipv6) script << " reset_iptables_v6" << endl;
script_skeleton.setVariable("reset_all", script_buffer);
script_buffer = "";
Configlet top_comment(fw, "linux24", "top_comment");
top_comment.setVariable("version", VERSION);
QString build_num;
build_num.setNum(BUILD_NUM);
top_comment.setVariable("build", build_num);
top_comment.setVariable("timestamp", timestr);
top_comment.setVariable("tz", tzname[stm->tm_isdst]);
top_comment.setVariable("user", user_name);
QFileInfo fw_file_info(fw_file_name);
script_buffer = "";
script << MANIFEST_MARKER << "* " << fw_file_info.fileName();
string remote_name = fw->getOptionsObject()->getStr("script_name_on_firewall");
if (!remote_name.empty()) script << " " << remote_name;
script << "\n";
/* Add additional files to manifest if specified. Currently there
* are no GUI controls to let user provide alternative names for
* these on the firewall. See description of manifest format in
* comments in src/gui/FirewallInstaller.cpp
*/
list<string> file_list = oscnf->getGeneratedFiles();
if (!file_list.empty())
{
info(" Adding additional files to manifest");
list<string>::const_iterator c_iter = file_list.begin();
for (; c_iter != file_list.end(); ++c_iter)
{
string name = *c_iter;
script << MANIFEST_MARKER << name << "\n";
}
}
top_comment.setVariable("manifest", script_buffer);
top_comment.setVariable("platform", platform.c_str());
top_comment.setVariable("fw_version", fw_version.c_str());
top_comment.setVariable("comment", prepend("# ", fw->getComment().c_str()));
script_skeleton.setVariable("top_comment", top_comment.expand());
script_skeleton.setVariable("errors_and_warnings",
prepend("# ", all_errors.join("\n")));
info("Output file name: " + fw_file_name.toStdString());
QFile fw_file(fw_file_name);
if (fw_file.open(QIODevice::WriteOnly))
{
QTextStream fw_str(&fw_file);
fw_str << script_skeleton.expand();
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") + fw_file_name.toStdString() +
" for writing");
}
} }
catch (FatalErrorInSingleRuleCompileMode &ex)
top_comment.setVariable("manifest", script_buffer);
top_comment.setVariable("platform", platform.c_str());
top_comment.setVariable("fw_version", fw_version.c_str());
top_comment.setVariable("comment", prepend("# ", fw->getComment().c_str()));
script_skeleton.setVariable("top_comment", top_comment.expand());
script_skeleton.setVariable("errors_and_warnings",
prepend("# ", all_errors.join("\n")));
info("Output file name: " + fw_file_name.toStdString());
QFile fw_file(fw_file_name);
if (fw_file.open(QIODevice::WriteOnly))
{ {
QTextStream fw_str(&fw_file); return getErrors("");
fw_str << script_skeleton.expand();
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") + fw_file_name.toStdString() +
" for writing");
} }
return ""; return "";

View File

@ -182,252 +182,254 @@ string CompilerDriver_ipf::run(const std::string &cluster_id,
objdb->findInIndex(objdb->getIntId(firewall_id))); objdb->findInIndex(objdb->getIntId(firewall_id)));
assert(fw); assert(fw);
// Copy rules from the cluster object try
populateClusterElements(cluster, fw);
commonChecks2(cluster, fw);
FWOptions* options = fw->getOptionsObject();
string fw_version = fw->getStr("version");
// Note that fwobjectname may be different from the name of the
// firewall fw This happens when we compile a member of a cluster
current_firewall_name = fw->getName().c_str();
fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
QFileInfo finfo(fw_file_name);
QString ipf_file_name = finfo.completeBaseName() + "-ipf.conf";
QString nat_file_name = finfo.completeBaseName() + "-nat.conf";
if (finfo.path() != ".")
{ {
ipf_file_name = finfo.path() + "/" + ipf_file_name; // Copy rules from the cluster object
nat_file_name = finfo.path() + "/" + nat_file_name; populateClusterElements(cluster, fw);
}
QString remote_ipf_name = options->getStr("ipf_conf_file_name_on_firewall").c_str(); commonChecks2(cluster, fw);
if (remote_ipf_name.isEmpty()) remote_ipf_name = ipf_file_name;
QString remote_nat_name = options->getStr("nat_conf_file_name_on_firewall").c_str(); FWOptions* options = fw->getOptionsObject();
if (remote_nat_name.isEmpty()) remote_nat_name = nat_file_name; string fw_version = fw->getStr("version");
string s; // Note that fwobjectname may be different from the name of the
// firewall fw This happens when we compile a member of a cluster
current_firewall_name = fw->getName().c_str();
string firewall_dir = options->getStr("firewall_dir"); fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
if (firewall_dir=="") firewall_dir = "/etc/fw";
bool debug = options->getBool("debug"); QFileInfo finfo(fw_file_name);
string ipf_dbg = (debug)?"-v":""; QString ipf_file_name = finfo.completeBaseName() + "-ipf.conf";
QString nat_file_name = finfo.completeBaseName() + "-nat.conf";
if (finfo.path() != ".")
{
ipf_file_name = finfo.path() + "/" + ipf_file_name;
nat_file_name = finfo.path() + "/" + nat_file_name;
}
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb , fw, false)); QString remote_ipf_name = options->getStr("ipf_conf_file_name_on_firewall").c_str();
prep->compile(); if (remote_ipf_name.isEmpty()) remote_ipf_name = ipf_file_name;
QString remote_nat_name = options->getStr("nat_conf_file_name_on_firewall").c_str();
if (remote_nat_name.isEmpty()) remote_nat_name = nat_file_name;
string s;
string firewall_dir = options->getStr("firewall_dir");
if (firewall_dir=="") firewall_dir = "/etc/fw";
bool debug = options->getBool("debug");
string ipf_dbg = (debug)?"-v":"";
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb , fw, false));
prep->compile();
/* /*
* Process firewall options, build OS network configuration script * Process firewall options, build OS network configuration script
*/ */
std::auto_ptr<OSConfigurator_bsd> oscnf; std::auto_ptr<OSConfigurator_bsd> oscnf;
string host_os = fw->getStr("host_OS"); string host_os = fw->getStr("host_OS");
string family=Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); string family=Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family");
if ( host_os == "solaris" ) if ( host_os == "solaris" )
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_solaris(objdb , fw, false)); oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_solaris(objdb , fw, false));
if ( host_os == "openbsd") if ( host_os == "openbsd")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_openbsd(objdb , fw, false)); oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_openbsd(objdb , fw, false));
if ( host_os == "freebsd") if ( host_os == "freebsd")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_freebsd(objdb , fw, false)); oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_freebsd(objdb , fw, false));
if (oscnf.get()==NULL) if (oscnf.get()==NULL)
{ {
abort("Unrecognized host OS " + host_os + " (family " + family + ")"); abort("Unrecognized host OS " + host_os + " (family " + family + ")");
return ""; return "";
} }
oscnf->prolog(); oscnf->prolog();
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME); list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME); list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);
PolicyCompiler_ipf c(objdb , fw, false , oscnf.get() ); PolicyCompiler_ipf c(objdb , fw, false , oscnf.get() );
FWObject *policy = all_policies.front(); FWObject *policy = all_policies.front();
c.setSourceRuleSet(Policy::cast(policy)); c.setSourceRuleSet(Policy::cast(policy));
c.setRuleSetName(policy->getName()); c.setRuleSetName(policy->getName());
c.setSingleRuleCompileMode(single_rule_id); c.setSingleRuleCompileMode(single_rule_id);
c.setDebugLevel( dl ); c.setDebugLevel( dl );
if (rule_debug_on) c.setDebugRule( drp ); if (rule_debug_on) c.setDebugRule( drp );
c.setVerbose( verbose ); c.setVerbose( verbose );
if (inTestMode()) c.setTestMode(); if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode(); if (inEmbeddedMode()) c.setEmbeddedMode();
if ( c.prolog() > 0 ) if ( c.prolog() > 0 )
{ {
have_filter = true; have_filter = true;
c.compile(); c.compile();
c.epilog(); c.epilog();
} }
NATCompiler_ipf n( objdb , fw, false , oscnf.get() ); NATCompiler_ipf n( objdb , fw, false , oscnf.get() );
FWObject *nat = all_nat.front(); FWObject *nat = all_nat.front();
n.setSourceRuleSet(NAT::cast(nat)); n.setSourceRuleSet(NAT::cast(nat));
n.setRuleSetName(nat->getName()); n.setRuleSetName(nat->getName());
n.setSingleRuleCompileMode(single_rule_id); n.setSingleRuleCompileMode(single_rule_id);
n.setDebugLevel( dl ); n.setDebugLevel( dl );
if (rule_debug_on) n.setDebugRule( drn ); if (rule_debug_on) n.setDebugRule( drn );
n.setVerbose( verbose ); n.setVerbose( verbose );
if (inTestMode()) n.setTestMode(); if (inTestMode()) n.setTestMode();
if (inEmbeddedMode()) n.setEmbeddedMode(); if (inEmbeddedMode()) n.setEmbeddedMode();
if ( n.prolog() > 0 ) if ( n.prolog() > 0 )
{ {
have_nat = true; have_nat = true;
n.compile(); n.compile();
n.epilog(); n.epilog();
} }
if (haveErrorsAndWarnings()) if (haveErrorsAndWarnings())
{ {
all_errors.push_front(getErrors("").c_str()); all_errors.push_front(getErrors("").c_str());
} }
if (single_rule_compile_on)
{
// in single rule compile mode just return the result
ostringstream ostr;
if (have_filter)
{
if (c.haveErrorsAndWarnings())
{
all_errors.push_back(c.getErrors("").c_str());
}
ostr << c.getCompiledScript();
}
if (have_nat)
{
if (n.haveErrorsAndWarnings())
{
all_errors.push_back(n.getErrors("").c_str());
}
ostr << n.getCompiledScript();
}
return
all_errors.join("\n").toStdString() +
ostr.str();
}
if (single_rule_compile_on)
{
// in single rule compile mode just return the result
ostringstream ostr;
if (have_filter) if (have_filter)
{ {
if (c.haveErrorsAndWarnings()) QFile ipf_file(ipf_file_name);
if (ipf_file.open(QIODevice::WriteOnly))
{ {
all_errors.push_back(c.getErrors("").c_str()); QTextStream ipf_str(&ipf_file);
// ostr << "# Policy compiler errors and warnings:" if (c.haveErrorsAndWarnings())
// << endl; {
// ostr << c.getErrors("# "); all_errors.push_back(c.getErrors("").c_str());
ipf_str << "# Policy compiler errors and warnings:"
<< endl;
ipf_str << c.getErrors("# ");
}
ipf_str << c.getCompiledScript();
ipf_file.close();
ipf_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
} else
{
abort(string(" Failed to open file ") +
ipf_file_name.toStdString() +
" for writing");
} }
ostr << c.getCompiledScript();
QString filePath;
if (remote_ipf_name[0] == '/') filePath = remote_ipf_name;
else filePath = QString("${FWDIR}/") + remote_ipf_name;
activation_commands.push_back(
composeActivationCommand(
fw, true, ipf_dbg, fw_version, filePath.toStdString()));
} }
if (have_nat) if (have_nat)
{ {
if (n.haveErrorsAndWarnings()) QFile nat_file(nat_file_name);
if (nat_file.open(QIODevice::WriteOnly))
{ {
all_errors.push_back(n.getErrors("").c_str()); QTextStream nat_str(&nat_file);
// ostr << "# NAT compiler errors and warnings:" if (n.haveErrorsAndWarnings())
// << endl; {
// ostr << n.getErrors("# "); all_errors.push_back(n.getErrors("").c_str());
nat_str << "# NAT compiler errors and warnings:"
<< endl;
nat_str << n.getErrors("# ");
}
nat_str << n.getCompiledScript();
nat_file.close();
nat_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
} else
{
abort(string(" Failed to open file ") +
nat_file_name.toStdString() +
" for writing");
} }
ostr << n.getCompiledScript();
QString filePath;
if (remote_nat_name[0] == '/') filePath = remote_nat_name;
else filePath = QString("${FWDIR}/") + remote_nat_name;
activation_commands.push_back(
composeActivationCommand(
fw, false, ipf_dbg, fw_version, filePath.toStdString()));
} }
/*
return * assemble the script and then perhaps post-process it if needed
all_errors.join("\n").toStdString() + */
ostr.str(); QString script_buffer = assembleFwScript(
} cluster, fw, !cluster_id.empty(), oscnf.get());
if (have_filter) info("Output file name: " + fw_file_name.toStdString());
{
QFile ipf_file(ipf_file_name); QFile fw_file(fw_file_name);
if (ipf_file.open(QIODevice::WriteOnly)) if (fw_file.open(QIODevice::WriteOnly))
{ {
QTextStream ipf_str(&ipf_file); QTextStream fw_str(&fw_file);
if (c.haveErrorsAndWarnings()) fw_str << script_buffer;
{ fw_file.close();
all_errors.push_back(c.getErrors("").c_str()); fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
ipf_str << "# Policy compiler errors and warnings:"
<< endl;
ipf_str << c.getErrors("# ");
}
ipf_str << c.getCompiledScript();
ipf_file.close();
ipf_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
} else
{
abort(string(" Failed to open file ") +
ipf_file_name.toStdString() +
" for writing");
}
QString filePath;
if (remote_ipf_name[0] == '/') filePath = remote_ipf_name;
else filePath = QString("${FWDIR}/") + remote_ipf_name;
activation_commands.push_back(
composeActivationCommand(
fw, true, ipf_dbg, fw_version, filePath.toStdString()));
}
if (have_nat)
{
QFile nat_file(nat_file_name);
if (nat_file.open(QIODevice::WriteOnly))
{
QTextStream nat_str(&nat_file);
if (n.haveErrorsAndWarnings())
{
all_errors.push_back(n.getErrors("").c_str());
nat_str << "# NAT compiler errors and warnings:"
<< endl;
nat_str << n.getErrors("# ");
}
nat_str << n.getCompiledScript();
nat_file.close();
nat_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther | QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner | QFile::ExeOwner |
QFile::ExeGroup | QFile::ExeGroup |
QFile::ExeOther ); QFile::ExeOther );
info(" Compiled successfully");
} else } else
{ {
abort(string(" Failed to open file ") + abort(string(" Failed to open file ") +
nat_file_name.toStdString() + fw_file_name.toStdString() +
" for writing"); " for writing");
} }
QString filePath;
if (remote_nat_name[0] == '/') filePath = remote_nat_name;
else filePath = QString("${FWDIR}/") + remote_nat_name;
activation_commands.push_back(
composeActivationCommand(
fw, false, ipf_dbg, fw_version, filePath.toStdString()));
} }
/* catch (FatalErrorInSingleRuleCompileMode &ex)
* assemble the script and then perhaps post-process it if needed
*/
QString script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get());
info("Output file name: " + fw_file_name.toStdString());
QFile fw_file(fw_file_name);
if (fw_file.open(QIODevice::WriteOnly))
{ {
QTextStream fw_str(&fw_file); return getErrors("");
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") +
fw_file_name.toStdString() +
" for writing");
} }
return ""; return "";
} }

View File

@ -129,214 +129,222 @@ string CompilerDriver_ipfw::run(const std::string &cluster_id,
objdb->findInIndex(objdb->getIntId(firewall_id))); objdb->findInIndex(objdb->getIntId(firewall_id)));
assert(fw); assert(fw);
// Copy rules from the cluster object try
populateClusterElements(cluster, fw); {
// Copy rules from the cluster object
populateClusterElements(cluster, fw);
commonChecks2(cluster, fw); commonChecks2(cluster, fw);
FWOptions* options = fw->getOptionsObject(); FWOptions* options = fw->getOptionsObject();
// Note that fwobjectname may be different from the name of the // Note that fwobjectname may be different from the name of the
// firewall fw This happens when we compile a member of a cluster // firewall fw This happens when we compile a member of a cluster
current_firewall_name = fw->getName().c_str(); current_firewall_name = fw->getName().c_str();
fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
string s; string s;
string firewall_dir=options->getStr("firewall_dir"); string firewall_dir=options->getStr("firewall_dir");
if (firewall_dir=="") firewall_dir="/etc/fw"; if (firewall_dir=="") firewall_dir="/etc/fw";
bool debug=options->getBool("debug"); bool debug=options->getBool("debug");
string shell_dbg=(debug)?"-x":"" ; string shell_dbg=(debug)?"-x":"" ;
/* /*
* Process firewall options, build OS network configuration script * Process firewall options, build OS network configuration script
*/ */
std::auto_ptr<OSConfigurator_bsd> oscnf; std::auto_ptr<OSConfigurator_bsd> oscnf;
string host_os = fw->getStr("host_OS"); string host_os = fw->getStr("host_OS");
string family = Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); string family = Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family");
if ( host_os == "macosx") if ( host_os == "macosx")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_macosx(objdb , fw, false)); oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_macosx(objdb , fw, false));
if ( host_os == "freebsd") if ( host_os == "freebsd")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_freebsd(objdb , fw, false)); oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_freebsd(objdb , fw, false));
if (oscnf.get()==NULL) if (oscnf.get()==NULL)
{
abort("Unrecognized host OS " + host_os + " (family " + family + ")");
return "";
}
oscnf->prolog();
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
vector<int> ipv4_6_runs;
string generated_script;
int policy_rules_count = 0;
int ipfw_rule_number = 0;
findImportedRuleSets(fw, all_policies);
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
}
if (options->getStr("ipv4_6_order") == "ipv6_first")
{
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
for (vector<int>::iterator i=ipv4_6_runs.begin();
i!=ipv4_6_runs.end(); ++i)
{
int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
/*
We need to create and run preprocessor for this address
family before nat and policy compilers, but if there are
no nat / policy rules for this address family, we do not
need preprocessor either.
*/
// Count rules for each address family
int policy_count = 0;
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p)
{ {
Policy *policy = Policy::cast(*p); abort("Unrecognized host OS " + host_os + " (family " + family + ")");
if (policy->matchingAddressFamily(policy_af)) policy_count++; return "";
} }
if (policy_count) oscnf->prolog();
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
vector<int> ipv4_6_runs;
string generated_script;
int policy_rules_count = 0;
int ipfw_rule_number = 0;
findImportedRuleSets(fw, all_policies);
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{ {
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb , fw, ipv6_policy)); if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (inTestMode()) prep->setTestMode(); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (inEmbeddedMode()) prep->setEmbeddedMode();
prep->compile();
} }
ostringstream c_str; if (options->getStr("ipv4_6_order") == "ipv6_first")
bool empty_output = true;
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p )
{ {
Policy *policy = Policy::cast(*p); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
string branch_name = policy->getName(); if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
if (!policy->matchingAddressFamily(policy_af)) continue; for (vector<int>::iterator i=ipv4_6_runs.begin();
i!=ipv4_6_runs.end(); ++i)
{
int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
PolicyCompiler_ipfw c(objdb, fw, ipv6_policy, oscnf.get()); /*
c.setIPFWNumber(ipfw_rule_number); We need to create and run preprocessor for this address
c.setSourceRuleSet( policy ); family before nat and policy compilers, but if there are
c.setRuleSetName(branch_name); no nat / policy rules for this address family, we do not
c.setSingleRuleCompileMode(single_rule_id); need preprocessor either.
c.setDebugLevel( dl ); */
if (rule_debug_on) c.setDebugRule( drp );
c.setVerbose( (bool)(verbose) );
if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode();
if ( (policy_rules_count=c.prolog()) > 0 ) // Count rules for each address family
int policy_count = 0;
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p)
{ {
c.compile(); Policy *policy = Policy::cast(*p);
c.epilog(); if (policy->matchingAddressFamily(policy_af)) policy_count++;
}
ipfw_rule_number = c.getIPFWNumber(); if (policy_count)
{
std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb , fw, ipv6_policy));
if (inTestMode()) prep->setTestMode();
if (inEmbeddedMode()) prep->setEmbeddedMode();
prep->compile();
}
if (c.getCompiledScriptLength() > 0) ostringstream c_str;
bool empty_output = true;
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p )
{
Policy *policy = Policy::cast(*p);
string branch_name = policy->getName();
if (!policy->matchingAddressFamily(policy_af)) continue;
PolicyCompiler_ipfw c(objdb, fw, ipv6_policy, oscnf.get());
c.setIPFWNumber(ipfw_rule_number);
c.setSourceRuleSet( policy );
c.setRuleSetName(branch_name);
c.setSingleRuleCompileMode(single_rule_id);
c.setDebugLevel( dl );
if (rule_debug_on) c.setDebugRule( drp );
c.setVerbose( (bool)(verbose) );
if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode();
if ( (policy_rules_count=c.prolog()) > 0 )
{ {
if (!single_rule_compile_on) c.compile();
c_str << "# ================ Rule set " c.epilog();
<< branch_name << endl;
if (c.haveErrorsAndWarnings()) ipfw_rule_number = c.getIPFWNumber();
if (c.getCompiledScriptLength() > 0)
{ {
all_errors.push_back(c.getErrors("").c_str()); if (!single_rule_compile_on)
// c_str << "# Policy compiler errors and warnings:" c_str << "# ================ Rule set "
// << endl; << branch_name << endl;
// c_str << c.getErrors("# "); if (c.haveErrorsAndWarnings())
{
all_errors.push_back(c.getErrors("").c_str());
// c_str << "# Policy compiler errors and warnings:"
// << endl;
// c_str << c.getErrors("# ");
}
c_str << c.getCompiledScript();
c_str << endl;
empty_output = false;
} }
c_str << c.getCompiledScript();
c_str << endl;
empty_output = false;
} }
} }
}
if (!empty_output && !single_rule_compile_on) if (!empty_output && !single_rule_compile_on)
{
if (ipv6_policy)
{ {
generated_script += "\n\n"; if (ipv6_policy)
generated_script += "# ================ IPv6\n"; {
generated_script += "\n\n"; generated_script += "\n\n";
} else generated_script += "# ================ IPv6\n";
{ generated_script += "\n\n";
generated_script += "\n\n"; } else
generated_script += "# ================ IPv4\n"; {
generated_script += "\n\n"; generated_script += "\n\n";
generated_script += "# ================ IPv4\n";
generated_script += "\n\n";
}
} }
generated_script += c_str.str();
} }
generated_script += c_str.str(); if (haveErrorsAndWarnings())
} {
all_errors.push_front(getErrors("").c_str());
}
if (haveErrorsAndWarnings()) if (single_rule_compile_on)
{ {
all_errors.push_front(getErrors("").c_str()); return
} all_errors.join("\n").toStdString() +
generated_script;
}
if (single_rule_compile_on) PolicyCompiler_ipfw c(objdb, fw, false, oscnf.get());
{ activation_commands.push_back(c.defaultRules().c_str());
return activation_commands.push_back(generated_script.c_str());
all_errors.join("\n").toStdString() +
generated_script;
}
PolicyCompiler_ipfw c(objdb, fw, false, oscnf.get());
activation_commands.push_back(c.defaultRules().c_str());
activation_commands.push_back(generated_script.c_str());
/* /*
* assemble the script and then perhaps post-process it if needed * assemble the script and then perhaps post-process it if needed
*/ */
QString script_buffer = assembleFwScript( QString script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get()); cluster, fw, !cluster_id.empty(), oscnf.get());
info("Output file name: " + fw_file_name.toStdString()); info("Output file name: " + fw_file_name.toStdString());
QFile fw_file(fw_file_name); QFile fw_file(fw_file_name);
if (fw_file.open(QIODevice::WriteOnly)) if (fw_file.open(QIODevice::WriteOnly))
{ {
QTextStream fw_str(&fw_file); QTextStream fw_str(&fw_file);
fw_str << script_buffer; fw_str << script_buffer;
fw_file.close(); fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner | fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther | QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner | QFile::ExeOwner |
QFile::ExeGroup | QFile::ExeGroup |
QFile::ExeOther ); QFile::ExeOther );
info(" Compiled successfully"); info(" Compiled successfully");
} else } else
{ {
abort(string(" Failed to open file ") + abort(string(" Failed to open file ") +
fw_file_name.toStdString() + fw_file_name.toStdString() +
" for writing"); " for writing");
}
} }
catch (FatalErrorInSingleRuleCompileMode &ex)
{
return getErrors("");
}
return ""; return "";
} }

View File

@ -209,399 +209,406 @@ string CompilerDriver_pf::run(const std::string &cluster_id,
objdb->findInIndex(objdb->getIntId(firewall_id))); objdb->findInIndex(objdb->getIntId(firewall_id)));
assert(fw); assert(fw);
// Copy rules from the cluster object try
populateClusterElements(cluster, fw); {
// Copy rules from the cluster object
populateClusterElements(cluster, fw);
commonChecks2(cluster, fw); commonChecks2(cluster, fw);
FWOptions* options = fw->getOptionsObject(); FWOptions* options = fw->getOptionsObject();
// Note that fwobjectname may be different from the name of the // Note that fwobjectname may be different from the name of the
// firewall fw This happens when we compile a member of a cluster // firewall fw This happens when we compile a member of a cluster
current_firewall_name = fw->getName().c_str(); current_firewall_name = fw->getName().c_str();
fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw");
string firewall_dir = options->getStr("firewall_dir"); string firewall_dir = options->getStr("firewall_dir");
if (firewall_dir=="") firewall_dir="/etc/fw"; if (firewall_dir=="") firewall_dir="/etc/fw";
string prolog_place = options->getStr("prolog_place"); string prolog_place = options->getStr("prolog_place");
if (prolog_place.empty()) prolog_place = "fw_file"; // old default if (prolog_place.empty()) prolog_place = "fw_file"; // old default
string pre_hook = fw->getOptionsObject()->getStr("prolog_script"); string pre_hook = fw->getOptionsObject()->getStr("prolog_script");
bool debug = options->getBool("debug"); bool debug = options->getBool("debug");
string shell_dbg = (debug)?"set -x":"" ; string shell_dbg = (debug)?"set -x":"" ;
string pfctl_dbg = (debug)?"-v ":""; string pfctl_dbg = (debug)?"-v ":"";
/* /*
* Process firewall options, build OS network configuration script * Process firewall options, build OS network configuration script
*/ */
std::auto_ptr<OSConfigurator_bsd> oscnf; std::auto_ptr<OSConfigurator_bsd> oscnf;
string platform = fw->getStr("platform"); string platform = fw->getStr("platform");
string fw_version = fw->getStr("version"); string fw_version = fw->getStr("version");
string host_os = fw->getStr("host_OS"); string host_os = fw->getStr("host_OS");
string family = Resources::os_res[host_os string family = Resources::os_res[host_os
]->Resources::getResourceStr("/FWBuilderResources/Target/family"); ]->Resources::getResourceStr("/FWBuilderResources/Target/family");
if (host_os == "solaris") if (host_os == "solaris")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_solaris( oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_solaris(
objdb , fw, false)); objdb , fw, false));
if (host_os == "openbsd") if (host_os == "openbsd")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_openbsd( oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_openbsd(
objdb , fw, false)); objdb , fw, false));
if (host_os == "freebsd") if (host_os == "freebsd")
oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_freebsd( oscnf = std::auto_ptr<OSConfigurator_bsd>(new OSConfigurator_freebsd(
objdb , fw, false)); objdb , fw, false));
if (oscnf.get()==NULL) if (oscnf.get()==NULL)
{
abort("Unrecognized host OS " + host_os + " (family " + family + ")");
return "";
}
oscnf->prolog();
string remote_fw_name = options->getStr("script_name_on_firewall");
string remote_conf_name = options->getStr("conf_file_name_on_firewall");
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);
findImportedRuleSets(fw, all_policies);
vector<int> ipv4_6_runs;
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
}
if (options->getStr("ipv4_6_order") == "ipv6_first")
{
if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
}
ostringstream* main_str = new ostringstream();
for (vector<int>::iterator i=ipv4_6_runs.begin();
i!=ipv4_6_runs.end(); ++i)
{
int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
// Count rules for each address family
int nat_count = 0;
int policy_count = 0;
for (list<FWObject*>::iterator p=all_nat.begin();
p!=all_nat.end(); ++p)
{ {
NAT *nat = NAT::cast(*p); abort("Unrecognized host OS " + host_os + " (family " + family + ")");
if (nat->matchingAddressFamily(policy_af)) nat_count++; return "";
} }
for (list<FWObject*>::iterator p=all_policies.begin(); oscnf->prolog();
p!=all_policies.end(); ++p)
string remote_fw_name = options->getStr("script_name_on_firewall");
string remote_conf_name = options->getStr("conf_file_name_on_firewall");
list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);
list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME);
findImportedRuleSets(fw, all_policies);
vector<int> ipv4_6_runs;
// command line options -4 and -6 control address family for which
// script will be generated. If "-4" is used, only ipv4 part will
// be generated. If "-6" is used, only ipv6 part will be generated.
// If neither is used, both parts will be done.
if (options->getStr("ipv4_6_order").empty() ||
options->getStr("ipv4_6_order") == "ipv4_first")
{ {
Policy *policy = Policy::cast(*p); if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (policy->matchingAddressFamily(policy_af)) policy_count++; if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
} }
if (nat_count || policy_count) if (options->getStr("ipv4_6_order") == "ipv6_first")
{ {
Preprocessor_pf* prep = new Preprocessor_pf( if (ipv6_run) ipv4_6_runs.push_back(AF_INET6);
objdb , fw, ipv6_policy); if (ipv4_run) ipv4_6_runs.push_back(AF_INET);
if (inTestMode()) prep->setTestMode();
if (inEmbeddedMode()) prep->setEmbeddedMode();
prep->compile();
delete prep;
} }
list<NATCompiler_pf::redirectRuleInfo> redirect_rules_info; ostringstream* main_str = new ostringstream();
for (list<FWObject*>::iterator p=all_nat.begin(); for (vector<int>::iterator i=ipv4_6_runs.begin();
p!=all_nat.end(); ++p ) i!=ipv4_6_runs.end(); ++i)
{ {
NAT *nat = NAT::cast(*p); int policy_af = *i;
bool ipv6_policy = (policy_af == AF_INET6);
if (!nat->matchingAddressFamily(policy_af)) continue; // Count rules for each address family
int nat_count = 0;
int policy_count = 0;
string ruleset_name = nat->getName(); for (list<FWObject*>::iterator p=all_nat.begin();
p!=all_nat.end(); ++p)
if (ruleset_name.find("/*")!=string::npos)
{ {
QString err("The name of the policy ruleset %1" NAT *nat = NAT::cast(*p);
" ends with '/*', assuming it is externally" if (nat->matchingAddressFamily(policy_af)) nat_count++;
" controlled and skipping it.");
warning(fw, nat, NULL,
err.arg(ruleset_name.c_str()).toStdString());
continue;
} }
if (nat->isTop()) for (list<FWObject*>::iterator p=all_policies.begin();
ruleset_name = "__main__"; p!=all_policies.end(); ++p)
if (table_factories.count(ruleset_name) == 0)
{ {
table_factories[ruleset_name] = new fwcompiler::TableFactory(this); Policy *policy = Policy::cast(*p);
if (policy->matchingAddressFamily(policy_af)) policy_count++;
} }
NATCompiler_pf n( objdb, fw, ipv6_policy, oscnf.get(), if (nat_count || policy_count)
table_factories[ruleset_name] );
n.setSourceRuleSet( nat );
n.setRuleSetName(nat->getName());
n.setSingleRuleCompileMode(single_rule_id);
n.setDebugLevel( dl );
if (rule_debug_on) n.setDebugRule(drn);
n.setVerbose( verbose );
if (inTestMode()) n.setTestMode();
if (inEmbeddedMode()) n.setEmbeddedMode();
int nat_rules_count = 0;
if ( (nat_rules_count=n.prolog()) > 0 )
{ {
n.compile(); Preprocessor_pf* prep = new Preprocessor_pf(
n.epilog(); objdb , fw, ipv6_policy);
} if (inTestMode()) prep->setTestMode();
have_nat = (have_nat || (nat_rules_count > 0)); if (inEmbeddedMode()) prep->setEmbeddedMode();
prep->compile();
if (nat->isTop()) delete prep;
{
generated_scripts[ruleset_name] = main_str;
} else
{
generated_scripts[ruleset_name] = new ostringstream();
} }
if (n.getCompiledScriptLength() > 0) list<NATCompiler_pf::redirectRuleInfo> redirect_rules_info;
for (list<FWObject*>::iterator p=all_nat.begin();
p!=all_nat.end(); ++p )
{ {
if (n.haveErrorsAndWarnings()) NAT *nat = NAT::cast(*p);
if (!nat->matchingAddressFamily(policy_af)) continue;
string ruleset_name = nat->getName();
if (ruleset_name.find("/*")!=string::npos)
{ {
// store errors and warnings so they will appear on top QString err("The name of the policy ruleset %1"
// of .fw file in addition to the .conf file " ends with '/*', assuming it is externally"
all_errors.push_back(n.getErrors("").c_str()); " controlled and skipping it.");
*(generated_scripts[ruleset_name]) warning(fw, nat, NULL,
<< "# NAT compiler errors and warnings:" err.arg(ruleset_name.c_str()).toStdString());
<< endl; continue;
*(generated_scripts[ruleset_name]) << n.getErrors("# ");
} }
*(generated_scripts[ruleset_name]) << n.getCompiledScript();
*(generated_scripts[ruleset_name]) << endl;
}
conf_files[ruleset_name] = getConfFileName( if (nat->isTop())
ruleset_name, ruleset_name = "__main__";
current_firewall_name.toUtf8().constData(),
fw_file_name.toUtf8().constData());
remote_conf_files[ruleset_name] = getRemoteConfFileName( if (table_factories.count(ruleset_name) == 0)
ruleset_name,
conf_files[ruleset_name],
remote_fw_name,
remote_conf_name);
const list<NATCompiler_pf::redirectRuleInfo> lst =
n.getRedirRulesInfo();
redirect_rules_info.insert(redirect_rules_info.begin(),
lst.begin(), lst.end());
}
for (list<FWObject*>::iterator p=all_policies.begin();
p!=all_policies.end(); ++p )
{
Policy *policy = Policy::cast(*p);
string ruleset_name = policy->getName();
if (ruleset_name.find("/*")!=string::npos)
{
QString err("The name of the policy ruleset %1"
" ends with '/*', assuming it is externally"
" controlled and skipping it.");
warning(fw, policy, NULL,
err.arg(ruleset_name.c_str()).toStdString());
continue;
}
if (!policy->matchingAddressFamily(policy_af)) continue;
if (policy->isTop())
ruleset_name = "__main__";
if (table_factories.count(ruleset_name) == 0)
{
table_factories[ruleset_name] = new fwcompiler::TableFactory(this);
}
PolicyCompiler_pf c( objdb, fw, ipv6_policy, oscnf.get(),
&redirect_rules_info,
table_factories[ruleset_name] );
c.setSourceRuleSet( policy );
c.setRuleSetName(policy->getName());
c.setSingleRuleCompileMode(single_rule_id);
c.setDebugLevel( dl );
if (rule_debug_on) c.setDebugRule(drp);
c.setVerbose( verbose );
if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode();
int pf_rules_count = 0;
if ( (pf_rules_count=c.prolog()) > 0 )
{
c.compile();
c.epilog();
}
have_filter = (have_filter || (pf_rules_count > 0));
if (policy->isTop())
{
generated_scripts[ruleset_name] = main_str;
} else
{
generated_scripts[ruleset_name] = new ostringstream();
}
if (c.getCompiledScriptLength() > 0)
{
if (c.haveErrorsAndWarnings())
{ {
all_errors.push_back(c.getErrors("").c_str()); table_factories[ruleset_name] = new fwcompiler::TableFactory(this);
*(generated_scripts[ruleset_name])
<< "# Policy compiler errors and warnings:"
<< endl;
*(generated_scripts[ruleset_name]) << c.getErrors("# ");
} }
*(generated_scripts[ruleset_name]) << c.getCompiledScript();
*(generated_scripts[ruleset_name]) << endl; NATCompiler_pf n( objdb, fw, ipv6_policy, oscnf.get(),
table_factories[ruleset_name] );
n.setSourceRuleSet( nat );
n.setRuleSetName(nat->getName());
n.setSingleRuleCompileMode(single_rule_id);
n.setDebugLevel( dl );
if (rule_debug_on) n.setDebugRule(drn);
n.setVerbose( verbose );
if (inTestMode()) n.setTestMode();
if (inEmbeddedMode()) n.setEmbeddedMode();
int nat_rules_count = 0;
if ( (nat_rules_count=n.prolog()) > 0 )
{
n.compile();
n.epilog();
}
have_nat = (have_nat || (nat_rules_count > 0));
if (nat->isTop())
{
generated_scripts[ruleset_name] = main_str;
} else
{
generated_scripts[ruleset_name] = new ostringstream();
}
if (n.getCompiledScriptLength() > 0)
{
if (n.haveErrorsAndWarnings())
{
// store errors and warnings so they will appear on top
// of .fw file in addition to the .conf file
all_errors.push_back(n.getErrors("").c_str());
*(generated_scripts[ruleset_name])
<< "# NAT compiler errors and warnings:"
<< endl;
*(generated_scripts[ruleset_name]) << n.getErrors("# ");
}
*(generated_scripts[ruleset_name]) << n.getCompiledScript();
*(generated_scripts[ruleset_name]) << endl;
}
conf_files[ruleset_name] = getConfFileName(
ruleset_name,
current_firewall_name.toUtf8().constData(),
fw_file_name.toUtf8().constData());
remote_conf_files[ruleset_name] = getRemoteConfFileName(
ruleset_name,
conf_files[ruleset_name],
remote_fw_name,
remote_conf_name);
const list<NATCompiler_pf::redirectRuleInfo> lst =
n.getRedirRulesInfo();
redirect_rules_info.insert(redirect_rules_info.begin(),
lst.begin(), lst.end());
} }
conf_files[ruleset_name] = getConfFileName( for (list<FWObject*>::iterator p=all_policies.begin();
ruleset_name, p!=all_policies.end(); ++p )
current_firewall_name.toUtf8().constData(), {
fw_file_name.toUtf8().constData()); Policy *policy = Policy::cast(*p);
string ruleset_name = policy->getName();
remote_conf_files[ruleset_name] = getRemoteConfFileName( if (ruleset_name.find("/*")!=string::npos)
ruleset_name, {
conf_files[ruleset_name], QString err("The name of the policy ruleset %1"
remote_fw_name, " ends with '/*', assuming it is externally"
remote_conf_name); " controlled and skipping it.");
warning(fw, policy, NULL,
err.arg(ruleset_name.c_str()).toStdString());
continue;
}
if (!policy->matchingAddressFamily(policy_af)) continue;
if (policy->isTop())
ruleset_name = "__main__";
if (table_factories.count(ruleset_name) == 0)
{
table_factories[ruleset_name] = new fwcompiler::TableFactory(this);
}
PolicyCompiler_pf c( objdb, fw, ipv6_policy, oscnf.get(),
&redirect_rules_info,
table_factories[ruleset_name] );
c.setSourceRuleSet( policy );
c.setRuleSetName(policy->getName());
c.setSingleRuleCompileMode(single_rule_id);
c.setDebugLevel( dl );
if (rule_debug_on) c.setDebugRule(drp);
c.setVerbose( verbose );
if (inTestMode()) c.setTestMode();
if (inEmbeddedMode()) c.setEmbeddedMode();
int pf_rules_count = 0;
if ( (pf_rules_count=c.prolog()) > 0 )
{
c.compile();
c.epilog();
}
have_filter = (have_filter || (pf_rules_count > 0));
if (policy->isTop())
{
generated_scripts[ruleset_name] = main_str;
} else
{
generated_scripts[ruleset_name] = new ostringstream();
}
if (c.getCompiledScriptLength() > 0)
{
if (c.haveErrorsAndWarnings())
{
all_errors.push_back(c.getErrors("").c_str());
*(generated_scripts[ruleset_name])
<< "# Policy compiler errors and warnings:"
<< endl;
*(generated_scripts[ruleset_name]) << c.getErrors("# ");
}
*(generated_scripts[ruleset_name]) << c.getCompiledScript();
*(generated_scripts[ruleset_name]) << endl;
}
conf_files[ruleset_name] = getConfFileName(
ruleset_name,
current_firewall_name.toUtf8().constData(),
fw_file_name.toUtf8().constData());
remote_conf_files[ruleset_name] = getRemoteConfFileName(
ruleset_name,
conf_files[ruleset_name],
remote_fw_name,
remote_conf_name);
}
} }
}
if (haveErrorsAndWarnings()) if (haveErrorsAndWarnings())
{ {
all_errors.push_front(getErrors("").c_str()); all_errors.push_front(getErrors("").c_str());
} }
if (single_rule_compile_on) if (single_rule_compile_on)
{ {
// in single rule compile mode just return the result // in single rule compile mode just return the result
QString buffer; QString buffer;
QTextStream pf_str(&buffer); QTextStream pf_str(&buffer);
for (map<string, ostringstream*>::iterator fi=generated_scripts.begin();
fi!=generated_scripts.end(); fi++)
{
string ruleset_name = fi->first;
ostringstream *strm = fi->second;
pf_str << table_factories[ruleset_name]->PrintTables();
pf_str << strm->str();
}
// clear() calls destructors of all elements in the container
table_factories.clear();
generated_scripts.clear();
return
all_errors.join("\n").toStdString() +
buffer.toStdString();
}
/*
* now write generated scripts to files
*/
for (map<string, ostringstream*>::iterator fi=generated_scripts.begin(); for (map<string, ostringstream*>::iterator fi=generated_scripts.begin();
fi!=generated_scripts.end(); fi++) fi!=generated_scripts.end(); fi++)
{ {
string ruleset_name = fi->first; string ruleset_name = fi->first;
string file_name = conf_files[ruleset_name];
ostringstream *strm = fi->second; ostringstream *strm = fi->second;
pf_str << table_factories[ruleset_name]->PrintTables();
pf_str << strm->str(); if (ruleset_name.find("/*")!=string::npos) continue;
QFile pf_file(file_name.c_str());
if (pf_file.open(QIODevice::WriteOnly))
{
QTextStream pf_str(&pf_file);
if (ruleset_name == "__main__")
{
printStaticOptions(pf_str, fw);
pf_str << table_factories[ruleset_name]->PrintTables();
if (prolog_place == "pf_file_after_tables")
printProlog(pf_str, pre_hook);
} else
{
pf_str << table_factories[ruleset_name]->PrintTables();
}
pf_str << strm->str();
pf_file.close();
} else
{
// clear() calls destructors of all elements in the container
table_factories.clear();
generated_scripts.clear();
abort(string(" Failed to open file ") + file_name + " for writing");
}
} }
/*
* assemble the script and then perhaps post-process it if needed
*/
QString script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get());
// clear() calls destructors of all elements in the container // clear() calls destructors of all elements in the container
table_factories.clear(); table_factories.clear();
generated_scripts.clear(); generated_scripts.clear();
return info("Output file name: " + fw_file_name.toStdString());
all_errors.join("\n").toStdString() +
buffer.toStdString();
}
/* QFile fw_file(fw_file_name);
* now write generated scripts to files if (fw_file.open(QIODevice::WriteOnly))
*/
for (map<string, ostringstream*>::iterator fi=generated_scripts.begin();
fi!=generated_scripts.end(); fi++)
{
string ruleset_name = fi->first;
string file_name = conf_files[ruleset_name];
ostringstream *strm = fi->second;
if (ruleset_name.find("/*")!=string::npos) continue;
QFile pf_file(file_name.c_str());
if (pf_file.open(QIODevice::WriteOnly))
{ {
QTextStream pf_str(&pf_file); QTextStream fw_str(&fw_file);
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
if (ruleset_name == "__main__") info(" Compiled successfully");
{
printStaticOptions(pf_str, fw);
pf_str << table_factories[ruleset_name]->PrintTables();
if (prolog_place == "pf_file_after_tables")
printProlog(pf_str, pre_hook);
} else
{
pf_str << table_factories[ruleset_name]->PrintTables();
}
pf_str << strm->str();
pf_file.close();
} else } else
{ {
// clear() calls destructors of all elements in the container abort(string(" Failed to open file ") +
table_factories.clear(); fw_file_name.toStdString() +
generated_scripts.clear(); " for writing");
abort(string(" Failed to open file ") + file_name + " for writing");
} }
} }
/* catch (FatalErrorInSingleRuleCompileMode &ex)
* assemble the script and then perhaps post-process it if needed
*/
QString script_buffer = assembleFwScript(
cluster, fw, !cluster_id.empty(), oscnf.get());
// clear() calls destructors of all elements in the container
table_factories.clear();
generated_scripts.clear();
info("Output file name: " + fw_file_name.toStdString());
QFile fw_file(fw_file_name);
if (fw_file.open(QIODevice::WriteOnly))
{ {
QTextStream fw_str(&fw_file); return getErrors("");
fw_str << script_buffer;
fw_file.close();
fw_file.setPermissions(QFile::ReadOwner | QFile::WriteOwner |
QFile::ReadGroup | QFile::ReadOther |
QFile::ExeOwner |
QFile::ExeGroup |
QFile::ExeOther );
info(" Compiled successfully");
} else
{
abort(string(" Failed to open file ") +
fw_file_name.toStdString() +
" for writing");
} }
return ""; return "";

View File

@ -1,15 +1,28 @@
#!/usr/bin/perl #!/bin/sh
$XMLFILE=@ARGV[0];
$DIFFCMD="diff -U 0 -u -b -B -I \"! Generated\" "; DIFFCMD="diff -C 5 -c -b -B -w -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipt v' -I 'Can not find file' -I '====' -I 'log '"
while (<>) { for f in $(ls *.fw.orig)
$str=$_; do
while ( $str=~ /<Firewall / ) { V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
$str=~ /<Firewall [^>]+name="([^"]*).*$"/; echo "echo \"$V\" | cut -c1-72"
$fw=$1; new_f=$(echo $f | sed 's/.org//')
printf "$DIFFCMD %s.fw.orig %s.fw\n",$fw,$fw; echo "$DIFFCMD $f $new_f"
$str=~ s/^.*<Firewall [^>]+name="$fw"[^>]+>//; done
} exit 0
run_diffs_for_file() {
xmlfile=$1
folder=$2
fwbedit list -f $xmlfile -o $folder -c -F%name% | sort | while read fwobj; do
V="$fwobj <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo "echo \"$V\" | cut -c1-72"
echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw"
done
} }
run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls
# run_diffs_for_file cluster-tests.fwb /User/Clusters

View File

@ -1,17 +1,22 @@
#!/usr/bin/perl #!/bin/sh
$XMLFILE=@ARGV[0]; XMLFILE="objects-for-regression-tests.fwb"
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \
sort | while read fwobj
do
echo "echo"
echo "echo \"============================ $fwobj\""
echo "fwb_iosacl -v -f $XMLFILE -xt $fwobj"
done
exit 0
while (<>) { XMLFILE="cluster-tests.fwb"
$str=$_; fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \
while ( $str=~ /<Firewall / ) { sort | while read fwobj
$str=~ /<Firewall [^>]+name="([^"]*).*$"/; do
$fw=$1; echo "echo"
printf "echo ====================== $fw =========================================\n"; echo "echo \"============================ $fwobj\""
printf "fwb_iosacl -xt -v -f $XMLFILE $fw\n"; echo "fwb_iosacl -v -f $XMLFILE -xt -xc $fwobj"
$str=~ s/^.*<Firewall [^>]+name="$fw"[^>]+>//; done
}
}

View File

@ -1,12 +1,12 @@
#!/bin/sh #!/bin/sh
XMLFILE=$1 DIFFCMD="diff -C 5 -c -b -B -w -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipf v' -I 'Can not find file' -I '====' -I 'log '"
DIFFCMD="diff -C 1 -c -b -B -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipt v' -I 'Can not find file' -I '====' -I 'log '"
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do for f in $(ls *.fw.orig *.conf.orig)
echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" do
echo "$DIFFCMD ${fwobj}-ipf.conf.orig ${fwobj}-ipf.conf" V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo "$DIFFCMD ${fwobj}-nat.conf.orig ${fwobj}-nat.conf" echo "echo \"$V\" | cut -c1-72"
new_f=$(echo $f | sed 's/.org//')
echo "$DIFFCMD $f $new_f"
done done

View File

@ -1,10 +1,22 @@
#!/bin/sh #!/bin/sh
XMLFILE=$1 XMLFILE="objects-for-regression-tests.fwb"
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do sort | while read fwobj
do
echo "echo" echo "echo"
echo "echo \"============================ $fwobj\"" echo "echo \"============================ $fwobj\""
echo "fwb_ipf -v -f $XMLFILE -xt $fwobj" echo "fwb_ipf -v -f $XMLFILE -xt $fwobj"
done done
exit 0
XMLFILE="cluster-tests.fwb"
fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \
sort | while read fwobj
do
echo "echo"
echo "echo \"============================ $fwobj\""
echo "fwb_ipf -v -f $XMLFILE -xt -xc $fwobj"
done

View File

@ -1,10 +1,28 @@
#!/bin/sh #!/bin/sh
XMLFILE=$1 DIFFCMD="diff -C 5 -c -b -B -w -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipt v' -I 'Can not find file' -I '====' -I 'log '"
DIFFCMD="diff -C 5 -c -b -B -I \"# Generated\" -I 'Activating ' -I '# Firewall Builder fwb_ipt v' -I 'Can not find file' -I '====' -I 'log '"
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do for f in $(ls *.fw.orig)
do
V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo "echo \"$V\" | cut -c1-72"
new_f=$(echo $f | sed 's/.org//')
echo "$DIFFCMD $f $new_f"
done
exit 0
run_diffs_for_file() {
xmlfile=$1
folder=$2
fwbedit list -f $xmlfile -o $folder -c -F%name% | sort | while read fwobj; do
V="$fwobj <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"
echo "echo \"$V\" | cut -c1-72"
echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw"
done done
}
run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls
# run_diffs_for_file cluster-tests.fwb /User/Clusters

View File

@ -1,10 +1,22 @@
#!/bin/sh #!/bin/sh
XMLFILE=$1 XMLFILE="objects-for-regression-tests.fwb"
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | \
fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do sort | while read fwobj
do
echo "echo" echo "echo"
echo "echo \"============================ $fwobj\"" echo "echo \"============================ $fwobj\""
echo "fwb_ipfw -v -f $XMLFILE -xt $fwobj" echo "fwb_ipfw -v -f $XMLFILE -xt $fwobj"
done done
exit 0
XMLFILE="cluster-tests.fwb"
fwbedit list -f $XMLFILE -o /User/Clusters -c -F%name% | \
sort | while read fwobj
do
echo "echo"
echo "echo \"============================ $fwobj\""
echo "fwb_ipfw -v -f $XMLFILE -xt -xc $fwobj"
done