예제 #1
0
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)");
    }
}
예제 #2
0
pixosIfaceOptsDialog::pixosIfaceOptsDialog(QWidget *parent, FWObject *o)
    : QDialog(parent)
{
    m_dialog = new Ui::pixosIfaceOptsDialog_q;
    m_dialog->setupUi(this);
    setWindowModality(Qt::WindowModal);
    obj = o;

    FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject();
    cluster_interface = (Cluster::cast(obj->getParent()) != NULL);

    setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj),
                      ifopt->getStr("type").c_str());

    // Using "type" control only for subinterfaces
    // and main interfaces of the firewall objects
    if (cluster_interface)
    {
        m_dialog->iface_type->hide();
        m_dialog->iface_type_label->hide();
    } else
    {
        m_dialog->iface_type->show();
        m_dialog->iface_type_label->show();
    }

    data.registerOption(m_dialog->vlan_id, ifopt, "vlan_id");

    data.loadAll();

    // special actions for different iface types
    // VLAN (8021q)
    typeChanged("");
}
예제 #3
0
QStringList instDialog::prepareArgForCompiler(Firewall *fw)
{
    FWOptions *fwopt = fw->getOptionsObject();
    QStringList args;

/*
 * I should be able to specify custom compiler for firewall with
 * no platform (e.g. for experiments)
 */
    string compiler = fwopt->getStr("compiler");
    if (compiler=="")
    {
        compiler=Resources::platform_res[fw->getStr("platform")]->getCompiler();
    }

    if (compiler=="")
    {
        QMessageBox::warning(
            this,"Firewall Builder",
            tr("Firewall platform is not specified in this object.\n\
Can't compile firewall policy."),
            tr("&Continue"), QString::null,QString::null,
            0, 1 );
        return args; // still empty list
    }
QString CompilerDriver_junosacl::assembleFwScript(Cluster *cluster,
                                                  Firewall *fw,
                                                  bool cluster_member,
                                                  OSConfigurator *oscnf)
{
    Configlet script_skeleton(fw, "junos", "script_skeleton");
    Configlet top_comment(fw, "junos", "top_comment");

    script_skeleton.setVariable("system_configuration_script",
                                QString::fromUtf8(system_configuration_script.c_str()));
    script_skeleton.setVariable("policy_script",
                                QString::fromUtf8(policy_script.c_str()));

    FWOptions* options = fw->getOptionsObject();
    options->setStr("prolog_script", options->getStr("junosacl_prolog_script"));
    options->setStr("epilog_script", options->getStr("junosacl_epilog_script"));

    // we do not offer user a choice of the place where to put prolog
    // lines, therefore we can reset this attribute to make sure it
    // does not interfere
    options->setStr("prolog_place", "");

    assembleFwScriptInternal(cluster, fw, cluster_member,
                             oscnf, &script_skeleton, &top_comment, "!", true);
    return script_skeleton.expand();
}
예제 #5
0
string OSConfigurator_linux24::printIPForwardingCommands()
{
/* Turn on packet forwarding if we have to */
    // string os_family = Resources::os_res[fw->getStr("host_OS")]->
    //     getResourceStr("/FWBuilderResources/Target/family");
    FWOptions* options = fw->getOptionsObject();
    Configlet ip_forwarding(fw, "linux24", "ip_forwarding");
    ip_forwarding.removeComments();
    ip_forwarding.collapseEmptyStrings(true);

    string s = options->getStr("linux24_ip_forward");
    ip_forwarding.setVariable("ipv4", !s.empty());
    ip_forwarding.setVariable("ipv4_forw", (s=="1" || s=="On" || s=="on")?1:0);

    s = options->getStr("linux24_ipv6_forward");
    ip_forwarding.setVariable("ipv6", !s.empty());
    ip_forwarding.setVariable("ipv6_forw", (s=="1" || s=="On" || s=="on")?1:0);

    return ip_forwarding.expand().toStdString();
}
QString FirewallInstaller::getGeneratedFileName(Firewall *fw)
{
    FWOptions  *fwopt = fw->getOptionsObject();
    QString generated_file;
    QString ofname = QString::fromUtf8(fwopt->getStr("output_file").c_str()).trimmed();
    if (!ofname.isEmpty())
    {
        generated_file = ofname;
    } else
        generated_file = QString::fromUtf8(fw->getName().c_str()) + ".fw";
    return generated_file;
}
예제 #7
0
void OSConfigurator_bsd::setKernelVariable(Firewall *fw,
                                           const string &var_name,
                                           Configlet *configlet)
{
    FWOptions* options = fw->getOptionsObject();
    string s;

    s = options->getStr(var_name);
    if (!s.empty())
    {
        configlet->setVariable(QString("have_") + var_name.c_str(), 1);
        configlet->setVariable(var_name.c_str(), s=="1" || s=="on" || s=="On");
    }
}
예제 #8
0
secuwallIfaceOptsDialog::secuwallIfaceOptsDialog(QWidget *parent, FWObject *o)
    : QDialog(parent)
{
    m_dialog = new Ui::secuwallIfaceOptsDialog_q;
    m_dialog->setupUi(this);
    obj = o;

    FWOptions *ifopt = (Interface::cast(obj))->getOptionsObject();
    cluster_interface = (Cluster::cast(obj->getParent()) != NULL);

    setInterfaceTypes(m_dialog->iface_type, Interface::cast(obj),
                      ifopt->getStr("type").c_str());

    // Using "type" control only for subinterfaces
    // and main interfaces of the firewall objects
    if (cluster_interface)
    {
        m_dialog->iface_type->hide();
        m_dialog->iface_type_label->hide();
    } else
    {
        m_dialog->iface_type->show();
        m_dialog->iface_type_label->show();
    }

    data.registerOption(m_dialog->iface_mtu,
                        ifopt,
                        "iface_mtu");

    data.registerOption(m_dialog->iface_disablearp,
                        ifopt,
                        "iface_disablearp");

    data.registerOption(m_dialog->iface_disableboot,
                        ifopt,
                        "iface_disableboot");

    data.registerOption(m_dialog->iface_options,
                        ifopt,
                        "iface_options");

    data.registerOption(m_dialog->vlan_id,
                        ifopt,
                        "vlan_id");

    data.loadAll();

    // perform special actions for different iface types
    typeChanged("");
}
예제 #9
0
string OSConfigurator_linux24::getPathForATool(const std::string &os_variant, OSData_ipt::tools tool_name)
{
    FWOptions* options = fw->getOptionsObject();
    string attr = os_data.getAttributeNameForTool(tool_name);

    string s = options->getStr("linux24_" + attr);
    if (!s.empty()) return s;

    string host_os = fw->getStr("host_OS");
    string r = "/FWBuilderResources/Target/tools/" + os_variant + "/" + attr;
    if (Resources::os_res[host_os]->getResourceStr(r).empty())
        r = "/FWBuilderResources/Target/tools/Unknown/" + attr;
    
    return Resources::os_res[host_os]->getResourceStr(r);
}
string PolicyCompiler_junosacl::PrintRule::_printAction(PolicyRule *rule)
{
    ostringstream  str;

    switch (rule->getAction()) {
    case PolicyRule::Accept:  str << "accept"; break;
    case PolicyRule::Deny:    str << "discard"; break;
    case PolicyRule::Reject:  str << "reject";
    {
        FWOptions  *ruleopt =rule->getOptionsObject();
        string reason = ruleopt->getStr("action_on_reject");

        if (!reason.empty())
            str << " " << reject_icmp_reason.at(reason);
    }
        break;
    default:		      str << rule->getActionAsString() << "";
    }
    return str.str();
}
예제 #11
0
void RuleOptionsDialog::applyChanges()
{

    std::unique_ptr<FWCmdChange> cmd( new FWCmdRuleChangeOptions(m_project, obj));
    // new_state  is a copy of the rule object
    FWObject* new_state = cmd->getNewState();
    FWOptions* new_rule_options = Rule::cast(new_state)->getOptionsObject();

    init = true;
    data.saveAll(new_rule_options);
    init = false;

/*  #2367 */

    PolicyRule *policy_rule = PolicyRule::cast(new_state);
    if (policy_rule)
    {
        FWOptions *ropt = policy_rule->getOptionsObject();

        if (platform=="iptables")
        {
            FWObject *tag_object = m_dialog->iptTagDropArea->getObject();
            // if tag_object==NULL, setTagObject clears setting in the rule
            policy_rule->setTagging(tag_object != NULL);
            policy_rule->setTagObject(tag_object);

            policy_rule->setClassification(
                ! ropt->getStr("classify_str").empty());

            policy_rule->setRouting( ! ropt->getStr("ipt_iif").empty() ||
                                     ! ropt->getStr("ipt_oif").empty() ||
                                     ! ropt->getStr("ipt_gw").empty());
        }
    
        if (platform=="pf")
        {
            FWObject *tag_object = m_dialog->pfTagDropArea->getObject();
            // if tag_object==NULL, setTagObject clears setting in the rule
            policy_rule->setTagging(tag_object != NULL);
            policy_rule->setTagObject(tag_object);

            policy_rule->setClassification(
                ! new_rule_options->getStr("pf_classify_str").empty());

            policy_rule->setRouting(
                ! new_rule_options->getStr("pf_route_option").empty() &&
                new_rule_options->getStr("pf_route_option") != "none");
        }

        if (platform=="ipf")
        {
            policy_rule->setRouting(
                ! new_rule_options->getStr("ipf_route_option").empty() &&
                new_rule_options->getStr("ipf_route_option") != "none");
        }

        if (platform=="ipfw")
        {
            policy_rule->setClassification(
                new_rule_options->getInt("ipfw_classify_method") > -1);
        }
    }

    if (!cmd->getOldState()->cmp(new_state, true))
    {
        if (obj->isReadOnly()) return;
        m_project->undoStack->push(cmd.release());
    }

}
예제 #12
0
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();
}
string OSConfigurator_pix_os::_printMPFPolicyMap()
{
    ostringstream res;
    string platform = fw->getStr("platform");
    string version = fw->getStr("version");
    string vers = "version_" + version;
    FWOptions *options = fw->getOptionsObject();
    assert(options!=NULL);

    std::list<InspectionClassMap> defaultClassMaps;
    std::list<InspectionClassMap> customClassMaps;
    std::map<std::string,int>    DefaultInspectionInspectStatements;
    std::map<std::string,int>    CustomInspectionInspectStatements;


    QStringList allowed_fixups = 
        QString(Resources::platform_res[platform]->getResourceStr(
                    "/FWBuilderResources/Target/options/" + vers +
                    "/fixups/list").c_str()).split(",");

    defaultClassMaps.clear();
    customClassMaps.clear();
    DefaultInspectionInspectStatements.clear();
    CustomInspectionInspectStatements.clear();

    foreach (QString fixup_xml_element, allowed_fixups)
    {
        string f = options->getStr(fixup_xml_element.toAscii().constData());

        if (!f.empty())
        {
            QString fixup_name = fixup_xml_element.replace("_fixup", "");

            int status;
            int p1,p2;
            string an;
            int av;
            istringstream str(f);

            str >> status >> p1 >> p2 >> an >> av;

/* We should really fix this in the GUI and pass max length parameter
 * as an/av rather than as port p1
 */
            if (fixup_name == "dns" && p1 != 0)
            {
                an = "maximum-length";
                av = p1;
                p1 = 53;
            }

            if (fixup_name.startsWith("ip_options"))
            {
                continue;
            }

            InspectionClassMap cm(fixup_name.toAscii().constData(),
                                  status, p1, p2, an, av);
            if (cm.isDefault()) defaultClassMaps.push_back(cm);
            else                customClassMaps.push_back(cm);
        }
QString CompilerDriver_junosacl::run(const string &cluster_id,
                                     const string &firewall_id,
                                     const string &single_rule_id)
{
    Cluster *cluster = NULL;
    Firewall *fw = NULL;

    getFirewallAndClusterObjects(cluster_id, firewall_id, &cluster, &fw);

    try
    {
        clearReadOnly(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();

        determineOutputFileNames(cluster, fw, !cluster_id.empty(),
                                 QStringList(""), QStringList("fw"),
                                 QStringList(""));

        /* Now that all checks are done, we can drop copies of cluster
         * interfaces that were added to the firewall by
         * CompilerDriver::populateClusterElements()
         */
        list<FWObject*> all_interfaces = fw->getByTypeDeep(Interface::TYPENAME);
        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();
        }

        FWOptions* options = fw->getOptionsObject();

        string fwvers = fw->getStr("version");
        if (fwvers == "") fw->setStr("version", "11.2");
        if (fwvers == "11.x") fw->setStr("version", "11.2");

        string platform = fw->getStr("platform");

        std::auto_ptr<OSConfigurator_junos> oscnf(new OSConfigurator_junos(objdb, fw, false));

        oscnf->prolog();
        oscnf->processFirewallOptions();

        list<FWObject*> all_policies = fw->getByType(Policy::TYPENAME);

        // assign unique rule ids that later will be used to generate
        // chain names.  This should be done after calls to
        // findImportedRuleSets()
        // NB: these ids are not used by this compiler

        assignUniqueRuleIds(all_policies);

        vector<int> ipv4_6_runs;

        // // // // //NamedObjectsManager named_objects_manager(persistent_objects, 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);
        }

        string object_groups_definitions;

        for (vector<int>::iterator i=ipv4_6_runs.begin();
             i!=ipv4_6_runs.end(); ++i)
        {
            int policy_af = *i;
            bool ipv6_policy = (policy_af == AF_INET6);

            // Count rules for each address family
            int policy_count = 0;

            for (list<FWObject*>::iterator p=all_policies.begin();
                 p!=all_policies.end(); ++p)
            {
                Policy *policy = Policy::cast(*p);
                if (policy->matchingAddressFamily(policy_af)) policy_count++;
            }
            if (policy_count)
            {
                std::auto_ptr<Preprocessor> prep(new Preprocessor(objdb, fw, false));
                if (inTestMode()) prep->setTestMode();
                if (inEmbeddedMode()) prep->setEmbeddedMode();
                prep->compile();
            }

            for (list<FWObject*>::iterator p=all_policies.begin();
                 p!=all_policies.end(); ++p)
            {
                Policy *policy = Policy::cast(*p);

                if (!policy->matchingAddressFamily(policy_af)) continue;

                PolicyCompiler_junosacl c(objdb, fw, ipv6_policy, oscnf.get());

                // // // // //c.setNamedObjectsManager(&named_objects_manager);
                c.setSourceRuleSet( policy );
                c.setRuleSetName(policy->getName());
                c.setPersistentObjects(persistent_objects);

                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)
                {
                    c.compile();
                    c.epilog();

                    if (!single_rule_compile_on)
                    {
                        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();
                } else {
                    info(" Nothing to compile in Policy");
                }
            }
        }

        /*
             * 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());
        }

        // // // // //object_groups_definitions +=
        // // // // //        named_objects_manager.getNamedObjectsDefinitions();

        if (single_rule_compile_on)
        {
            return formSingleRuleCompileOutput(
                        QString::fromUtf8(
                            (object_groups_definitions +
                             policy_script).c_str()));
        }

        system_configuration_script += object_groups_definitions;

        QString 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 "";
}
예제 #15
0
void RuleOptionsDialog::loadFWObject(FWObject *o)
{
    obj = o;
    firewall = o;
    // use Firewall::cast to match both Firewall and Cluster
    while (!Firewall::cast(firewall)) firewall = firewall->getParent();
    platform = firewall->getStr("platform").c_str();
    string version = firewall->getStr("version");

    // build a map for combobox so visible combobox items can be localized
    QStringList route_options = getRouteOptions_pf_ipf(platform);
    QStringList route_load_options = getRouteLoadOptions_pf(platform);
    QStringList classify_options_ipfw = getClassifyOptions_ipfw(platform);

    Rule      *rule = dynamic_cast<Rule*>(o);
    FWOptions *ropt = rule->getOptionsObject();
    PolicyRule *policy_rule = PolicyRule::cast(rule);

    int wid=0;
    if (platform=="iptables") wid=1;
    if (platform=="ipf")      wid=2;
    if (platform=="pf")       wid=3;
    if (platform=="ipfw")     wid=4;
    if (platform=="pix" || platform=="fwsm")      wid=5;
    if (platform=="iosacl" || platform=="procurve_acl")   wid=6;
	if (platform=="junosacl") wid=7;

    m_dialog->wStack->widget(wid)->raise();
    m_dialog->wStack->setCurrentWidget(m_dialog->wStack->widget(wid));

    QStringList  logLevels=getLogLevels( obj->getStr("platform").c_str() );
    m_dialog->ipt_logLevel->clear();
    m_dialog->ipt_logLevel->addItems(getScreenNames(logLevels));
    m_dialog->ipf_logLevel->clear();
    m_dialog->ipf_logLevel->addItems(getScreenNames(logLevels));
    m_dialog->pix_logLevel->clear();
    m_dialog->pix_logLevel->addItems(getScreenNames(logLevels));

    QStringList logFacilities=getLogFacilities( obj->getStr("platform").c_str());
    m_dialog->ipf_logFacility->clear();
    m_dialog->ipf_logFacility->addItems(getScreenNames(logFacilities));
    QStringList limitSuffixes=getLimitSuffixes( obj->getStr("platform").c_str());
    m_dialog->ipt_limitSuffix->clear();
    m_dialog->ipt_limitSuffix->addItems(getScreenNames(limitSuffixes));

    m_dialog->ipt_hashlimit_suffix->clear();
    m_dialog->ipt_hashlimit_suffix->addItems(getScreenNames(limitSuffixes));

    fillInterfaces(m_dialog->ipt_iif);
    fillInterfaces(m_dialog->ipt_oif);
    fillInterfaces(m_dialog->ipf_route_opt_if);
    fillInterfaces(m_dialog->pf_route_opt_if);


    data.clear();

    if (platform=="iptables")
    {
        data.registerOption(m_dialog->ipt_logPrefix, ropt,  "log_prefix");
        data.registerOption(m_dialog->ipt_logLevel, ropt,
                             "log_level", logLevels);
        data.registerOption(m_dialog->ipt_nlgroup, ropt,  "ulog_nlgroup");

        data.registerOption(m_dialog->ipt_limit, ropt,  "limit_value");
        data.registerOption(m_dialog->ipt_limitSuffix, ropt,
                             "limit_suffix", limitSuffixes);
        data.registerOption(m_dialog->ipt_limit_not, ropt,  "limit_value_not");
        data.registerOption(m_dialog->ipt_burst, ropt,  "limit_burst");

        data.registerOption(m_dialog->ipt_connlimit, ropt,  "connlimit_value");
        data.registerOption(m_dialog->ipt_connlimit_above_not, ropt,
                            "connlimit_above_not");
        data.registerOption(m_dialog->ipt_connlimit_masklen, ropt,
                            "connlimit_masklen");

        data.registerOption(m_dialog->ipt_hashlimit, ropt,  "hashlimit_value");
        data.registerOption(m_dialog->ipt_hashlimit_suffix, ropt,
                            "hashlimit_suffix");
        data.registerOption(m_dialog->ipt_hashlimit_burst, ropt,
                            "hashlimit_burst");
        data.registerOption(m_dialog->cb_srcip, ropt,  "hashlimit_mode_srcip");
        data.registerOption(m_dialog->cb_dstip, ropt,  "hashlimit_mode_dstip");
        data.registerOption(m_dialog->cb_srcport, ropt,
                            "hashlimit_mode_srcport");
        data.registerOption(m_dialog->cb_dstport, ropt,
                            "hashlimit_mode_dstport");
        data.registerOption(m_dialog->ipt_hashlimit_dstlimit, ropt,
                            "hashlimit_dstlimit");
        data.registerOption(m_dialog->ipt_hashlimit_name, ropt,
                            "hashlimit_name");
        data.registerOption(m_dialog->ipt_hashlimit_size, ropt,
                            "hashlimit_size");
        data.registerOption(m_dialog->ipt_hashlimit_max, ropt,
                            "hashlimit_max");
        data.registerOption(m_dialog->ipt_hashlimit_expire, ropt,
                            "hashlimit_expire");
        data.registerOption(m_dialog->ipt_hashlimit_gcinterval, ropt,
                            "hashlimit_gcinterval");

        // in v3.0 attribute "assume fw is part of any" used to be a
        // checkbox and therefore stored as boolean in the rule
        // options. Old "on" maps to the new "on", which means old "True"
        // maps to "1". Old "off" maps to "use global" though.
        string old_val = ropt->getStr("firewall_is_part_of_any_and_networks");
        if (old_val == "True") ropt->setStr("firewall_is_part_of_any_and_networks", "1");
        if (old_val == "False") ropt->setStr("firewall_is_part_of_any_and_networks", "");

        QStringList threeStateMapping;
        threeStateMapping.push_back(QObject::tr("Follow global setting"));
        threeStateMapping.push_back("");

        threeStateMapping.push_back(QObject::tr("On"));
        threeStateMapping.push_back("1");

        threeStateMapping.push_back(QObject::tr("Off"));
        threeStateMapping.push_back("0");

        data.registerOption(m_dialog->ipt_assume_fw_is_part_of_any, ropt,
                            "firewall_is_part_of_any_and_networks",
                            threeStateMapping);
        data.registerOption(m_dialog->ipt_stateless, ropt,  "stateless");

        data.registerOption(m_dialog->ipt_mark_connections, ropt,
                            "ipt_mark_connections");

        data.registerOption(m_dialog->classify_str, ropt, "classify_str");

        // Route
        data.registerOption(m_dialog->ipt_iif, ropt, "ipt_iif" );
        data.registerOption(m_dialog->ipt_oif, ropt, "ipt_oif" );
        data.registerOption(m_dialog->ipt_gw, ropt, "ipt_gw" );
        data.registerOption(m_dialog->ipt_continue, ropt, "ipt_continue" );
        data.registerOption(m_dialog->ipt_tee, ropt, "ipt_tee");

        FWObject *o = policy_rule->getTagObject();
        m_dialog->iptTagDropArea->setObject(o);
        m_dialog->iptTagDropArea->update();
    }


    if (platform=="ipf")
    {
        data.registerOption(m_dialog->ipf_logFacility, ropt,
                            "ipf_log_facility", logFacilities);
        data.registerOption(m_dialog->ipf_logLevel, ropt,
                            "log_level", logLevels);
        data.registerOption(m_dialog->ipf_masq_icmp, ropt,
                            "ipf_return_icmp_as_dest");
        data.registerOption(m_dialog->ipf_stateless, ropt,  "stateless");
        data.registerOption(m_dialog->ipf_keep_frags, ropt,  "ipf_keep_frags");

        // Route
        data.registerOption(m_dialog->ipf_route_option, ropt,
                            "ipf_route_option", route_options);
        data.registerOption(m_dialog->ipf_route_opt_if, ropt,
                            "ipf_route_opt_if");
        data.registerOption(m_dialog->ipf_route_opt_addr, ropt,
                            "ipf_route_opt_addr");
    }

    if (platform=="pf")
    {
        bool ge_4_5 = XMLTools::version_compare(version, "4.5")>=0;

        m_dialog->pf_no_sync->setEnabled(ge_4_5);
        m_dialog->pf_pflow->setEnabled(ge_4_5);
        
        data.registerOption(m_dialog->pf_logPrefix, ropt,
                            "log_prefix");
        data.registerOption(m_dialog->pf_stateless, ropt,
                            "stateless");
        data.registerOption(m_dialog->pf_keep_state, ropt,
                            "pf_keep_state");
        data.registerOption(m_dialog->pf_no_sync, ropt,
                            "pf_no_sync");
        data.registerOption(m_dialog->pf_pflow, ropt,
                            "pf_pflow");
        data.registerOption(m_dialog->pf_sloppy_tracker, ropt,
                            "pf_sloppy_tracker");
        data.registerOption(m_dialog->pf_rule_max_state, ropt,
                            "pf_rule_max_state");
        data.registerOption(m_dialog->pf_source_tracking, ropt,
                            "pf_source_tracking");
        data.registerOption(m_dialog->pf_max_src_nodes, ropt,
                            "pf_max_src_nodes");
        data.registerOption(m_dialog->pf_max_src_states, ropt,
                            "pf_max_src_states");
        data.registerOption(m_dialog->pf_max_src_conn, ropt,
                            "pf_max_src_conn");
        data.registerOption(m_dialog->pf_overload_table, ropt,
                            "pf_max_src_conn_overload_table");
        data.registerOption(m_dialog->pf_flush, ropt,
                            "pf_max_src_conn_flush");
        data.registerOption(m_dialog->pf_global, ropt,
                            "pf_max_src_conn_global");
        data.registerOption(m_dialog->pf_max_src_conn_rate_num, ropt,
                            "pf_max_src_conn_rate_num");
        data.registerOption(m_dialog->pf_max_src_conn_rate_seconds, ropt,
                            "pf_max_src_conn_rate_seconds");
        data.registerOption(m_dialog->pf_modulate, ropt,
                            "pf_modulate_state");
        data.registerOption(m_dialog->pf_synproxy, ropt,
                            "pf_synproxy");

        // Tag
        FWObject *o = policy_rule->getTagObject();
        m_dialog->pfTagDropArea->setObject(o);
        m_dialog->pfTagDropArea->update();

        // Classify
        data.registerOption(m_dialog->pf_classify_str, ropt, "pf_classify_str");

        // Route
        data.registerOption(m_dialog->pf_fastroute, ropt, "pf_fastroute");
        data.registerOption(m_dialog->pf_route_load_option, ropt,
                            "pf_route_load_option", route_load_options);
        data.registerOption(m_dialog->pf_route_option, ropt, "pf_route_option",
                            route_options);
        data.registerOption(m_dialog->pf_route_opt_if, ropt, "pf_route_opt_if");
        data.registerOption(m_dialog->pf_route_opt_addr, ropt, "pf_route_opt_addr");
    }

    if (platform=="ipfw")
    {
        data.registerOption(m_dialog->ipfw_stateless, ropt, "stateless");

/* #2367 */
        // Classify
        data.registerOption(m_dialog->ipfw_classify_method, ropt,
                            "ipfw_classify_method", classify_options_ipfw);
        data.registerOption(m_dialog->usePortNum, ropt, "ipfw_pipe_queue_num");
    }

    if (platform=="iosacl" || platform=="procurve_acl")
    {
        data.registerOption(m_dialog->iosacl_add_mirror_rule,
                            ropt, "iosacl_add_mirror_rule");
    }

    if (platform=="pix" || platform=="fwsm")
    {
        string vers = "version_" + version;
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
        if (Resources::platform_res[platform.toAscii().constData()]->getResourceBool(
              "/FWBuilderResources/Target/options/" +
              vers + "/pix_rule_syslog_settings"))
#else
        if (Resources::platform_res[platform.toLatin1().constData()]->getResourceBool(
              "/FWBuilderResources/Target/options/" +
              vers + "/pix_rule_syslog_settings"))
#endif
        {
            m_dialog->pix_disable_rule_log->setEnabled(true);
            m_dialog->pix_logLevel->setEnabled(true);
            m_dialog->pix_log_interval->setEnabled(true);

            data.registerOption(m_dialog->pix_disable_rule_log, ropt,
                                "disable_logging_for_this_rule");
            data.registerOption(m_dialog->pix_logLevel, ropt,
                                "log_level",logLevels);
            data.registerOption(m_dialog->pix_log_interval, ropt,
                                "log_interval");
        } else
        {
            m_dialog->pix_disable_rule_log->setEnabled(false);
            m_dialog->pix_logLevel->setEnabled(false);
            m_dialog->pix_log_interval->setEnabled(false);
        }

    }

    if (platform=="junosacl")
    {
        data.registerOption(m_dialog->counterLineEdit, ropt, "counter_name");
    }



    init = true;
    data.loadAll();

    m_dialog->pf_max_src_nodes->setEnabled(
        m_dialog->pf_source_tracking->isChecked());
    m_dialog->pf_max_src_states->setEnabled(
        m_dialog->pf_source_tracking->isChecked());


    connlimitAboveLabelChange();
    limitLabelChange();

    //apply->setEnabled(false);
    init=false;
}
예제 #16
0
void OSConfigurator_linux24::processFirewallOptions() 
{
    Configlet kernel_vars(fw, "linux24", "kernel_vars");
    kernel_vars.removeComments();
    kernel_vars.collapseEmptyStrings(true);

    FWOptions* options = fw->getOptionsObject();

    setConfigletMacroForOptionStr(options->getStr("linux24_ip_dynaddr"), &kernel_vars, "linux24_ip_dynaddr");
    setConfigletMacroForOptionStr(options->getStr("linux24_rp_filter"), &kernel_vars, "linux24_rp_filter");
    setConfigletMacroForOptionStr(options->getStr("linux24_accept_source_route"), &kernel_vars, "linux24_accept_source_route");
    setConfigletMacroForOptionStr(options->getStr("linux24_accept_redirects"), &kernel_vars, "linux24_accept_redirects");
    setConfigletMacroForOptionStr(options->getStr("linux24_log_martians"), &kernel_vars, "linux24_log_martians");
    setConfigletMacroForOptionStr(options->getStr("linux24_icmp_echo_ignore_broadcasts"), &kernel_vars, "linux24_icmp_echo_ignore_broadcasts");
    setConfigletMacroForOptionStr(options->getStr("linux24_icmp_echo_ignore_all"), &kernel_vars, "linux24_icmp_echo_ignore_all");
    setConfigletMacroForOptionStr(options->getStr("linux24_icmp_ignore_bogus_error_responses"), &kernel_vars, "linux24_icmp_ignore_bogus_error_responses");
    setConfigletMacroForOptionStr(options->getStr("linux24_tcp_window_scaling"), &kernel_vars, "linux24_tcp_window_scaling");
    setConfigletMacroForOptionStr(options->getStr("linux24_tcp_sack"), &kernel_vars, "linux24_tcp_sack");
    setConfigletMacroForOptionStr(options->getStr("linux24_tcp_fack"), &kernel_vars, "linux24_tcp_fack");
    setConfigletMacroForOptionStr(options->getStr("linux24_tcp_syncookies"), &kernel_vars, "linux24_tcp_syncookies");
    setConfigletMacroForOptionStr(options->getStr("linux24_tcp_ecn"), &kernel_vars, "linux24_tcp_ecn");
    setConfigletMacroForOptionStr(options->getStr("linux24_tcp_timestamps"), &kernel_vars, "linux24_tcp_timestamps");

    int opt = options->getInt("linux24_tcp_fin_timeout");
    setConfigletMacroForOptionInt((opt==0)?-1:opt, &kernel_vars, "linux24_tcp_fin_timeout");
    opt = options->getInt("linux24_tcp_keepalive_interval");
    setConfigletMacroForOptionInt((opt==0)?-1:opt, &kernel_vars, "linux24_tcp_keepalive_interval");

    Configlet conntrack_vars(fw, "linux24", "conntrack");
    conntrack_vars.removeComments();
    conntrack_vars.collapseEmptyStrings(true);

    string version = fw->getStr("version");
    bool version_ge_1_4 = XMLTools::version_compare(version, "1.4.0") >= 0;
    conntrack_vars.setVariable("iptables_version_ge_1_4", version_ge_1_4);
    conntrack_vars.setVariable("iptables_version_lt_1_4", !version_ge_1_4);

    // if conntrack_max and conntrack_hashsize are equal to 0, we do
    // not add commands from the configlet (so the kernel defaults are
    // used). Options above assume -1 is the default. Need to pass -1
    // instead of 0 for the conntrack vars
    opt = options->getInt("linux24_conntrack_max");
    setConfigletMacroForOptionInt(
        (opt==0)?-1:opt,
        &conntrack_vars, "conntrack_max");
    opt = options->getInt("linux24_conntrack_hashsize");
    setConfigletMacroForOptionInt(
        (opt==0)?-1:opt,
        &conntrack_vars, "conntrack_hashsize");

    // This option uses three-state control and assumes empty string is the default
    setConfigletMacroForOptionStr(
        options->getStr("linux24_conntrack_tcp_be_liberal"),
        &conntrack_vars, "conntrack_tcp_be_liberal");

    output << kernel_vars.expand().toStdString();
    output << endl;
    output << conntrack_vars.expand().toStdString();
}
예제 #17
0
/*
 * 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 "";
}