From 301a4ed8648f63d0c0ebb671e5f38ff8548f0a0c Mon Sep 17 00:00:00 2001 From: Vadim Kurland Date: Fri, 13 Nov 2009 19:30:17 +0000 Subject: [PATCH] fixes #614 Use FatalErrorInSingleRuleCompleMode in all compilers --- build_num | 2 +- src/cisco_lib/CompilerDriver_iosacl_run.cpp | 367 ++++---- src/cisco_lib/CompilerDriver_pix_run.cpp | 61 +- src/compiler_lib/CompilerDriver.cpp | 42 +- src/iptlib/CompilerDriver_ipt_run.cpp | 969 ++++++++++---------- src/pflib/CompilerDriver_ipf_run.cpp | 384 ++++---- src/pflib/CompilerDriver_ipfw_run.cpp | 332 +++---- src/pflib/CompilerDriver_pf_run.cpp | 649 ++++++------- test/iosacl/quick-cmp.sh | 35 +- test/iosacl/run.all | 31 +- test/ipf/quick-cmp.sh | 14 +- test/ipf/run.all | 18 +- test/ipfw/quick-cmp.sh | 24 +- test/ipfw/run.all | 18 +- 14 files changed, 1535 insertions(+), 1411 deletions(-) diff --git a/build_num b/build_num index aedf35194..115e25080 100644 --- a/build_num +++ b/build_num @@ -1 +1 @@ -#define BUILD_NUM 1747 +#define BUILD_NUM 1748 diff --git a/src/cisco_lib/CompilerDriver_iosacl_run.cpp b/src/cisco_lib/CompilerDriver_iosacl_run.cpp index a0b864aad..dc5d9065a 100644 --- a/src/cisco_lib/CompilerDriver_iosacl_run.cpp +++ b/src/cisco_lib/CompilerDriver_iosacl_run.cpp @@ -135,217 +135,224 @@ string CompilerDriver_iosacl::run(const std::string &cluster_id, objdb->findInIndex(objdb->getIntId(firewall_id))); assert(fw); - // Copy rules from the cluster object - 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()) + try { - // incorrect version. This could have happened if user converted - // firewall platform. See bug #2662290 - fw->setStr("version", "12.1"); - } + // Copy rules from the cluster object + populateClusterElements(cluster, fw); - bool ios_acl_basic = options->getBool("ios_acl_basic"); - 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"); + commonChecks2(cluster, fw); - if ( !ios_acl_basic && - !ios_acl_no_clear && - !ios_acl_substitution ) - { - if ( ios_add_clear_statements ) options->setBool("ios_acl_basic",true); - else options->setBool("ios_acl_no_clear",true); - } + // 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(); - std::auto_ptr oscnf(new OSConfigurator_ios(objdb, fw, false)); + QString ofname = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); - oscnf->prolog(); - oscnf->processFirewallOptions(); + FWOptions* options = fw->getOptionsObject(); - list all_policies = fw->getByType(Policy::TYPENAME); - int policy_rules_count = 0; + string fwvers = fw->getStr("version"); + if (fwvers == "") fw->setStr("version", "12.1"); + if (fwvers == "12.x") fw->setStr("version", "12.1"); - vector ipv4_6_runs; - - 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::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::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p) + 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()) { - Policy *policy = Policy::cast(*p); - if (policy->matchingAddressFamily(policy_af)) policy_count++; - } - if (policy_count) - { - std::auto_ptr prep(new Preprocessor(objdb, fw, false)); - prep->compile(); + // incorrect version. This could have happened if user converted + // firewall platform. See bug #2662290 + fw->setStr("version", "12.1"); } - for (list::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p ) + bool ios_acl_basic = options->getBool("ios_acl_basic"); + 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 oscnf(new OSConfigurator_ios(objdb, fw, false)); - PolicyCompiler_iosacl c(objdb, fw, ipv6_policy, oscnf.get()); + oscnf->prolog(); + oscnf->processFirewallOptions(); - c.setSourceRuleSet( policy ); - c.setRuleSetName(policy->getName()); + list all_policies = fw->getByType(Policy::TYPENAME); + int policy_rules_count = 0; - 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 ); + vector ipv4_6_runs; - 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::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::iterator p=all_policies.begin(); + p!=all_policies.end(); ++p) { - c.compile(); - c.epilog(); + Policy *policy = Policy::cast(*p); + if (policy->matchingAddressFamily(policy_af)) policy_count++; + } + if (policy_count) + { + std::auto_ptr prep(new Preprocessor(objdb, fw, false)); + prep->compile(); + } - if (!single_rule_compile_on) + for (list::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"; - policy_script += "! ================ IPv6\n"; - policy_script += "\n\n"; - } else - { - policy_script += "\n\n"; - policy_script += "! ================ IPv4\n"; - policy_script += "\n\n"; + if (ipv6_policy) + { + policy_script += "\n\n"; + policy_script += "! ================ IPv6\n"; + policy_script += "\n\n"; + } else + { + policy_script += "\n\n"; + policy_script += "! ================ IPv4\n"; + policy_script += "\n\n"; + } } - } - if (c.haveErrorsAndWarnings()) - { - all_errors.push_back(c.getErrors("").c_str()); - } - policy_script += c.getCompiledScript(); + if (c.haveErrorsAndWarnings()) + { + all_errors.push_back(c.getErrors("").c_str()); + } + policy_script += c.getCompiledScript(); - } else - info(" Nothing to compile in Policy"); - } + } else + info(" Nothing to compile in Policy"); + } - if (!ipv6_policy) - { - list 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 ) + if (!ipv6_policy) { - r.compile(); - r.epilog(); + list all_routing = fw->getByType(Routing::TYPENAME); + 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(); - } else - info(" Nothing to compile in Routing"); + if (r.haveErrorsAndWarnings()) + { + 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"); } } - - if (haveErrorsAndWarnings()) + catch (FatalErrorInSingleRuleCompileMode &ex) { - 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"); + return getErrors(""); } return ""; diff --git a/src/cisco_lib/CompilerDriver_pix_run.cpp b/src/cisco_lib/CompilerDriver_pix_run.cpp index 6a62c540d..688f16ee8 100644 --- a/src/cisco_lib/CompilerDriver_pix_run.cpp +++ b/src/cisco_lib/CompilerDriver_pix_run.cpp @@ -557,41 +557,38 @@ string CompilerDriver_pix::run(const std::string &cluster_id, script_buffer = assembleFwScript( 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) { - if (haveErrorsAndWarnings()) - { - 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 getErrors(""); } return ""; diff --git a/src/compiler_lib/CompilerDriver.cpp b/src/compiler_lib/CompilerDriver.cpp index 3b12a09ed..53f2a4d40 100644 --- a/src/compiler_lib/CompilerDriver.cpp +++ b/src/compiler_lib/CompilerDriver.cpp @@ -266,16 +266,39 @@ void CompilerDriver::commonChecks(Firewall *fw) if (ofname.empty()) continue; if (output_file_names.count(ofname) > 0) { - string err = - string("Member firewalls use the same output file name ") + - ofname; - throw FWException(err); + QString err("Member firewalls use the same output file name %1"); + error(cluster, NULL, NULL, err.arg(ofname.c_str()).toStdString()); } 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) { 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'."); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } /* 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."); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } 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"); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } for (list::iterator j = all_addr.begin(); @@ -411,6 +437,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw) .arg(FWObjectDatabase::getStringId( iface->getId()).c_str()) .arg(ip_addr->toString().c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } } } @@ -430,7 +457,10 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw) QString err; if (!int_prop->validateInterface(parent, iface, true, err)) + { abort(fw, NULL, NULL, err.toStdString()); + throw FatalErrorInSingleRuleCompileMode(); + } string interface_type = iface->getOptionsObject()->getStr("type"); if (interface_type.empty()) interface_type = "ethernet"; @@ -467,6 +497,7 @@ void CompilerDriver::commonChecks2(Cluster *cluster, Firewall *fw) ); abort(fw, NULL, NULL, err.arg(iface->getName().c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } } } @@ -977,6 +1008,7 @@ int CompilerDriver::checkCluster(Cluster* cluster) { /* No configured cluster interface found */ abort(cluster, NULL, NULL, "The cluster has no interfaces."); + throw FatalErrorInSingleRuleCompileMode(); } for (; cluster_ifaces != cluster_ifaces.end(); ++cluster_ifaces) @@ -991,6 +1023,7 @@ int CompilerDriver::checkCluster(Cluster* cluster) { QString err("Found duplicate cluster interface %1"); abort(cluster, NULL, NULL, err.arg(iface_name.c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } const InetAddr *other_iface_address = Interface::cast(*other_ifaces)->getAddressPtr(); 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"); abort(cluster, NULL, NULL, err.arg(iface_address->toString().c_str()).toStdString()); + throw FatalErrorInSingleRuleCompileMode(); } } } diff --git a/src/iptlib/CompilerDriver_ipt_run.cpp b/src/iptlib/CompilerDriver_ipt_run.cpp index 0e046065e..005b23ecc 100644 --- a/src/iptlib/CompilerDriver_ipt_run.cpp +++ b/src/iptlib/CompilerDriver_ipt_run.cpp @@ -113,580 +113,589 @@ string CompilerDriver_ipt::run(const std::string &cluster_id, objdb->findInIndex(objdb->getIntId(firewall_id))); 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 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( - new OSConfigurator_ipcop(objdb , fw, false)); - } - - if (os_family == "linux24") - oscnf = std::auto_ptr( - new OSConfigurator_linux24(objdb , fw, false)); - - if (os_family == "secuwall") - oscnf = std::auto_ptr( - 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 all_policies = fw->getByType(Policy::TYPENAME); - list 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 minus_n_commands_filter; - std::map minus_n_commands_mangle; - std::map minus_n_commands_nat; - - vector ipv4_6_runs; string generated_script; - 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") + try { - if (ipv4_run) ipv4_6_runs.push_back(AF_INET); - if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); - } + // Copy rules from the cluster object + populateClusterElements(cluster, fw); - 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); - } + commonChecks2(cluster, fw); - for (vector::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) - { - int policy_af = *i; - bool ipv6_policy = (policy_af == AF_INET6); + 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"); - /* - 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(); + FWOptions* options = fw->getOptionsObject(); + string s; - /* - 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. - */ + // 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(); - // Count rules for each address family - int nat_count = 0; - int policy_count = 0; + fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); - for (list::iterator p=all_nat.begin(); - p!=all_nat.end(); ++p) + if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" && + fw->getOptionsObject()->getBool("use_iptables_restore")) { - NAT *nat = NAT::cast(*p); - if (nat->matchingAddressFamily(policy_af)) nat_count++; + abort("Prolog place \"after policy reset\" can not be used" + " when policy is activated with iptables-restore"); } - for (list::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p) + 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 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); - if (policy->matchingAddressFamily(policy_af)) policy_count++; + prolog_done = true; + epilog_done = true; } - if (nat_count || policy_count) + string os_variant = DISTRO; + +/* minimal sanity checking */ + if (os_family == "ipcop") { - Preprocessor* prep = new Preprocessor( - objdb , fw, ipv6_policy); - if (inTestMode()) prep->setTestMode(); - if (inEmbeddedMode()) prep->setEmbeddedMode(); - prep->compile(); - delete prep; + 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( + new OSConfigurator_ipcop(objdb , fw, false)); } - ostringstream automaitc_rules_stream; - ostringstream filter_rules_stream; - ostringstream mangle_rules_stream; - ostringstream nat_rules_stream; + if (os_family == "linux24") + oscnf = std::auto_ptr( + new OSConfigurator_linux24(objdb , fw, false)); - bool empty_output = true; + if (os_family == "secuwall") + oscnf = std::auto_ptr( + new OSConfigurator_secuwall(objdb , fw, false)); - // First, process branch NAT rulesets, then top NAT ruleset - - NAT *top_nat = NULL; - for (list::iterator p=all_nat.begin(); - p!=all_nat.end(); ++p) + if (oscnf.get()==NULL) { - NAT *nat = NAT::cast(*p); - if (!nat->matchingAddressFamily(policy_af)) continue; - if (nat->isTop()) + 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 all_policies = fw->getByType(Policy::TYPENAME); + list 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 minus_n_commands_filter; + std::map minus_n_commands_mangle; + std::map minus_n_commands_nat; + + vector 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::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::iterator p=all_nat.begin(); + p!=all_nat.end(); ++p) { - top_nat = nat; - continue; + NAT *nat = NAT::cast(*p); + if (nat->matchingAddressFamily(policy_af)) nat_count++; } - if (! processNatRuleSet( + + for (list::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::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, - nat, + top_nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; - } - if (top_nat && - ! 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::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p ) + for (int all_top = 0; all_top < 2; ++all_top) { - Policy *policy = Policy::cast(*p); - if (!policy->matchingAddressFamily(policy_af)) continue; + for (list::iterator p=all_policies.begin(); + 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 == 1) continue; + if (policy->isTop() && all_top == 0) continue; + if (!policy->isTop() && all_top == 1) continue; - if (! processPolicyRuleSet( - fw, - policy, - single_rule_id, - filter_rules_stream, - mangle_rules_stream, - automaitc_rules_stream, - oscnf.get(), - policy_af, - minus_n_commands_filter, - minus_n_commands_mangle)) empty_output = false; + if (! processPolicyRuleSet( + fw, + policy, + single_rule_id, + filter_rules_stream, + mangle_rules_stream, + automaitc_rules_stream, + oscnf.get(), + policy_af, + minus_n_commands_filter, + minus_n_commands_mangle)) empty_output = false; + } } - } - if (!empty_output && !single_rule_compile_on) - { - if (ipv6_policy) + if (!empty_output && !single_rule_compile_on) { - have_ipv6 = true; - generated_script += "\n\n"; - generated_script += "# ================ IPv6\n"; - generated_script += "\n\n"; - } else - { - generated_script += "\n\n"; - generated_script += "# ================ IPv4\n"; - generated_script += "\n\n"; + if (ipv6_policy) + { + have_ipv6 = true; + generated_script += "\n\n"; + generated_script += "# ================ IPv6\n"; + generated_script += "\n\n"; + } else + { + 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, - automaitc_rules_stream.str(), - nat_rules_stream.str(), - mangle_rules_stream.str(), - filter_rules_stream.str(), - ipv6_policy); - } + std::auto_ptr routing_compiler( + new RoutingCompiler_ipt(objdb, fw, false, oscnf.get())); - std::auto_ptr routing_compiler( - new RoutingCompiler_ipt(objdb, fw, false, oscnf.get())); - - 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 ) + RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); + if (routing) { - routing_compiler->compile(); - routing_compiler->epilog(); + 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->epilog(); + } + + if (routing_compiler->haveErrorsAndWarnings()) + all_errors.push_back(routing_compiler->getErrors("").c_str()); } - if (routing_compiler->haveErrorsAndWarnings()) - all_errors.push_back(routing_compiler->getErrors("").c_str()); - } - - if (single_rule_compile_on) - { - // in single rule compile mode just return the result Note - // that we do not return all_errors because all compilers - // include errors and warnings with generated code for each - // rule. CompilerDriver errors, however, need to be added on - // top. - return - getErrors("") + + if (single_rule_compile_on) + { + // in single rule compile mode just return the result Note + // that we do not return all_errors because all compilers + // include errors and warnings with generated code for each + // rule. CompilerDriver errors, however, need to be added on + // top. + return + getErrors("") + // all_errors.join("\n").toStdString() + - generated_script + routing_compiler->getCompiledScript(); - } + generated_script + routing_compiler->getCompiledScript(); + } - if (haveErrorsAndWarnings()) - { - all_errors.push_front(getErrors("").c_str()); - } + if (haveErrorsAndWarnings()) + { + all_errors.push_front(getErrors("").c_str()); + } /* * These store generated configuration internally, extract it later using * OSConfiguration::getGeneratedFiles(); */ - oscnf->printChecksForRunTimeMultiAddress(); - oscnf->processFirewallOptions(); + oscnf->printChecksForRunTimeMultiAddress(); + oscnf->processFirewallOptions(); /* * now write generated scripts to files */ - char *timestr; - time_t tm; - struct tm *stm; + char *timestr; + time_t tm; + struct tm *stm; - tm = time(NULL); - stm = localtime(&tm); - timestr = strdup(ctime(&tm)); - timestr[strlen(timestr)-1] = '\0'; + tm = time(NULL); + stm = localtime(&tm); + timestr = strdup(ctime(&tm)); + timestr[strlen(timestr)-1] = '\0'; #ifdef _WIN32 - char* user_name = getenv("USERNAME"); + char* user_name = getenv("USERNAME"); #else - struct passwd *pwd = getpwuid(getuid()); - assert(pwd); - char *user_name = pwd->pw_name; + struct passwd *pwd = getpwuid(getuid()); + assert(pwd); + char *user_name = pwd->pw_name; #endif - if (user_name == NULL) - { - user_name = getenv("LOGNAME"); 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 * run on Linksys device with sveasoft firmware */ - Configlet script_skeleton(fw, "linux24", "script_skeleton"); - script_skeleton.removeComments(); + Configlet script_skeleton(fw, "linux24", "script_skeleton"); + script_skeleton.removeComments(); - QString script_buffer; - QTextStream script(&script_buffer, QIODevice::WriteOnly); - script_buffer = ""; + QString script_buffer; + QTextStream script(&script_buffer, QIODevice::WriteOnly); + 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 << "export PATH" << "\n"; + script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n"; + script << "export PATH" << "\n"; - script_skeleton.setVariable("path", script_buffer); - script_buffer = ""; + script_skeleton.setVariable("path", script_buffer); + script_buffer = ""; - Configlet script_constants(fw, "linux24", "constants"); - script_skeleton.setVariable("constants", script_constants.expand()); + Configlet script_constants(fw, "linux24", "constants"); + script_skeleton.setVariable("constants", script_constants.expand()); - /* - * print definitions for variables IPTABLES, IP, LOGGER. Some - * 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 - * strings entered by user in the GUI and stored in firewall - * options. - */ - script_skeleton.setVariable("tools", - oscnf->printPathForAllTools(os_variant).c_str()); - script_skeleton.setVariable("shell_functions", - oscnf->printShellFunctions().c_str()); - if (supports_prolog_epilog) - { - //script_skeleton.setVariable("prolog_epilog", - // oscnf->printPrologEpilogFunctions().c_str()); + /* + * print definitions for variables IPTABLES, IP, LOGGER. Some + * 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 + * strings entered by user in the GUI and stored in firewall + * options. + */ + script_skeleton.setVariable("tools", + oscnf->printPathForAllTools(os_variant).c_str()); + script_skeleton.setVariable("shell_functions", + oscnf->printShellFunctions().c_str()); + if (supports_prolog_epilog) + { + //script_skeleton.setVariable("prolog_epilog", + // 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( - "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( - "configure_interfaces", indent(4, QString(ostr.str().c_str()))); + "configure_interfaces", indent(4, QString(ostr.str().c_str()))); - // verify_interfaces checks bridge interfaces so run it - // after those have been created - if (options->getBool("verify_interfaces")) - { - list l2=fw->getByType(Interface::TYPENAME); - if (l2.empty() ) + // verify_interfaces checks bridge interfaces so run it + // after those have been created + if (options->getBool("verify_interfaces")) + { + list l2=fw->getByType(Interface::TYPENAME); + 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()); - 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"); - if (prolog_place == "") prolog_place="top"; + string prolog_place = fw->getOptionsObject()->getStr("prolog_place"); + if (prolog_place == "") prolog_place="top"; - /* there is no way to stick prolog commands between iptables - * reset and iptables rules if we use iptables-restore to - * activate policy. Therefore, if prolog needs to be ran after - * iptables flush and we use iptables-restore, we run prolog - * on top of the script. - */ - if (!prolog_done && - (prolog_place == "top" || - (prolog_place == "after_flush" && - fw->getOptionsObject()->getBool("use_iptables_restore")))) - { - script_skeleton.setVariable("prolog_top", 1); - script_skeleton.setVariable("prolog_after_interfaces", 0); - script_skeleton.setVariable("prolog_after_flush", 0); - prolog_done = true; - } + /* there is no way to stick prolog commands between iptables + * reset and iptables rules if we use iptables-restore to + * activate policy. Therefore, if prolog needs to be ran after + * iptables flush and we use iptables-restore, we run prolog + * on top of the script. + */ + if (!prolog_done && + (prolog_place == "top" || + (prolog_place == "after_flush" && + fw->getOptionsObject()->getBool("use_iptables_restore")))) + { + script_skeleton.setVariable("prolog_top", 1); + script_skeleton.setVariable("prolog_after_interfaces", 0); + script_skeleton.setVariable("prolog_after_flush", 0); + prolog_done = true; + } - if (!prolog_done && prolog_place == "after_interfaces") - { - script_skeleton.setVariable("prolog_top", 0); - script_skeleton.setVariable("prolog_after_interfaces", 1); - script_skeleton.setVariable("prolog_after_flush", 0); - prolog_done = true; - } + if (!prolog_done && prolog_place == "after_interfaces") + { + script_skeleton.setVariable("prolog_top", 0); + script_skeleton.setVariable("prolog_after_interfaces", 1); + script_skeleton.setVariable("prolog_after_flush", 0); + prolog_done = true; + } - if (!prolog_done && prolog_place == "after_flush") - { - script_skeleton.setVariable("prolog_top", 0); - script_skeleton.setVariable("prolog_after_interfaces", 0); - script_skeleton.setVariable("prolog_after_flush", 1); - prolog_done = true; - } + if (!prolog_done && prolog_place == "after_flush") + { + script_skeleton.setVariable("prolog_top", 0); + script_skeleton.setVariable("prolog_after_interfaces", 0); + script_skeleton.setVariable("prolog_after_flush", 1); + prolog_done = true; + } - script_skeleton.setVariable("load_modules", - oscnf->generateCodeForProtocolHandlers().c_str()); - script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"\"nat\"":""); + script_skeleton.setVariable("load_modules", + oscnf->generateCodeForProtocolHandlers().c_str()); + script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"\"nat\"":""); - script_skeleton.setVariable("ip_forward_commands", - oscnf->printIPForwardingCommands().c_str()); + script_skeleton.setVariable("ip_forward_commands", + oscnf->printIPForwardingCommands().c_str()); - /* - * script body begins here - */ - script_buffer = ""; + /* + * script body begins here + */ + script_buffer = ""; - if (oscnf->haveErrorsAndWarnings()) - { - all_errors.push_back(oscnf->getErrors("").c_str()); + if (oscnf->haveErrorsAndWarnings()) + { + all_errors.push_back(oscnf->getErrors("").c_str()); // script << "# OS configuration errors and warnings:" << "\n"; // 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 file_list = oscnf->getGeneratedFiles(); - if (!file_list.empty()) - { - info(" Adding additional files to manifest"); - list::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 file_list = oscnf->getGeneratedFiles(); + if (!file_list.empty()) + { + info(" Adding additional files to manifest"); + list::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"); + } + } - - 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)) + catch (FatalErrorInSingleRuleCompileMode &ex) { - 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"); + return getErrors(""); } return ""; diff --git a/src/pflib/CompilerDriver_ipf_run.cpp b/src/pflib/CompilerDriver_ipf_run.cpp index 79eab9e51..2d330f2c7 100644 --- a/src/pflib/CompilerDriver_ipf_run.cpp +++ b/src/pflib/CompilerDriver_ipf_run.cpp @@ -182,252 +182,254 @@ string CompilerDriver_ipf::run(const std::string &cluster_id, objdb->findInIndex(objdb->getIntId(firewall_id))); assert(fw); - // Copy rules from the cluster object - 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() != ".") + try { - ipf_file_name = finfo.path() + "/" + ipf_file_name; - nat_file_name = finfo.path() + "/" + nat_file_name; - } + // Copy rules from the cluster object + populateClusterElements(cluster, fw); - QString remote_ipf_name = options->getStr("ipf_conf_file_name_on_firewall").c_str(); - if (remote_ipf_name.isEmpty()) remote_ipf_name = ipf_file_name; + commonChecks2(cluster, fw); - 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; + FWOptions* options = fw->getOptionsObject(); + 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"); - if (firewall_dir=="") firewall_dir = "/etc/fw"; + fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); - bool debug = options->getBool("debug"); - string ipf_dbg = (debug)?"-v":""; + 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; + nat_file_name = finfo.path() + "/" + nat_file_name; + } - std::auto_ptr prep(new Preprocessor(objdb , fw, false)); - prep->compile(); + QString remote_ipf_name = options->getStr("ipf_conf_file_name_on_firewall").c_str(); + 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 prep(new Preprocessor(objdb , fw, false)); + prep->compile(); /* * Process firewall options, build OS network configuration script */ - std::auto_ptr oscnf; - string host_os = fw->getStr("host_OS"); - string family=Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); - if ( host_os == "solaris" ) - oscnf = std::auto_ptr(new OSConfigurator_solaris(objdb , fw, false)); + std::auto_ptr oscnf; + string host_os = fw->getStr("host_OS"); + string family=Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); + if ( host_os == "solaris" ) + oscnf = std::auto_ptr(new OSConfigurator_solaris(objdb , fw, false)); - if ( host_os == "openbsd") - oscnf = std::auto_ptr(new OSConfigurator_openbsd(objdb , fw, false)); + if ( host_os == "openbsd") + oscnf = std::auto_ptr(new OSConfigurator_openbsd(objdb , fw, false)); - if ( host_os == "freebsd") - oscnf = std::auto_ptr(new OSConfigurator_freebsd(objdb , fw, false)); + if ( host_os == "freebsd") + oscnf = std::auto_ptr(new OSConfigurator_freebsd(objdb , fw, false)); - if (oscnf.get()==NULL) - { - abort("Unrecognized host OS " + host_os + " (family " + family + ")"); - return ""; - } + if (oscnf.get()==NULL) + { + abort("Unrecognized host OS " + host_os + " (family " + family + ")"); + return ""; + } - oscnf->prolog(); + oscnf->prolog(); - list all_policies = fw->getByType(Policy::TYPENAME); - list all_nat = fw->getByType(NAT::TYPENAME); + list all_policies = fw->getByType(Policy::TYPENAME); + list 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.setRuleSetName(policy->getName()); + c.setSourceRuleSet(Policy::cast(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(); + 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(); - if ( c.prolog() > 0 ) - { - have_filter = true; - c.compile(); - c.epilog(); - } + if ( c.prolog() > 0 ) + { + have_filter = true; + c.compile(); + 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.setRuleSetName(nat->getName()); + n.setSourceRuleSet(NAT::cast(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(); + 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(); - if ( n.prolog() > 0 ) - { - have_nat = true; - n.compile(); - n.epilog(); - } + if ( n.prolog() > 0 ) + { + have_nat = true; + n.compile(); + n.epilog(); + } - if (haveErrorsAndWarnings()) - { - all_errors.push_front(getErrors("").c_str()); - } + if (haveErrorsAndWarnings()) + { + 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 (c.haveErrorsAndWarnings()) + QFile ipf_file(ipf_file_name); + if (ipf_file.open(QIODevice::WriteOnly)) { - all_errors.push_back(c.getErrors("").c_str()); - // ostr << "# Policy compiler errors and warnings:" - // << endl; - // ostr << c.getErrors("# "); + QTextStream ipf_str(&ipf_file); + if (c.haveErrorsAndWarnings()) + { + 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 (n.haveErrorsAndWarnings()) + QFile nat_file(nat_file_name); + if (nat_file.open(QIODevice::WriteOnly)) { - all_errors.push_back(n.getErrors("").c_str()); - // ostr << "# NAT compiler errors and warnings:" - // << endl; - // ostr << n.getErrors("# "); + 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::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 - all_errors.join("\n").toStdString() + - ostr.str(); - } +/* + * assemble the script and then perhaps post-process it if needed + */ + QString script_buffer = assembleFwScript( + cluster, fw, !cluster_id.empty(), oscnf.get()); - if (have_filter) - { - QFile ipf_file(ipf_file_name); - if (ipf_file.open(QIODevice::WriteOnly)) + info("Output file name: " + fw_file_name.toStdString()); + + QFile fw_file(fw_file_name); + if (fw_file.open(QIODevice::WriteOnly)) { - QTextStream ipf_str(&ipf_file); - if (c.haveErrorsAndWarnings()) - { - 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"); - } - - 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 | + 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 ") + - nat_file_name.toStdString() + + fw_file_name.toStdString() + " 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())); } -/* - * 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)) + catch (FatalErrorInSingleRuleCompileMode &ex) { - 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 getErrors(""); } + return ""; } diff --git a/src/pflib/CompilerDriver_ipfw_run.cpp b/src/pflib/CompilerDriver_ipfw_run.cpp index 1f1cbf0f0..3c73ace57 100644 --- a/src/pflib/CompilerDriver_ipfw_run.cpp +++ b/src/pflib/CompilerDriver_ipfw_run.cpp @@ -129,214 +129,222 @@ string CompilerDriver_ipfw::run(const std::string &cluster_id, objdb->findInIndex(objdb->getIntId(firewall_id))); assert(fw); - // Copy rules from the cluster object - populateClusterElements(cluster, fw); + try + { + // 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 - // firewall fw This happens when we compile a member of a cluster - current_firewall_name = fw->getName().c_str(); + // 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"); + fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); - string s; + string s; - string firewall_dir=options->getStr("firewall_dir"); - if (firewall_dir=="") firewall_dir="/etc/fw"; + string firewall_dir=options->getStr("firewall_dir"); + if (firewall_dir=="") firewall_dir="/etc/fw"; - bool debug=options->getBool("debug"); - string shell_dbg=(debug)?"-x":"" ; + bool debug=options->getBool("debug"); + string shell_dbg=(debug)?"-x":"" ; /* * Process firewall options, build OS network configuration script */ - std::auto_ptr oscnf; - string host_os = fw->getStr("host_OS"); - string family = Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); - if ( host_os == "macosx") - oscnf = std::auto_ptr(new OSConfigurator_macosx(objdb , fw, false)); + std::auto_ptr oscnf; + string host_os = fw->getStr("host_OS"); + string family = Resources::os_res[host_os]->Resources::getResourceStr("/FWBuilderResources/Target/family"); + if ( host_os == "macosx") + oscnf = std::auto_ptr(new OSConfigurator_macosx(objdb , fw, false)); - if ( host_os == "freebsd") - oscnf = std::auto_ptr(new OSConfigurator_freebsd(objdb , fw, false)); + if ( host_os == "freebsd") + oscnf = std::auto_ptr(new OSConfigurator_freebsd(objdb , fw, false)); - if (oscnf.get()==NULL) - { - abort("Unrecognized host OS " + host_os + " (family " + family + ")"); - return ""; - } - - oscnf->prolog(); - - - list all_policies = fw->getByType(Policy::TYPENAME); - vector 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::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::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p) + if (oscnf.get()==NULL) { - Policy *policy = Policy::cast(*p); - if (policy->matchingAddressFamily(policy_af)) policy_count++; + abort("Unrecognized host OS " + host_os + " (family " + family + ")"); + return ""; } - if (policy_count) + oscnf->prolog(); + + + list all_policies = fw->getByType(Policy::TYPENAME); + vector 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 prep(new Preprocessor(objdb , fw, ipv6_policy)); - if (inTestMode()) prep->setTestMode(); - if (inEmbeddedMode()) prep->setEmbeddedMode(); - prep->compile(); + if (ipv4_run) ipv4_6_runs.push_back(AF_INET); + if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } - ostringstream c_str; - bool empty_output = true; - - for (list::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p ) + if (options->getStr("ipv4_6_order") == "ipv6_first") { - Policy *policy = Policy::cast(*p); - string branch_name = policy->getName(); + if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); + if (ipv4_run) ipv4_6_runs.push_back(AF_INET); + } - if (!policy->matchingAddressFamily(policy_af)) continue; + for (vector::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); - 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(); + /* + 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. + */ - if ( (policy_rules_count=c.prolog()) > 0 ) + // Count rules for each address family + int policy_count = 0; + + for (list::iterator p=all_policies.begin(); + p!=all_policies.end(); ++p) { - c.compile(); - c.epilog(); + Policy *policy = Policy::cast(*p); + if (policy->matchingAddressFamily(policy_af)) policy_count++; + } - ipfw_rule_number = c.getIPFWNumber(); + if (policy_count) + { + std::auto_ptr 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::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_str << "# ================ Rule set " - << branch_name << endl; - if (c.haveErrorsAndWarnings()) + c.compile(); + c.epilog(); + + ipfw_rule_number = c.getIPFWNumber(); + + if (c.getCompiledScriptLength() > 0) { - all_errors.push_back(c.getErrors("").c_str()); - // c_str << "# Policy compiler errors and warnings:" - // << endl; - // c_str << c.getErrors("# "); + if (!single_rule_compile_on) + c_str << "# ================ Rule set " + << branch_name << endl; + 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 (ipv6_policy) + if (!empty_output && !single_rule_compile_on) { - generated_script += "\n\n"; - generated_script += "# ================ IPv6\n"; - generated_script += "\n\n"; - } else - { - generated_script += "\n\n"; - generated_script += "# ================ IPv4\n"; - generated_script += "\n\n"; + if (ipv6_policy) + { + generated_script += "\n\n"; + generated_script += "# ================ IPv6\n"; + generated_script += "\n\n"; + } else + { + 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()) - { - all_errors.push_front(getErrors("").c_str()); - } + if (single_rule_compile_on) + { + return + all_errors.join("\n").toStdString() + + generated_script; + } - if (single_rule_compile_on) - { - return - 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()); + 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 */ - QString script_buffer = assembleFwScript( - cluster, fw, !cluster_id.empty(), oscnf.get()); + QString script_buffer = assembleFwScript( + 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); - 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 ); + QFile fw_file(fw_file_name); + 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"); + info(" Compiled successfully"); + } else + { + abort(string(" Failed to open file ") + + fw_file_name.toStdString() + + " for writing"); + } } + catch (FatalErrorInSingleRuleCompileMode &ex) + { + return getErrors(""); + } + return ""; } diff --git a/src/pflib/CompilerDriver_pf_run.cpp b/src/pflib/CompilerDriver_pf_run.cpp index 5843dc3c2..04e7ce28c 100644 --- a/src/pflib/CompilerDriver_pf_run.cpp +++ b/src/pflib/CompilerDriver_pf_run.cpp @@ -209,399 +209,406 @@ string CompilerDriver_pf::run(const std::string &cluster_id, objdb->findInIndex(objdb->getIntId(firewall_id))); assert(fw); - // Copy rules from the cluster object - populateClusterElements(cluster, fw); + try + { + // 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 - // firewall fw This happens when we compile a member of a cluster - current_firewall_name = fw->getName().c_str(); + // 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"); + fw_file_name = determineOutputFileName(cluster, fw, !cluster_id.empty(), ".fw"); - string firewall_dir = options->getStr("firewall_dir"); - if (firewall_dir=="") firewall_dir="/etc/fw"; + string firewall_dir = options->getStr("firewall_dir"); + if (firewall_dir=="") firewall_dir="/etc/fw"; - string prolog_place = options->getStr("prolog_place"); - if (prolog_place.empty()) prolog_place = "fw_file"; // old default - string pre_hook = fw->getOptionsObject()->getStr("prolog_script"); + string prolog_place = options->getStr("prolog_place"); + if (prolog_place.empty()) prolog_place = "fw_file"; // old default + string pre_hook = fw->getOptionsObject()->getStr("prolog_script"); - bool debug = options->getBool("debug"); - string shell_dbg = (debug)?"set -x":"" ; - string pfctl_dbg = (debug)?"-v ":""; + bool debug = options->getBool("debug"); + string shell_dbg = (debug)?"set -x":"" ; + string pfctl_dbg = (debug)?"-v ":""; /* * Process firewall options, build OS network configuration script */ - std::auto_ptr oscnf; - string platform = fw->getStr("platform"); - string fw_version = fw->getStr("version"); - string host_os = fw->getStr("host_OS"); - string family = Resources::os_res[host_os - ]->Resources::getResourceStr("/FWBuilderResources/Target/family"); + std::auto_ptr oscnf; + string platform = fw->getStr("platform"); + string fw_version = fw->getStr("version"); + string host_os = fw->getStr("host_OS"); + string family = Resources::os_res[host_os + ]->Resources::getResourceStr("/FWBuilderResources/Target/family"); - if (host_os == "solaris") - oscnf = std::auto_ptr(new OSConfigurator_solaris( - objdb , fw, false)); + if (host_os == "solaris") + oscnf = std::auto_ptr(new OSConfigurator_solaris( + objdb , fw, false)); - if (host_os == "openbsd") - oscnf = std::auto_ptr(new OSConfigurator_openbsd( - objdb , fw, false)); + if (host_os == "openbsd") + oscnf = std::auto_ptr(new OSConfigurator_openbsd( + objdb , fw, false)); - if (host_os == "freebsd") - oscnf = std::auto_ptr(new OSConfigurator_freebsd( - objdb , fw, false)); + if (host_os == "freebsd") + oscnf = std::auto_ptr(new OSConfigurator_freebsd( + objdb , fw, false)); - 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 all_policies = fw->getByType(Policy::TYPENAME); - list all_nat = fw->getByType(NAT::TYPENAME); - - findImportedRuleSets(fw, all_policies); - - vector 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::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::iterator p=all_nat.begin(); - p!=all_nat.end(); ++p) + if (oscnf.get()==NULL) { - NAT *nat = NAT::cast(*p); - if (nat->matchingAddressFamily(policy_af)) nat_count++; + abort("Unrecognized host OS " + host_os + " (family " + family + ")"); + return ""; } - for (list::iterator p=all_policies.begin(); - p!=all_policies.end(); ++p) + oscnf->prolog(); + + string remote_fw_name = options->getStr("script_name_on_firewall"); + string remote_conf_name = options->getStr("conf_file_name_on_firewall"); + + list all_policies = fw->getByType(Policy::TYPENAME); + list all_nat = fw->getByType(NAT::TYPENAME); + + findImportedRuleSets(fw, all_policies); + + vector 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 (policy->matchingAddressFamily(policy_af)) policy_count++; + if (ipv4_run) ipv4_6_runs.push_back(AF_INET); + 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( - objdb , fw, ipv6_policy); - if (inTestMode()) prep->setTestMode(); - if (inEmbeddedMode()) prep->setEmbeddedMode(); - prep->compile(); - delete prep; + if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); + if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } - list redirect_rules_info; + ostringstream* main_str = new ostringstream(); - for (list::iterator p=all_nat.begin(); - p!=all_nat.end(); ++p ) + for (vector::iterator i=ipv4_6_runs.begin(); + 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(); - - if (ruleset_name.find("/*")!=string::npos) + for (list::iterator p=all_nat.begin(); + p!=all_nat.end(); ++p) { - QString err("The name of the policy ruleset %1" - " ends with '/*', assuming it is externally" - " controlled and skipping it."); - warning(fw, nat, NULL, - err.arg(ruleset_name.c_str()).toStdString()); - continue; + NAT *nat = NAT::cast(*p); + if (nat->matchingAddressFamily(policy_af)) nat_count++; } - if (nat->isTop()) - ruleset_name = "__main__"; - - if (table_factories.count(ruleset_name) == 0) + for (list::iterator p=all_policies.begin(); + p!=all_policies.end(); ++p) { - 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(), - 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 ) + if (nat_count || policy_count) { - 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(); + Preprocessor_pf* prep = new Preprocessor_pf( + objdb , fw, ipv6_policy); + if (inTestMode()) prep->setTestMode(); + if (inEmbeddedMode()) prep->setEmbeddedMode(); + prep->compile(); + delete prep; } - if (n.getCompiledScriptLength() > 0) + list redirect_rules_info; + + for (list::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 - // 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("# "); + QString err("The name of the policy ruleset %1" + " ends with '/*', assuming it is externally" + " controlled and skipping it."); + warning(fw, nat, NULL, + err.arg(ruleset_name.c_str()).toStdString()); + continue; } - *(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()); + if (nat->isTop()) + ruleset_name = "__main__"; - remote_conf_files[ruleset_name] = getRemoteConfFileName( - ruleset_name, - conf_files[ruleset_name], - remote_fw_name, - remote_conf_name); - - const list lst = - n.getRedirRulesInfo(); - redirect_rules_info.insert(redirect_rules_info.begin(), - lst.begin(), lst.end()); - } - - for (list::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()) + if (table_factories.count(ruleset_name) == 0) { - all_errors.push_back(c.getErrors("").c_str()); - *(generated_scripts[ruleset_name]) - << "# Policy compiler errors and warnings:" - << endl; - *(generated_scripts[ruleset_name]) << c.getErrors("# "); + table_factories[ruleset_name] = new fwcompiler::TableFactory(this); } - *(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 lst = + n.getRedirRulesInfo(); + redirect_rules_info.insert(redirect_rules_info.begin(), + lst.begin(), lst.end()); } - conf_files[ruleset_name] = getConfFileName( - ruleset_name, - current_firewall_name.toUtf8().constData(), - fw_file_name.toUtf8().constData()); + for (list::iterator p=all_policies.begin(); + p!=all_policies.end(); ++p ) + { + Policy *policy = Policy::cast(*p); + string ruleset_name = policy->getName(); - remote_conf_files[ruleset_name] = getRemoteConfFileName( - ruleset_name, - conf_files[ruleset_name], - remote_fw_name, - remote_conf_name); + 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()); + *(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()) - { - all_errors.push_front(getErrors("").c_str()); - } + if (haveErrorsAndWarnings()) + { + all_errors.push_front(getErrors("").c_str()); + } - if (single_rule_compile_on) - { - // in single rule compile mode just return the result - QString buffer; - QTextStream pf_str(&buffer); + if (single_rule_compile_on) + { + // in single rule compile mode just return the result + QString buffer; + QTextStream pf_str(&buffer); + for (map::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::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; - 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 table_factories.clear(); generated_scripts.clear(); - return - all_errors.join("\n").toStdString() + - buffer.toStdString(); - } + info("Output file name: " + fw_file_name.toStdString()); -/* - * now write generated scripts to files - */ - for (map::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)) + QFile fw_file(fw_file_name); + if (fw_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__") - { - 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(); + info(" Compiled successfully"); } 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"); + abort(string(" Failed to open file ") + + fw_file_name.toStdString() + + " 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 - 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)) + catch (FatalErrorInSingleRuleCompileMode &ex) { - 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 getErrors(""); } return ""; diff --git a/test/iosacl/quick-cmp.sh b/test/iosacl/quick-cmp.sh index cca8ce170..d4f939c2a 100755 --- a/test/iosacl/quick-cmp.sh +++ b/test/iosacl/quick-cmp.sh @@ -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 (<>) { - $str=$_; - while ( $str=~ /]+name="([^"]*).*$"/; - $fw=$1; - printf "$DIFFCMD %s.fw.orig %s.fw\n",$fw,$fw; - $str=~ s/^.*]+name="$fw"[^>]+>//; - } +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" +done } + + +run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls +# run_diffs_for_file cluster-tests.fwb /User/Clusters + diff --git a/test/iosacl/run.all b/test/iosacl/run.all index 1624d109e..08977ba03 100755 --- a/test/iosacl/run.all +++ b/test/iosacl/run.all @@ -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 (<>) { - $str=$_; - while ( $str=~ /]+name="([^"]*).*$"/; - $fw=$1; - printf "echo ====================== $fw =========================================\n"; - printf "fwb_iosacl -xt -v -f $XMLFILE $fw\n"; - $str=~ s/^.*]+name="$fw"[^>]+>//; - } -} - +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_iosacl -v -f $XMLFILE -xt -xc $fwobj" +done diff --git a/test/ipf/quick-cmp.sh b/test/ipf/quick-cmp.sh index 5a57224d2..d5e3cb86b 100755 --- a/test/ipf/quick-cmp.sh +++ b/test/ipf/quick-cmp.sh @@ -1,12 +1,12 @@ #!/bin/sh -XMLFILE=$1 -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 '" +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 '" -fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do - echo "$DIFFCMD ${fwobj}.fw.orig ${fwobj}.fw" - echo "$DIFFCMD ${fwobj}-ipf.conf.orig ${fwobj}-ipf.conf" - echo "$DIFFCMD ${fwobj}-nat.conf.orig ${fwobj}-nat.conf" +for f in $(ls *.fw.orig *.conf.orig) +do + V="$f <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" + echo "echo \"$V\" | cut -c1-72" + new_f=$(echo $f | sed 's/.org//') + echo "$DIFFCMD $f $new_f" done - diff --git a/test/ipf/run.all b/test/ipf/run.all index 1844ab186..0884d8e14 100755 --- a/test/ipf/run.all +++ b/test/ipf/run.all @@ -1,10 +1,22 @@ #!/bin/sh -XMLFILE=$1 - -fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do +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_ipf -v -f $XMLFILE -xt $fwobj" 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 + diff --git a/test/ipfw/quick-cmp.sh b/test/ipfw/quick-cmp.sh index dd5609090..d4f939c2a 100755 --- a/test/ipfw/quick-cmp.sh +++ b/test/ipfw/quick-cmp.sh @@ -1,10 +1,28 @@ #!/bin/sh -XMLFILE=$1 -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 '" +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 '" -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" done +} + + +run_diffs_for_file objects-for-regression-tests.fwb /User/Firewalls +# run_diffs_for_file cluster-tests.fwb /User/Clusters diff --git a/test/ipfw/run.all b/test/ipfw/run.all index 23cfd2a5a..9bf0e1520 100755 --- a/test/ipfw/run.all +++ b/test/ipfw/run.all @@ -1,10 +1,22 @@ #!/bin/sh -XMLFILE=$1 - -fwbedit list -f $XMLFILE -o /User/Firewalls -c -F%name% | sort | while read fwobj; do +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_ipfw -v -f $XMLFILE -xt $fwobj" 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 +