/* * This method builds and returns activation command * This method is used for all firewall platforms but PIX */ QString FirewallInstaller::getActivationCmd() { if (!cnf->activationCmd.isEmpty()) { return cnf->activationCmd; } FWOptions *fwopt = cnf->fwobj->getOptionsObject(); QString configlet_name = "installer_commands_"; if (cnf->user=="root") configlet_name += "root"; else configlet_name += "reg_user"; string host_os = cnf->fwobj->getStr("host_OS"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); // installer configlets should be different for each OS, but if // some OS can use the same script, it will be placed in the file // under os_family name. For example: // for linksys/sveasoft configlet is in src/res/configlets/sveasoft // but since linux24 and openwrt can use the same script, it is // located in src/res/configlets/linux24 (openwrt.xml file defines // family as "linux24") Configlet configlet(host_os, os_family, configlet_name); configlet.removeComments(); configlet.collapseEmptyStrings(true); // test run and rollback were deprecated in 4.2.0. On Linux, BSD // and PIX rollback was implemented by rebooting firewall which is // too heavy-handed and it did not work on BSD at all. configlet.setVariable("test", false); configlet.setVariable("run", true); configlet.setVariable("with_rollback", false); configlet.setVariable("no_rollback", true); configlet.setVariable("firewall_name", QString::fromUtf8(cnf->fwobj->getName().c_str())); configlet.setVariable("with_compression", cnf->compressScript); configlet.setVariable("no_compression", ! cnf->compressScript); // On FreeBSD where we can generate either shell script or rc.conf // file, installation commands differ. // // TODO: find more generic way to do this so that GUI installer does not // have to be aware of the differences in generated file format. configlet.setVariable("rc_conf_format", fwopt->getBool("generate_rc_conf_file")); configlet.setVariable("shell_script_format", ! fwopt->getBool("generate_rc_conf_file")); replaceMacrosInCommand(&configlet); return configlet.expand().trimmed(); }
void NATCompiler_pf::PrintRule::_printNATRuleOptions(Rule *rule) { FWOptions *ruleopt =rule->getOptionsObject(); if (ruleopt->getBool("pf_bitmask")) compiler->output << "bitmask "; if (ruleopt->getBool("pf_random")) compiler->output << "random "; if (ruleopt->getBool("pf_source_hash")) compiler->output << "source-hash "; if (ruleopt->getBool("pf_round_robin")) compiler->output << "round-robin "; if (ruleopt->getBool("pf_static_port")) compiler->output << "static-port "; }
void AutomaticRules_nxosacl::addSshAccessRule() { if (ruleset == NULL) return; FWOptions *fwopt = fw->getOptionsObject(); if (fwopt->getBool("mgmt_ssh") && ! fwopt->getStr("mgmt_addr").empty()) { AutomaticRules_cisco::addSshAccessRule(); /* * AutomaticRules_cisco::addDefaultPolicyRule() adds a rule to * permit backup ssh access to the firewall. Since NXOS ACL are * stateless, we need to add another rule to permit reply * packets. */ TCPService *ssh_rev = ruleset->getRoot()->createTCPService(); ssh_rev->setSrcRangeStart(22); ssh_rev->setSrcRangeEnd(22); persistent_objects->add(ssh_rev, false); Network *mgmt_workstation = ruleset->getRoot()->createNetwork(); mgmt_workstation->setAddressNetmask(fwopt->getStr("mgmt_addr")); persistent_objects->add(mgmt_workstation, false); addMgmtRule( fw, mgmt_workstation, ssh_rev, NULL, PolicyRule::Outbound, PolicyRule::Accept, "backup ssh access rule (out)"); } }
/* * Generate calls to the shell function update_addresses_of_interface * to add or remove ip addresses of interfaces. The following cases * are supported, depending on the value of * @add_virtual_addresses_for_nat and @configure_interfaces * * configure_interfaces == false && add_virtual_addresses_for_nat == false: * do not generate any commands * * configure_interfaces == false && add_virtual_addresses_for_nat == true: * use only virtual_addresses_for_nat, add normal addresses of the interface * to the list of addresses we should ignore * * configure_interfaces == true && add_virtual_addresses_for_nat == false: * ignore virtual_addresses_for_nat * * configure_interfaces == true && add_virtual_addresses_for_nat == true: * use virtual_addresses_for_nat * * */ string OSConfigurator_linux24::printInterfaceConfigurationCommands() { FWOptions* options = fw->getOptionsObject(); std::unique_ptr<interfaceProperties> int_prop( interfacePropertiesObjectFactory::getInterfacePropertiesObject( fw->getStr("host_OS"))); Configlet script(fw, "linux24", "configure_interfaces"); script.removeComments(); script.collapseEmptyStrings(true); list<FWObject*> interfaces = fw->getByTypeDeep(Interface::TYPENAME); bool need_promote_command = false; QStringList gencmd; list<FWObject*>::iterator i; for (i=interfaces.begin(); i!=interfaces.end(); ++i ) { Interface *iface = Interface::cast(*i); assert(iface); string iface_name = iface->getName(); QStringList update_addresses; QStringList ignore_addresses; if (int_prop->manageIpAddresses(iface, update_addresses, ignore_addresses)) { if (options->getBool("manage_virtual_addr") && virtual_addresses_for_nat.count(iface_name) > 0) update_addresses.push_back( virtual_addresses_for_nat[iface_name].c_str()); // generate update_addresses calls even if interface has // no addresses in fwbuilder. This makes sure all // addresses it might have on the machine will be // removed. Say, interface was regular and had an address // and then user converted it to unnumbered. In this case // the address should be removed. gencmd.push_back( printUpdateAddressCommand(iface, update_addresses, ignore_addresses)); // update_addresses list looks like this: // ("eth0", "22.22.22.22/24", "22.22.22.23/24") // I need to add "promote" command only when there is more than 1 address. need_promote_command |= (update_addresses.size() > 2); } known_interfaces.push_back(iface_name); } script.setVariable("have_interfaces", interfaces.size() > 0); script.setVariable("need_promote_command", need_promote_command); script.setVariable("configure_interfaces_script", gencmd.join("\n")); return script.expand().toStdString() + "\n"; }
string PolicyCompiler_iosacl::PrintRule::_printLog(PolicyRule *rule) { if (rule->getLogging()) { FWOptions *ruleopt =rule->getOptionsObject(); if (ruleopt->getBool("iosacl_log_input")) return "log-input "; return "log "; } return ""; }
bool PolicyCompiler_pf::ProcessScrubOption::processNext() { PolicyRule *rule=getNext(); if (rule==NULL) return false; FWOptions *ruleopt =rule->getOptionsObject(); if ( ruleopt->getBool("scrub") ) { if (rule->getAction()!=PolicyRule::Accept) { ruleopt->setBool("scrub",false); tmp_queue.push_back(rule); compiler->abort(rule, "Rule option 'scrub' is supported only for rules " "with action 'Accept'"); return true; } PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Scrub); r->getOptionsObject()->setBool("scrub",false); tmp_queue.push_back(r); ruleopt->setBool("scrub",false); tmp_queue.push_back(rule); return true; } /* if service is ip_fragment and action is 'Deny', then add rule with scrub */ Service *srv=compiler->getFirstSrv(rule); assert(srv); if ( (srv->getBool("short_fragm") || srv->getBool("fragm")) && ( rule->getAction()==PolicyRule::Deny || rule->getAction()==PolicyRule::Reject) ) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setAction(PolicyRule::Scrub); r->getOptionsObject()->setBool("scrub",false); tmp_queue.push_back(r); return true; } tmp_queue.push_back(rule); return true; }
OSConfigurator_linux24::OSConfigurator_linux24(FWObjectDatabase *_db, Firewall *fw, bool ipv6_policy) : OSConfigurator(_db, fw, ipv6_policy) , os_data(fw->getStr("host_OS")) { command_wrappers = new Configlet(fw, "linux24", "run_time_wrappers"); FWOptions* fwopt = fw->getOptionsObject(); string version = fw->getStr("version"); using_ipset = (XMLTools::version_compare(version, "1.4.1.1") >= 0 && fwopt->getBool("use_m_set")); }
bool PolicyCompiler_ipf::expandAnyService::processNext() { PolicyCompiler_ipf *pcomp=dynamic_cast<PolicyCompiler_ipf*>(compiler); PolicyRule *rule=getNext(); if (rule==NULL) return false; RuleElementSrv *srv=rule->getSrv(); FWOptions *ruleopt =rule->getOptionsObject(); if (srv->isAny() && ! ruleopt->getBool("stateless") && rule->getAction()==PolicyRule::Accept) { PolicyRule *r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); RuleElementSrv *nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anyicmp); //compiler->dbcopy->findInIndex(ANY_ICMP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anytcp); //compiler->dbcopy->findInIndex(ANY_TCP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); nsrv=r->getSrv(); nsrv->clearChildren(); nsrv->addRef(pcomp->anyudp); //compiler->dbcopy->findInIndex(ANY_UDP_OBJ_ID)); tmp_queue.push_back(r); r = compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); FWOptions *ruleopt =r->getOptionsObject(); ruleopt->setBool("stateless",true); tmp_queue.push_back(r); } else tmp_queue.push_back(rule); return true; }
string OSConfigurator_linux24::generateCodeForProtocolHandlers() { FWOptions* options = fw->getOptionsObject(); bool nomod = Resources::os_res[fw->getStr("host_OS")]-> Resources::getResourceBool("/FWBuilderResources/Target/options/suppress_modules"); // string host_os = fw->getStr("host_OS"); // string os_family = Resources::os_res[host_os]-> // getResourceStr("/FWBuilderResources/Target/family"); Configlet load_modules(fw, "linux24", "load_modules"); load_modules.removeComments(); // See ticket #2 string modules_dir = Resources::os_res[fw->getStr("host_OS")]-> Resources::getResourceStr("/FWBuilderResources/Target/options/default/modules_dir"); /* there is no need to load modules on some platforms */ load_modules.setVariable("load_modules", options->getBool("load_modules") && !nomod); load_modules.setVariable("modules_dir", modules_dir.c_str()); return load_modules.expand().toStdString(); }
string OSConfigurator_bsd::printFunctions() { ostringstream ostr; FWOptions* options = fw->getOptionsObject(); string host_os = fw->getStr("host_OS"); string version = fw->getStr("version"); Configlet functions(fw, "bsd", "shell_functions"); functions.removeComments(); functions.setVariable("dyn_addr", options->getBool("dynAddr")); if (options->getBool("dynAddr")) { /* * get addresses of dynamic interfaces */ QString script_buffer; QTextStream ostr(&script_buffer, QIODevice::WriteOnly); FWObjectTypedChildIterator j=fw->findByType(Interface::TYPENAME); for ( ; j!=j.end(); ++j ) { Interface *iface=Interface::cast(*j); if ( iface->isDyn() ) { /* if interface name ends with '*', this is a wildcard interface. Do * not get its address at this time. * * Do we support wildcard interfaces on *BSD at all ? */ if (iface->getName().find("*")==string::npos) ostr << "getaddr " << iface->getName().c_str() << " " << getInterfaceVarName(iface).c_str() << "\n"; } } functions.setVariable("get_dyn_addr_commands", script_buffer); } else functions.setVariable("get_dyn_addr_commands", ""); ostr << functions.expand().toStdString(); if ( options->getBool("configure_interfaces") ) { Configlet update_addresses(fw, "bsd", "update_addresses"); update_addresses.removeComments(); update_addresses.setVariable("freebsd", host_os == "freebsd"); update_addresses.setVariable("openbsd", host_os == "openbsd"); ostr << update_addresses.expand().toStdString(); } if ( options->getBool("configure_vlan_interfaces") ) { Configlet update_vlans(fw, "bsd", "update_vlans"); update_vlans.removeComments(); update_vlans.setVariable("freebsd", host_os == "freebsd"); update_vlans.setVariable("openbsd", host_os == "openbsd"); ostr << update_vlans.expand().toStdString(); } if (options->getBool("configure_bridge_interfaces")) { Configlet update_bridge(fw, "bsd", "update_bridge"); update_bridge.removeComments(); update_bridge.setVariable("freebsd", host_os == "freebsd"); if (host_os == "openbsd") { update_bridge.setVariable("openbsd", true); update_bridge.setVariable("openbsd_lt_47", XMLTools::version_compare(version, "4.7")<0); update_bridge.setVariable("openbsd_ge_47", XMLTools::version_compare(version, "4.7")>=0); } ostr << update_bridge.expand().toStdString(); } if ( options->getBool("configure_carp_interfaces") ) { Configlet update_carp(fw, "bsd", "update_carp"); update_carp.removeComments(); update_carp.setVariable("freebsd", host_os == "freebsd"); update_carp.setVariable("openbsd", host_os == "openbsd"); ostr << update_carp.expand().toStdString(); } if ( options->getBool("configure_pfsync_interfaces") ) { Configlet update_pfsync(fw, "bsd", "update_pfsync"); update_pfsync.removeComments(); update_pfsync.setVariable("freebsd", host_os == "freebsd"); update_pfsync.setVariable("openbsd", host_os == "openbsd"); ostr << update_pfsync.expand().toStdString(); } return ostr.str(); }
bool MangleTableCompiler_ipt::keepMangleTableRules::processNext() { PolicyRule *rule = getNext(); if (rule==NULL) return false; FWOptions *ruleopt = rule->getOptionsObject(); PolicyCompiler_ipt *ipt_comp = dynamic_cast<PolicyCompiler_ipt*>(compiler); string ruleset_name = compiler->getRuleSetName(); FWOptions *rulesetopts = ipt_comp->getSourceRuleSet()->getOptionsObject(); if (rulesetopts->getBool("mangle_only_rule_set")) tmp_queue.push_back(rule); else { if (rule->getAction() == PolicyRule::Branch && ruleopt->getBool("ipt_branch_in_mangle")) { PolicyRule* r; // this is a branching rule for mangle table. Need to put it // into PREROUTING and POSTROUTING chains as well because some // targets that work with mangle table can only go into these // chains, yet we do not know what kind of rules will user // place in the branch if (rule->getDirection()==PolicyRule::Undefined || rule->getDirection()==PolicyRule::Both || rule->getDirection()==PolicyRule::Inbound) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","PREROUTING"); tmp_queue.push_back(r); } if (rule->getDirection()==PolicyRule::Undefined || rule->getDirection()==PolicyRule::Both || rule->getDirection()==PolicyRule::Outbound) { r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","POSTROUTING"); tmp_queue.push_back(r); } // ticket #1415 User reports that only packets that went // through the FORWARD chain can match inbound "-i" and // outbound "-o" interface at the same time. Since we do // not allow both in and out interface matches in one rule // and have to use branch to do this, need to branch in // FORWARD chain as well so that inbound interface can be // matched in the branching rule and outbound interface // can be matched in a rule in the branch // // This is ugly, this means the branch will inspect the // packet at least twice - in PREROUTING and FORWARD, or // FORWARD and POSTROUTING chains. // // I mention above that some targets can only be used in // PREROUTING or POSTROUTING chains. It would help if // these tagrets worked in FORWARD chain, in that case we // could just branch in FORWARD instead of all thress chains. // r= compiler->dbcopy->createPolicyRule(); compiler->temp_ruleset->add(r); r->duplicate(rule); r->setStr("ipt_chain","FORWARD"); tmp_queue.push_back(r); // tmp_queue.push_back(rule); return true; } if (rule->getTagging() || rule->getRouting() || rule->getClassification() || ruleopt->getBool("put_in_mangle_table")) tmp_queue.push_back(rule); } return true; }
QString CompilerDriver_pix::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); // Copy rules from the cluster object populateClusterElements(cluster, fw); if (cluster) { // PIX failover is dfferent from VRRP and other failover protocols // in that it does not create new virtual address. Instead, each // unit is configured with two ip addresses, one for the active // unit and another for standby one. When active unit fails, the // other one assumes its address. // // This matters because when we use cluster object or one of its // interfaces in rules, compiler should expand it to the set of // addresses that includes addresses of the corresponding // interface of both member firewalls. Method // CompilerDriver::copyFailoverInterface adds a copy of firewall // interface to the cluster object. This works for all firewalls, // but for PIX we need to add copies of interfaces from both // members. // FWObjectTypedChildIterator cl_iface = cluster->findByType(Interface::TYPENAME); for (; cl_iface != cl_iface.end(); ++cl_iface) { FailoverClusterGroup *failover_group = FailoverClusterGroup::cast( (*cl_iface)->getFirstByType(FailoverClusterGroup::TYPENAME)); if (failover_group) { //FWObject *this_member_interface = NULL; //UNUSED list<FWObject*> other_member_interfaces; for (FWObjectTypedChildIterator it = failover_group->findByType(FWObjectReference::TYPENAME); it != it.end(); ++it) { FWObject *intf = FWObjectReference::getObject(*it); assert(intf); //if (intf->isChildOf(fw)) this_member_interface = intf; //UNUSED //else other_member_interfaces.push_back(intf); if (!intf->isChildOf(fw)) other_member_interfaces.push_back(intf); } if (!other_member_interfaces.empty()) { for (list<FWObject*>::iterator it=other_member_interfaces.begin(); it!=other_member_interfaces.end(); ++it) { cluster->addCopyOf(*it, true); } } } } } #if 0 FWObjectTypedChildIterator iface = fw->findByType(Interface::TYPENAME); for (; iface != iface.end(); ++iface) { (*iface)->dump(true, true); } #endif determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("")); FWOptions* options = fw->getOptionsObject(); QString script_buffer; std::auto_ptr<NATCompiler_pix> n; std::auto_ptr<PolicyCompiler_pix> c; std::auto_ptr<RoutingCompiler_pix> r; try { clearReadOnly(fw); commonChecks2(cluster, fw); pixClusterConfigurationChecks(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(); bool pix_acl_basic = options->getBool("pix_acl_basic"); bool pix_acl_no_clear = options->getBool("pix_acl_no_clear"); bool pix_acl_substitution = options->getBool("pix_acl_substitution"); bool pix_add_clear_statements = options->getBool("pix_add_clear_statements"); if (!pix_acl_basic && !pix_acl_no_clear && !pix_acl_substitution) { if ( pix_add_clear_statements ) options->setBool("pix_acl_basic",true); else options->setBool("pix_acl_no_clear",true); } list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); pixSecurityLevelChecks(fw, all_interfaces); pixNetworkZoneChecks(fw, all_interfaces); /* Now that all checks are done, we can drop copies of cluster * interfaces that were added to the firewall by * CompilerDriver::populateClusterElements() */ list<FWObject*> copies_of_cluster_interfaces; for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); if (iface->getOptionsObject()->getBool("cluster_interface")) copies_of_cluster_interfaces.push_back(iface); } while (copies_of_cluster_interfaces.size()) { fw->remove(copies_of_cluster_interfaces.front()); copies_of_cluster_interfaces.pop_front(); } NamedObjectsManagerPIX named_objects_manager(persistent_objects, fw); all_interfaces = fw->getByTypeDeep(Interface::TYPENAME); for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i) { Interface *iface = Interface::cast(*i); assert(iface); /* * missing labels on interfaces * */ if (iface->getLabel()=="") { string lbl; if (iface->isDedicatedFailover()) { // dedicated failover interface misses label. This // interface can be used in failover cluster group // or state sync group. Assign label depending on // the function. FWObjectTypedChildIterator it = cluster->findByType(StateSyncClusterGroup::TYPENAME); StateSyncClusterGroup *state_sync_group = StateSyncClusterGroup::cast(*it); if (state_sync_group && state_sync_group->hasMember(iface)) lbl = "state"; if (!iface->getOptionsObject()->getStr("failover_group_id").empty()) lbl = "failover"; } if (lbl.empty()) { if (iface->getSecurityLevel()==0) lbl="outside"; else { if (iface->getSecurityLevel()==100) lbl="inside"; else { QString l("dmz%1"); lbl = l.arg(iface->getSecurityLevel()).toStdString(); } } } iface->setLabel(lbl); } } /* * now sort interfaces by their network zone "width" (that * is, more narrow network zone should go first, interface * with network zone "any" should be the last) * std::sort(fw->begin(), fw->end(), sort_by_net_zone() ); */ try { AutomaticRules_cisco auto_rules(fw, persistent_objects); auto_rules.addSshAccessRule(); } catch (FWException &ex) { abort(ex.toString()); } std::auto_ptr<Preprocessor> prep( new Preprocessor(objdb , fw, false)); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); std::auto_ptr<OSConfigurator> oscnf( new OSConfigurator_pix_os(objdb , fw, false)); if (inTestMode()) oscnf->setTestMode(); if (inEmbeddedMode()) oscnf->setEmbeddedMode(); oscnf->prolog(); oscnf->processFirewallOptions(); bool have_named_objects = false; bool have_object_groups = false; /* create compilers and run the whole thing */ string version = fw->getStr("version"); if (XMLTools::version_compare(version, "8.3")>=0) n = std::auto_ptr<NATCompiler_pix>( new NATCompiler_asa8(objdb, fw, false, oscnf.get())); else n = std::auto_ptr<NATCompiler_pix>( new NATCompiler_pix(objdb, fw, false, oscnf.get())); RuleSet *nat = RuleSet::cast(fw->getFirstByType(NAT::TYPENAME)); if (nat) { nat->assignUniqueRuleIds(); n->setNamedObjectsManager(&named_objects_manager); n->setSourceRuleSet(nat); n->setRuleSetName(nat->getName()); n->setPersistentObjects(persistent_objects); 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 ( n->prolog() > 0 ) { n->compile(); n->epilog(); preamble_commands += n->printPreambleCommands(); clear_commands += n->printClearCommands(); have_named_objects = (have_named_objects || named_objects_manager.haveNamedObjects()); have_object_groups = (have_object_groups || named_objects_manager.haveObjectGroups()); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in NAT"); } c = std::auto_ptr<PolicyCompiler_pix>( new PolicyCompiler_pix(objdb, fw, false, oscnf.get() , n.get())); RuleSet *policy = RuleSet::cast(fw->getFirstByType(Policy::TYPENAME)); if (policy) { policy->assignUniqueRuleIds(); c->setNamedObjectsManager(&named_objects_manager); c->setSourceRuleSet(policy); c->setRuleSetName(policy->getName()); c->setPersistentObjects(persistent_objects); 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 ( c->prolog() > 0 ) { c->compile(); c->epilog(); preamble_commands += c->printPreambleCommands(); clear_commands += c->printClearCommands(); have_named_objects = (have_named_objects || named_objects_manager.haveNamedObjects()); have_object_groups = (have_object_groups || named_objects_manager.haveObjectGroups()); //named_objects_manager.saveObjectGroups(); } else info(" Nothing to compile in Policy"); } r = std::auto_ptr<RoutingCompiler_pix>( new RoutingCompiler_pix(objdb, fw, false, oscnf.get())); RuleSet *routing = RuleSet::cast(fw->getFirstByType(Routing::TYPENAME)); if (routing) { routing->assignUniqueRuleIds(); r->setNamedObjectsManager(&named_objects_manager); r->setSourceRuleSet(routing); r->setRuleSetName(routing->getName()); r->setPersistentObjects(persistent_objects); if (inTestMode()) r->setTestMode(); if (inEmbeddedMode()) r->setEmbeddedMode(); r->setSingleRuleCompileMode(single_rule_id); r->setDebugLevel( dl ); if (rule_debug_on) r->setDebugRule( drp ); r->setVerbose( verbose ); if ( r->prolog() > 0 ) { r->compile(); r->epilog(); } else info(" Nothing to compile in Routing"); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } policy_script = c->getCompiledScript(); nat_script = n->getCompiledScript(); routing_script = r->getCompiledScript(); named_objects_and_groups = named_objects_manager.getNamedObjectsDefinitions(); if (c->haveErrorsAndWarnings()) all_errors.push_back(c->getErrors("C ").c_str()); if (n->haveErrorsAndWarnings()) all_errors.push_back(n->getErrors("N ").c_str()); if (r->haveErrorsAndWarnings()) all_errors.push_back(r->getErrors("R ").c_str()); if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (named_objects_and_groups + policy_script + nat_script + routing_script).c_str())); } system_configuration_script = oscnf->getCompiledScript(); system_configuration_script += "\n"; clear_commands += named_objects_manager.getClearCommands() + "\n"; // system_configuration_script += preamble_commands; // system_configuration_script += clear_commands; script_buffer = assembleFwScript( cluster, fw, !cluster_id.empty(), oscnf.get()); QString ofname = getAbsOutputFileName(file_names[FW_FILE]); 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 { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } if (!all_errors.isEmpty()) status = BaseCompiler::FWCOMPILER_WARNING; } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; }
QString CompilerDriver_pix::assembleFwScript(Cluster *cluster, Firewall* fw, bool cluster_member, OSConfigurator *oscnf) { Configlet script_skeleton(fw, "pix_os", "script_skeleton"); Configlet top_comment(fw, "pix_os", "top_comment"); FWOptions* options = fw->getOptionsObject(); options->setStr("prolog_script", options->getStr("pix_prolog_script")); options->setStr("epilog_script", options->getStr("pix_epilog_script")); options->setStr("prolog_place", ""); string vers = fw->getStr("version"); string platform = fw->getStr("platform"); bool outbound_acl_supported = Resources::platform_res[platform]->getResourceBool( string("/FWBuilderResources/Target/options/")+ "version_"+vers+ "/pix_outbound_acl_supported"); bool afpa = options->getBool("pix_assume_fw_part_of_any"); bool emulate_outb_acls = options->getBool("pix_emulate_out_acl"); bool generate_outb_acls = options->getBool("pix_generate_out_acl"); top_comment.setVariable( "outbound_acl_supported", QString((outbound_acl_supported) ? "supported" : "not supported")); top_comment.setVariable("emulate_outb_acls", QString((emulate_outb_acls)?"yes":"no")); top_comment.setVariable("generate_outb_acls", QString((generate_outb_acls)?"yes":"no")); top_comment.setVariable("afpa", QString((afpa)?"yes":"no")); script_skeleton.setVariable("short_script", options->getBool("short_script")); script_skeleton.setVariable("not_short_script", ! options->getBool("short_script")); script_skeleton.setVariable("preamble_commands", QString::fromUtf8( preamble_commands.c_str())); script_skeleton.setVariable("clear_commands", QString::fromUtf8( clear_commands.c_str())); script_skeleton.setVariable("system_configuration_script", QString::fromUtf8( system_configuration_script.c_str())); script_skeleton.setVariable("named_objects_and_object_groups", QString::fromUtf8( named_objects_and_groups.c_str())); script_skeleton.setVariable("policy_script", QString::fromUtf8(policy_script.c_str())); script_skeleton.setVariable("nat_script", QString::fromUtf8(nat_script.c_str())); script_skeleton.setVariable("routing_script", QString::fromUtf8(routing_script.c_str())); assembleFwScriptInternal(cluster, fw, cluster_member, oscnf, &script_skeleton, &top_comment, "!", true); return script_skeleton.expand(); }
/* * Go through paces to compile firewall which may be a member of a * cluster. Note that both firewall and cluster are defined by their * unique string IDs. This is necessary because CompilerDriver * operates with a copy of the object database which is not exposed * outside, so the caller can not provide pointers to these obejcts. */ QString CompilerDriver_ipt::run(const std::string &cluster_id, const std::string &firewall_id, const std::string &single_rule_id) { FWObjectDatabase::registerObjectType(combinedAddress::TYPENAME, &create_combinedAddress); // see #2212 Create temporary copy of the firewall and cluster // objects and pass them to the compilers. Cluster *cluster = NULL; Firewall *fw = NULL; getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw); string generated_script; try { clearReadOnly(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(); if (fw->getOptionsObject()->getStr("prolog_place") == "after_flush" && fw->getOptionsObject()->getBool("use_iptables_restore")) { abort("Prolog place \"after policy reset\" can not be used" " when policy is activated with iptables-restore"); } string firewall_dir = options->getStr("firewall_dir"); if (firewall_dir=="") firewall_dir="/etc"; bool debug=options->getBool("debug"); QString shell_dbg = (debug)?"set -x":"" ; std::auto_ptr<OSConfigurator_linux24> oscnf; string platform_family = Resources::platform_res[platform]-> getResourceStr("/FWBuilderResources/Target/family"); string os_family = Resources::os_res[host_os]-> getResourceStr("/FWBuilderResources/Target/family"); bool supports_prolog_epilog = Resources::getTargetCapabilityBool( platform, "supports_prolog_epilog"); if (!supports_prolog_epilog) { prolog_done = true; epilog_done = true; } string os_variant = DISTRO; /* minimal sanity checking */ if (os_family == "ipcop") { os_variant = "ipcop"; // can't use iptables-restore with ipcop fw->getOptionsObject()->setBool("use_iptables_restore", false); // ipcop has its own iptables commands that accept packets // in states ESTABLISHED,RELATED fw->getOptionsObject()->setBool("accept_established", false); oscnf = std::auto_ptr<OSConfigurator_linux24>( new OSConfigurator_ipcop(objdb , fw, false)); } if (os_family == "linux24" || os_family == "openwrt" || os_family == "dd-wrt-nvram" || os_family == "dd-wrt-jffs" || os_family == "sveasoft") oscnf = std::auto_ptr<OSConfigurator_linux24>( new OSConfigurator_linux24(objdb , fw, false)); if (os_family == "secuwall") oscnf = std::auto_ptr<OSConfigurator_linux24>( new OSConfigurator_secuwall(objdb , fw, false)); if (oscnf.get()==NULL) { abort("Unrecognized host OS " + fw->getStr("host_OS") + " (family " + os_family+")"); return ""; } if (inTestMode()) oscnf->setTestMode(); if (inEmbeddedMode()) oscnf->setEmbeddedMode(); oscnf->validateInterfaces(); oscnf->prolog(); list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME); list<FWObject*> all_nat = fw->getByType(NAT::TYPENAME); int routing_rules_count = 0; bool have_ipv4 = false; bool have_ipv6 = false; // track chains in each table separately. Can we have the same // chain in filter and mangle tables ? Would it be the same // chain, i.e. do we need to create it only once or do we create // it twice, in each table separately ? // Using separate trackers we track and create chain in each // table separately. std::map<const std::string, bool> minus_n_commands_filter; std::map<const std::string, bool> minus_n_commands_mangle; std::map<const std::string, bool> minus_n_commands_nat; vector<int> ipv4_6_runs; findImportedRuleSets(fw, all_policies); findBranchesInMangleTable(fw, all_policies); findImportedRuleSets(fw, all_nat); try { AutomaticRules_ipt auto_rules(fw, persistent_objects); auto_rules.addConntrackRule(); auto_rules.addFailoverRules(); } catch (FWException &ex) { abort(ex.toString()); } // assign unique rule ids that later will be used to generate // chain names. This should be done after calls to // findImportedRuleSets() assignUniqueRuleIds(all_policies); assignUniqueRuleIds(all_nat); // command line options -4 and -6 control address family for which // script will be generated. If "-4" is used, only ipv4 part will // be generated. If "-6" is used, only ipv6 part will be generated. // If neither is used, both parts will be done. if (options->getStr("ipv4_6_order").empty() || options->getStr("ipv4_6_order") == "ipv4_first") { if (ipv4_run) ipv4_6_runs.push_back(AF_INET); if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); } if (options->getStr("ipv4_6_order") == "ipv6_first") { if (ipv6_run) ipv4_6_runs.push_back(AF_INET6); if (ipv4_run) ipv4_6_runs.push_back(AF_INET); } for (vector<int>::iterator i=ipv4_6_runs.begin(); i!=ipv4_6_runs.end(); ++i) { int policy_af = *i; bool ipv6_policy = (policy_af == AF_INET6); /* clear chain tracker map only between ipv4/ipv6 runs Don't clear it between compiler runs for different policy or nat objects for the same address family. */ minus_n_commands_filter.clear(); minus_n_commands_mangle.clear(); minus_n_commands_nat.clear(); /* We need to create and run preprocessor for this address family before nat and policy compilers, but if there are no nat / policy rules for this address family, we do not need preprocessor either. */ // Count rules for each address family int nat_count = 0; int policy_count = 0; for (list<FWObject*>::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { NAT *nat = NAT::cast(*p); if (nat->matchingAddressFamily(policy_af)) nat_count++; } for (list<FWObject*>::iterator p=all_policies.begin(); p!=all_policies.end(); ++p) { Policy *policy = Policy::cast(*p); if (policy->matchingAddressFamily(policy_af)) policy_count++; } if (nat_count || policy_count) { Preprocessor_ipt* prep = new Preprocessor_ipt( objdb , fw, ipv6_policy); prep->setSingleRuleCompileMode(single_rule_id); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); delete prep; } ostringstream automaitc_rules_stream; ostringstream automaitc_mangle_stream; ostringstream filter_rules_stream; ostringstream mangle_rules_stream; ostringstream nat_rules_stream; bool empty_output = true; // First, process branch NAT rulesets, then top NAT ruleset NAT *top_nat = NULL; for (list<FWObject*>::iterator p=all_nat.begin(); p!=all_nat.end(); ++p) { NAT *nat = NAT::cast(*p); if (!nat->matchingAddressFamily(policy_af)) continue; if (nat->isTop()) { top_nat = nat; continue; } if (! processNatRuleSet( fw, nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; } if (top_nat && ! processNatRuleSet( fw, top_nat, single_rule_id, nat_rules_stream, oscnf.get(), policy_af, minus_n_commands_nat)) empty_output = false; // first process all non-top rule sets, then all top rule sets for (int all_top = 0; all_top < 2; ++all_top) { for (list<FWObject*>::iterator p=all_policies.begin(); p!=all_policies.end(); ++p ) { Policy *policy = Policy::cast(*p); if (!policy->matchingAddressFamily(policy_af)) 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, automaitc_mangle_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) { have_ipv6 = true; generated_script += "\n\n"; generated_script += "# ================ IPv6\n"; generated_script += "\n\n"; } else { have_ipv4 = true; generated_script += "\n\n"; generated_script += "# ================ IPv4\n"; generated_script += "\n\n"; } } generated_script += dumpScript(fw, automaitc_rules_stream.str(), automaitc_mangle_stream.str(), nat_rules_stream.str(), mangle_rules_stream.str(), filter_rules_stream.str(), ipv6_policy); if (single_rule_compile_on) generated_script += "\n\n"; } std::auto_ptr<RoutingCompiler_ipt> 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->setPersistentObjects(persistent_objects); routing_compiler->setSingleRuleCompileMode(single_rule_id); routing_compiler->setDebugLevel( dl ); if (rule_debug_on) routing_compiler->setDebugRule(drr); 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()); } /* * compilers detach persistent objects when they finish, this * means at this point library persistent_objects is not part * of any object tree. */ objdb->reparent(persistent_objects); if (haveErrorsAndWarnings()) { all_errors.push_front(getErrors("").c_str()); } if (single_rule_compile_on) { return formSingleRuleCompileOutput( QString::fromUtf8( (getErrors("") + generated_script + routing_compiler->getCompiledScript()).c_str())); } /* * These store generated configuration internally, extract it later using * OSConfiguration::getGeneratedFiles(); */ oscnf->processFirewallOptions(); /* * now write generated scripts to files */ char *timestr = NULL; time_t tm; struct tm *stm; tm = time(NULL); stm = localtime(&tm); timestr = strdup(ctime(&tm)); timestr[strlen(timestr)-1] = '\0'; /* * 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(); QString script_buffer; QTextStream script(&script_buffer, QIODevice::WriteOnly); /* * text comes from the compiler in UTF-8 (because all comments * and object names are stored in UTF-8 in objects and * compilers do not decode). We have a choice: 1) apply * QString::fromUtf8() to all strings coming from the compiler * to convert to Unicode and rely on QTextStream to convert * back to UTF-8 in the generated file, or 2) leavle strings * coming from compilers as-is and tell the stream to not * covert. */ script_buffer = ""; script_skeleton.setVariable("shell_debug", shell_dbg); script << "PATH=\"/sbin:/usr/sbin:/bin:/usr/bin:${PATH}\"" << "\n"; script << "export PATH" << "\n"; script_skeleton.setVariable("path", script_buffer); script_buffer = ""; 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(have_ipv6).c_str()); script_skeleton.setVariable("run_time_address_tables", oscnf->printRunTimeAddressTablesCode().c_str()); script_skeleton.setVariable("using_ipset", oscnf->usingIpSetModule()); 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") || options->getBool("manage_virtual_addr")) { if ( options->getBool("configure_interfaces")) ostr << oscnf->printInterfaceConfigurationCommands(); else ostr << oscnf->printVirtualAddressesForNatCommands(); } ostr << oscnf->printCommandsToClearKnownInterfaces(); ostr << oscnf->printDynamicAddressesConfigurationCommands(); script_skeleton.setVariable( "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<FWObject*> 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()); 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; } 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; } script_skeleton.setVariable("load_modules", oscnf->generateCodeForProtocolHandlers().c_str()); script_skeleton.setVariable("load_modules_with_nat", (have_nat)?"nat":""); script_skeleton.setVariable("load_modules_with_ipv6", (have_ipv6)?"ipv6":""); script_skeleton.setVariable("ip_forward_commands", oscnf->printIPForwardingCommands().c_str()); /* * script body begins here */ script_buffer = ""; if (oscnf->haveErrorsAndWarnings()) { all_errors.push_back(oscnf->getErrors("").c_str()); } // convert from UTF8 to make sure localized comments are shown correctly // script << oscnf->getCompiledScript().c_str(); // script << generated_script.c_str(); // script << routing_compiler->getCompiledScript().c_str(); script << QString::fromUtf8(oscnf->getCompiledScript().c_str()); script << QString::fromUtf8(generated_script.c_str()); script << QString::fromUtf8(routing_compiler->getCompiledScript().c_str()); 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); script_skeleton.setVariable("database", objdb->getFileName().c_str()); /* * 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 = ""; if (have_ipv4) script << " reset_iptables_v4" << endl; if (have_ipv6) script << " reset_iptables_v6" << endl; script_skeleton.setVariable("reset_all", script_buffer); script_buffer = ""; Configlet block_action(fw, "linux24", "block_action"); if (XMLTools::version_compare(fw_version, "1.4.20") >= 0) block_action.setVariable("opt_wait", "-w"); else block_action.setVariable("opt_wait", ""); block_action.collapseEmptyStrings(true); // the name of the option is historical (including the typo) if (fw->getOptionsObject()->getBool("add_mgmt_ssh_rule_when_stoped")) { std::auto_ptr<PolicyCompiler_ipt> policy_compiler = createPolicyCompiler(fw, false, NULL, NULL); PolicyCompiler_ipt::PrintRule* print_rule = policy_compiler->createPrintRuleProcessor(); print_rule->setContext(policy_compiler.get()); print_rule->_printBackupSSHAccessRules(&block_action); } else { block_action.setVariable("mgmt_access", 0); } script_skeleton.setVariable("block_action", block_action.expand()); Configlet stop_action(fw, "linux24", "stop_action"); stop_action.collapseEmptyStrings(true); stop_action.setVariable("have_ipv4", have_ipv4); stop_action.setVariable("have_ipv6", have_ipv6); if (XMLTools::version_compare(fw_version, "1.4.20") >= 0) stop_action.setVariable("opt_wait", "-w"); else stop_action.setVariable("opt_wait", ""); script_skeleton.setVariable("stop_action", stop_action.expand()); Configlet status_action(fw, "linux24", "status_action"); status_action.collapseEmptyStrings(true); script_skeleton.setVariable("status_action", status_action.expand()); Configlet top_comment(fw, "linux24", "top_comment"); top_comment.setVariable("version", VERSION); top_comment.setVariable("timestamp", timestr); top_comment.setVariable("tz", tzname[stm->tm_isdst]); top_comment.setVariable("user", user_name); top_comment.setVariable("database", objdb->getFileName().c_str()); determineOutputFileNames(cluster, fw, !cluster_id.empty(), QStringList(""), QStringList("fw"), QStringList("script_name_on_firewall")); script_buffer = ""; script << MANIFEST_MARKER << "* " << this->escapeFileName(file_names[FW_FILE]); if (!remote_file_names[FW_FILE].isEmpty()) script << " " << this->escapeFileName(remote_file_names[FW_FILE]); 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 */ map<string, string> file_list = oscnf->getGeneratedFiles(); if (!file_list.empty()) { info(" Adding additional files to manifest"); map<string, string>::const_iterator c_iter = file_list.begin(); for (; c_iter != file_list.end(); ++c_iter) { string name = c_iter->first; string dest = c_iter->second; script << MANIFEST_MARKER << this->escapeFileName(name.c_str()); if (!dest.empty()) script << " " << dest; script << "\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: " + file_names[FW_FILE].toStdString()); QFile fw_file(file_names[FW_FILE]); 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 { QString err(" Failed to open file %1 for writing: %2; Current dir: %3"); abort(err.arg(fw_file.fileName()) .arg(fw_file.error()).arg(QDir::current().path()).toStdString()); } free(timestr); if (!all_errors.isEmpty()) status = BaseCompiler::FWCOMPILER_WARNING; } catch (FWException &ex) { status = BaseCompiler::FWCOMPILER_ERROR; return QString::fromUtf8(ex.toString().c_str()); } return ""; }
/** * Print shell functions used by the script. If argument (boolean) is true, * do not add comments. */ string OSConfigurator_linux24::printShellFunctions(bool have_ipv6) { QStringList output; FWOptions* options = fw->getOptionsObject(); string version = fw->getStr("version"); // string host_os = fw->getStr("host_OS"); // string os_family = Resources::os_res[host_os]-> // getResourceStr("/FWBuilderResources/Target/family"); Configlet shell_functions(fw, "linux24", "shell_functions"); output.push_back(shell_functions.expand()); /* check if package iproute2 is installed, but do this only if * we really need /usr/sbin/ip */ Configlet configlet(fw, "linux24", "check_utilities"); configlet.removeComments(); configlet.collapseEmptyStrings(true); configlet.setVariable("load_modules", options->getBool("load_modules")); if (options->getBool("load_modules") || options->getBool("configure_vlan_interfaces") || options->getBool("configure_bonding_interfaces")) { configlet.setVariable("need_modprobe", true); } if (options->getBool("verify_interfaces") || options->getBool("manage_virtual_addr") || options->getBool("configure_interfaces") ) { configlet.setVariable("need_vconfig", options->getBool("configure_vlan_interfaces")); configlet.setVariable("need_brctl", options->getBool("configure_bridge_interfaces")); configlet.setVariable("need_ifenslave", options->getBool("configure_bonding_interfaces")); } configlet.setVariable("need_ipset", using_ipset); configlet.setVariable("need_iptables_restore", options->getBool("use_iptables_restore")); configlet.setVariable("need_ip6tables_restore", have_ipv6 && options->getBool("use_iptables_restore")); output.push_back(configlet.expand()); /* * Generate commands to reset all tables and chains and set * default policy */ Configlet reset_iptables(fw, "linux24", "reset_iptables"); if (XMLTools::version_compare(version, "1.4.20") >= 0) reset_iptables.setVariable("opt_wait", "-w"); else reset_iptables.setVariable("opt_wait", ""); output.push_back(reset_iptables.expand()); Configlet addr_conf(fw, "linux24", "update_addresses"); output.push_back(addr_conf.expand()); if (options->getBool("configure_vlan_interfaces")) { Configlet conf(fw, "linux24", "update_vlans"); output.push_back(conf.expand()); } if (options->getBool("configure_bridge_interfaces")) { Configlet conf(fw, "linux24", "update_bridge"); output.push_back(conf.expand()); } if (options->getBool("configure_bonding_interfaces")) { Configlet conf(fw, "linux24", "update_bonding"); output.push_back(conf.expand()); } return output.join("\n").toStdString(); }