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:
parent
011ca8ca27
commit
301a4ed864
@ -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 "";
|
||||||
|
|||||||
@ -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 "";
|
||||||
|
|||||||
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 "";
|
||||||
|
|||||||
@ -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 "";
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 "";
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user