// the IP address of the gateway RGtw has to be in a network of the interface RItf
bool RoutingCompiler::contradictionRGtwAndRItf::processNext()
{
    RoutingRule *rule=getNext(); if (rule==NULL) return false;
    
    tmp_queue.push_back(rule);
    
    RuleElementRGtw *gtwrel=rule->getRGtw();
    RuleElementRItf *itfrel=rule->getRItf();
    
    FWObject *oRGtw = FWReference::cast(gtwrel->front())->getPointer();
    FWObject *oRItf = FWReference::cast(itfrel->front())->getPointer();
    
    if (oRItf->getName() == "Any") { return true; }
    
    
    if (Host::cast(oRGtw) != NULL ||
        Interface::cast(oRGtw) != NULL ||
        Address::cast(oRGtw)->dimension()==1)
    {

        const InetAddr* ip_interface = NULL;

        if ( Host::cast(oRGtw) != NULL)
        {
            Host *host=Host::cast(oRGtw);
            ip_interface = host->getAddressPtr();
        } else if (Interface::cast(oRGtw) != NULL)
        {
            Interface *intf=Interface::cast(oRGtw);
            ip_interface = intf->getAddressPtr();
        } else if (Address::cast(oRGtw)->dimension()==1)
        {
            Address *ipv4 = Address::cast(oRGtw);
            ip_interface = ipv4->getAddressPtr();
        }

        if (ip_interface)
        {
            list<FWObject*> obj_list = oRItf->getByType(IPv4::TYPENAME);
            for (list<FWObject*>::iterator i=obj_list.begin();
                 i!=obj_list.end(); ++i) 
            {
                Address *addr = Address::cast(*i);
                if (addr->belongs(*ip_interface))
                    return true;
            }
        }

        string msg;
        msg = "Object \"" + oRGtw->getName() +
            "\" used as gateway in the routing rule " +
            rule->getLabel() +
            " is not in the same local network as interface " +
            oRItf->getName();
        compiler->abort(rule, msg.c_str());
    }

    return true;
}
string RoutingCompiler::debugPrintRule(Rule *r)
{
    RoutingRule *rule = RoutingRule::cast(r);

    RuleElementRDst *dstrel = rule->getRDst();
    RuleElementRItf *itfrel = rule->getRItf();
    RuleElementRGtw *gtwrel = rule->getRGtw();

    ostringstream str;

//    str << setw(70) << setfill('-') << "-";

    string dst, itf, gtw;
   
    FWObject *obj = FWReference::getObject(itfrel->front());
    itf = (obj) ? obj->getName() : "NULL";

    obj = FWReference::getObject(gtwrel->front());
    gtw = (obj) ? obj->getName() : "NULL";
     
    
    int no = 0;
    FWObject::iterator i1 = dstrel->begin();
    while ( i1!=dstrel->end())
    {
        str << endl;

        dst = " ";

        if (i1 != dstrel->end())
        {
            FWObject *o = FWReference::getObject(*i1);
            dst = (o) ? o->getName() : "NULL";
        }

        int w = 0;
        if (no==0)
        {
            str << rule->getLabel();
            w = rule->getLabel().length();
        }
        
        str <<  setw(10-w)  << setfill(' ') << " ";

        str <<  setw(18) << setfill(' ') << dst.c_str() << " ";
        str <<  setw(18) << setfill(' ') << itf.c_str() << " ";
        str <<  setw(18) << setfill(' ') << gtw.c_str() << " ";
        str <<  setw(18) << setfill(' ') << " ";

        ++no;

        if ( i1 != dstrel->end() ) ++i1;
    }
    return str.str();
}
// Invalid routing destination network: network address and netmask mismatch. 
bool RoutingCompiler::validateNetwork::processNext()
{
    RoutingRule *rule=getNext(); if (rule==NULL) return false;
    
    tmp_queue.push_back(rule);
    
    RuleElementRDst *dstrel=rule->getRDst();
    FWObject *o = FWReference::cast(dstrel->front())->getPointer();
     
    // currently we do not support run-time DNSName and AddressTable objects
    // in routing rules.
    MultiAddress *ma = MultiAddress::cast(o);
    if (ma && ma->isRunTime()) 
    {
        compiler->abort(rule, "Use of dynamic run-time objects "
                        "as destination in routing rules is not supported.");
    }

    if( checkValidNetwork(o) == false)
    {
        string msg;
        msg = "Object \"" + o->getName() +
            "\" used as destination in the routing rule " +
            rule->getLabel() + " has invalid netmask";
        compiler->abort(rule, msg.c_str());
    }
    return true;
    
}
void ObjectManipulator::unlockObject()
{
    if (fwbdebug)
        qDebug() << "ObjectManipulator::unlockObject selected:"
                 << getCurrentObjectTree()->getNumSelected();

    if (getCurrentObjectTree()->getNumSelected()==0) return;

    try
    {
        FWObject *obj;

        vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
        for (vector<FWObject*>::iterator i=so.begin();  i!=so.end(); ++i)
        {
            obj= *i;
            FWObject *lib = obj->getLibrary();
            if (lib->getId()!=FWObjectDatabase::STANDARD_LIB_ID)
            {
                std::auto_ptr<FWCmdLockObject> cmd(
                    new FWCmdLockObject(m_project, obj, tr("Unlock object ") +
                                        QString::fromUtf8(obj->getName().c_str())));
                FWObject* new_state = cmd->getNewState();
                new_state->setReadOnly(false);
                if (!cmd->getOldState()->cmp(new_state, true))
                    m_project->undoStack->push(cmd.release());
            }
        }
    } catch (FWException &ex)
    {
        qDebug() << ex.toString().c_str();
    }
}
/*
 * checks if one of the children of RuleElement is a host, IPv4 or
 * network object with address 0.0.0.0 and netmask 0.0.0.0.
 *
 * Exceptions: 
 *   - object 'any'
 *   - interface with dynamic address.
 *
 * In addition check for address A.B.C.D/0 which is most likely a
 * mistake if A.B.C.D != 0.0.0.0. See #475
 */
Address* PolicyCompiler::checkForZeroAddr::findZeroAddress(RuleElement *re)
{
    Address *a=NULL;

    for (FWObject::iterator i=re->begin(); i!=re->end(); i++) 
    {
        FWObject *o = FWReference::getObject(*i);
	assert(o!=NULL);

        MultiAddress *maddr = MultiAddress::cast(o);
        if (maddr && maddr->isRunTime()) continue;

        Address *addr = Address::cast(o);
        
        if (addr==NULL && o!=NULL)
            compiler->warning(
                    re->getParent(), 
                    string("findZeroAddress: Unknown object in rule element: ") +
                    o->getName() +
                    "  type=" + o->getTypeName());

        if (addr && addr->hasInetAddress())
        {
            if (Interface::cast(o)!=NULL && 
                (Interface::cast(o)->isDyn() ||
                 Interface::cast(o)->isUnnumbered() ||
                 Interface::cast(o)->isBridgePort()))
                continue;

            if ( ! addr->isAny())
            {
                const InetAddr *ad = addr->getAddressPtr();
                const InetAddr *nm = addr->getNetmaskPtr();
                // AddressRange has address but not netmask
                // AddressRange with address 0.0.0.0 is acceptable
                // (not equivalent to "any")
                if (ad->isAny() && nm!=NULL && nm->isAny())
                {
                    a = addr;
                    break;
                }
                // Address A.B.C.D/0 is most likely a mistake if
                // A.B.C.D != 0.0.0.0
                if ((Network::cast(addr) || NetworkIPv6::cast(addr)) &&
                    !ad->isAny() && nm!=NULL && nm->isAny())
                {
                    a = addr;
                    break;
                }
            }
        }
    }

    return a;
}
void ProjectPanel::fileExport()
{
    LibExportDialog ed;
    list<FWObject*>  selectedLibs;
    map<int,FWObject*>::iterator i;
    int lib_idx = -1;
    do
    {
        if (ed.exec()!=QDialog::Accepted) return;

        QList<QListWidgetItem*> selitems = ed.m_dialog->libs->selectedItems();

        for (i=ed.mapOfLibs.begin(); i!=ed.mapOfLibs.end(); i++)
            if (selitems.contains(ed.m_dialog->libs->item(i->first)))
                selectedLibs.push_back(i->second);

        lib_idx=ed.m_dialog->libs->currentRow ();

        if (lib_idx<0 || selectedLibs.size()==0)
        {
            QMessageBox::critical(
                this,"Firewall Builder",
                tr("Please select a library you want to export."),
                "&Continue", QString::null,QString::null,
                0, 1 );

            return;
        }
    } while (!exportLibraryTest(selectedLibs));

    FWObject *selLib = ed.mapOfLibs[ lib_idx ];
    QString path = st->getOpenFileDir() + QString::fromUtf8(selLib->getName().c_str()) + ".fwl";

    resetFD();

    QString fname = QFileDialog::getSaveFileName(
        this,
        "Choose a filename to save under",
        path,
        "Firewall Builder library files (*.fwl)");

    if (fname.isEmpty()) return;

    if (QFile::exists(fname) &&
         QMessageBox::warning(
             this,"Firewall Builder",
             tr("The file %1 already exists.\nDo you want to overwrite it ?")
             .arg(fname),
             tr("&Yes"), tr("&No"), QString::null,
             0, 1 )==1 ) return;

    st->setOpenFileDir(path);
    exportLibraryTo(fname,selectedLibs,ed.m_dialog->exportRO->isChecked());
}
bool PolicyCompiler::InterfacePolicyRules::processNext()
{
    PolicyRule *rule = getNext(); if (rule==NULL) return false;

    RuleElementItf *itfre = rule->getItf(); assert(itfre);
    if (itfre->isAny())
    {
//        rule->setInterfaceId(-1);
        tmp_queue.push_back(rule);
        return true;
    }

    for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i)
    {
        FWObject *o = FWReference::getObject(*i);
        if (ObjectGroup::isA(o))
        {
            // a group in "interface" rule element. GUI checks that only
            // interfaces are allowed in such group, but we should check anyway.
            for (FWObject::iterator i=o->begin(); i!=o->end(); ++i)
            {
                FWObject *o1 = FWReference::getObject(*i);
                if (!Interface::isA(o1))
                {
                    compiler->warning(
                        "Object '" + o1->getName() +
                        "', which is not an interface, is a member of the group '" +
                        o->getName() +
                        "' used in 'Interface' element of a rule.");
                    continue;
                }
                PolicyRule *r= compiler->dbcopy->createPolicyRule();
                compiler->temp_ruleset->add(r);
                r->duplicate(rule);
                RuleElementItf *nitf = r->getItf();
                nitf->clearChildren();
                nitf->setAnyElement();
                nitf->addRef(o1);
                tmp_queue.push_back(r);
            }
        } else
        {
            PolicyRule *r= compiler->dbcopy->createPolicyRule();
            compiler->temp_ruleset->add(r);
            r->duplicate(rule);
            RuleElementItf *nitf = r->getItf();
	    nitf->clearChildren();
	    nitf->setAnyElement();
            nitf->addRef(o);
            tmp_queue.push_back(r);
        }
    }
    return true;
}
void ObjectManipulator::autorenameVlans(list<FWObject*> &obj_list)
{
    for (list<FWObject*>::iterator j=obj_list.begin(); j!=obj_list.end(); ++j)
    {
        FWObject *obj = *j;
        FWObject *parent = obj->getParent();
        FWObject *fw = parent;
        while (fw && Firewall::cast(fw)==NULL) fw = fw->getParent();
        assert(fw);
        QString obj_name = QString::fromUtf8(obj->getName().c_str());

        std::auto_ptr<interfaceProperties> int_prop(
            interfacePropertiesObjectFactory::getInterfacePropertiesObject(fw));

        if (int_prop->looksLikeVlanInterface(obj_name))
        {
            // even though we only call this function if the type of
            // this interface is 8021q, need to check its naming
            // schema as well. We can't automatically rename
            // interfaces that do not follow known naming convention.

            QString base_name;
            int vlan_id;
            int_prop->parseVlan(obj_name, &base_name, &vlan_id);
            if (base_name != "vlan")
            {
                QString new_name = QString("%1.%2")
                    .arg(QString::fromUtf8(
                             parent->getName().c_str()))
                    .arg(vlan_id);
                if (new_name != QString::fromUtf8(obj->getName().c_str()))
                {
                    FWCmdChange* cmd = new FWCmdChangeName(m_project, obj);
                    FWObject* new_state = cmd->getNewState();
                    new_state->setName(string(new_name.toUtf8()));
                    m_project->undoStack->push(cmd);
                }
            }
        }
    }
}
Exemple #9
0
void ProjectPanel::updateFirewallName()
{
    if (visibleRuleSet==NULL) return ;
    QString name;
//     mw->buildEditorTitleAndIcon(visibleRuleSet, ObjectEditor::optNone,
//                                 &name, NULL, false);
//    name = "<b>" + name  + "</b>";
    FWObject *fw = visibleRuleSet->getParent();
    name = QString("%1 / %2")
           .arg(QString::fromUtf8(fw->getName().c_str()))
           .arg(QString::fromUtf8(visibleRuleSet->getName().c_str()));
    m_panel->rulesetname->setText(name );
}
void RuleOptionsDialog::fillInterfaces(QComboBox* cb)
{
    QSet<QString> deduplicated_interface_names;

    list<FWObject*> interfaces = firewall->getByTypeDeep(Interface::TYPENAME);
    for (list<FWObject*>::iterator i=interfaces.begin(); i!=interfaces.end(); ++i)
    {
        Interface *iface = Interface::cast(*i);
        assert(iface);

        if (iface->isLoopback()) continue;

        deduplicated_interface_names.insert(iface->getName().c_str());

        if (Cluster::isA(firewall))
        {
            FailoverClusterGroup *failover_group =
                FailoverClusterGroup::cast(
                    iface->getFirstByType(FailoverClusterGroup::TYPENAME));
            if (failover_group)
            {
                for (FWObject::iterator it=failover_group->begin();
                     it!=failover_group->end(); ++it)
                {
                    FWObject *mi = FWReference::getObject(*it);
                    if (Interface::isA(mi) && ! iface->isLoopback())
                    {
                        deduplicated_interface_names.insert(mi->getName().c_str());
                    }
                }
            }
        }
    }

    QStringList sorted_interfaces;
    QSetIterator<QString> it(deduplicated_interface_names);
    while (it.hasNext())
    {
        sorted_interfaces << it.next();
    }
    sorted_interfaces.sort();

    cb->clear();
    cb->addItem("");
    cb->addItems(sorted_interfaces);
}
void PrintingController::findAllGroups(list<FWObject*> &objects,
                                       list<FWObject*> &groups)
{
    if (fwbdebug) qDebug("findAllGroups: arg1 size %d", int(objects.size()));
    for (FWObject::iterator obj=objects.begin(); obj!=objects.end(); ++obj)
    {
        if (fwbdebug) qDebug("   %s",(*obj)->getName().c_str());
        FWObject *o = *obj;
        if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
        if (Group::cast(o)!=NULL &&
            std::find(groups.begin(),groups.end(),o)==groups.end())
        {
            groups.push_back(o);
            if (fwbdebug) qDebug("Add group %s to groups",o->getName().c_str());
            findAllGroups(*o,groups);
        }
    }
}
//  the IP address of the gateway has to be in a local network of the firewall
bool RoutingCompiler::reachableAddressInRGtw::processNext()
{
    RoutingRule *rule=getNext(); if (rule==NULL) return false;
    tmp_queue.push_back(rule);
    
    RuleElementRGtw *gtwrel=rule->getRGtw();
    FWObject *o = FWReference::cast(gtwrel->front())->getPointer();
              
    if( checkReachableIPAddress(o) == false)
    {
        string msg;
        msg = "Object \"" + o->getName() +
            "\" used as gateway in the routing rule " +
            rule->getLabel() +
            " is not reachable because it is not in any local network of the firewall";
        compiler->abort(rule, msg.c_str());
    }
    return true;
}
bool RoutingCompiler::rItfChildOfFw::processNext()
{
    RoutingRule *rule=getNext(); if (rule==NULL) return false;
    tmp_queue.push_back(rule);
    
    RuleElementRItf *itfrel = rule->getRItf();

    if (itfrel->isAny()) return true;

    FWObject *o = FWReference::cast(itfrel->front())->getPointer();

    // the interface is not a child of the firewall. Could be
    // cluster interface though. In that case make sure the
    // firewall is a member of that cluster.
    Interface *iface = Interface::cast(o);
    if (iface)
    {
        FWObject *parent = Host::getParentHost(iface);
        //FWObject *parent = iface->getParentHost();
        if (parent->getId() == compiler->fw->getId()) return true;

        Cluster *cluster = Cluster::cast(parent);
        if (cluster)
        {            
            list<Firewall*> members;
            cluster->getMembersList(members);
            list<Firewall*>::iterator it;
            for (it=members.begin(); it!=members.end(); ++it)
            {
                if ((*it)->getId() == compiler->fw->getId()) return true;
            }
        }
    }
    string msg;
    msg = "Object \"" + o->getName() + 
        "\" used as interface in the routing rule " +
        rule->getLabel() +
        " is not a child of the firewall the rule belongs to";
    compiler->abort(rule, msg.c_str());
    // even though we call abort() here, it does not actually stop the
    // program if it runs in the test mode.
    return true;
}
bool RoutingCompiler::singleAdressInRGtw::processNext()
{
    RoutingRule *rule=getNext(); if (rule==NULL) return false;
    tmp_queue.push_back(rule);
    
    RuleElementRGtw *gtwrel=rule->getRGtw();

    FWObject *o = FWReference::getObject(gtwrel->front());
              
    if( gtwrel->checkSingleIPAdress(o) == false)
    {       
        string msg;
        msg = "Object \"" + o->getName() +
            "\" used as a gateway in the routing rule " +
            rule->getLabel() + " has multiple ip adresses";
        compiler->abort(rule, msg.c_str());
    }
    return true;
}
void ObjectManipulator::autorename(list<FWObject*> &obj_list,
                                   const string &objtype,
                                   const string &namesuffix)
{
    for (list<FWObject*>::iterator j=obj_list.begin(); j!=obj_list.end(); ++j)
    {
        FWObject *obj = *j;
        QString old_name = obj->getName().c_str();
        FWObject *parent = obj->getParent();
        QString name = getStandardName(parent, objtype, namesuffix);
        name = makeNameUnique(parent, name, objtype.c_str());
        if (name != old_name)
        {
            FWCmdChange* cmd = new FWCmdChangeName(m_project, obj);
            FWObject* new_state = cmd->getNewState();
            new_state->setName(string(name.toUtf8()));
            m_project->undoStack->push(cmd);
        }
    }
}
void ObjectManipulator::lockObject()
{
    if (fwbdebug)
        qDebug() << "ObjectManipulator::lockObject selected:"
                 << getCurrentObjectTree()->getNumSelected();

    if (getCurrentObjectTree()->getNumSelected()==0) return;

    try
    {
        FWObject *obj;

        vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
        for (vector<FWObject*>::iterator i=so.begin();  i!=so.end(); ++i)
        {
            obj= *i;
            FWObject *lib = obj->getLibrary();
            // these lbraries are locked anyway, do not let the user
            // lock objects inside because they won't be able to unlock them.
            if (lib->getId()!=FWObjectDatabase::STANDARD_LIB_ID)
            {
                std::auto_ptr<FWCmdLockObject> cmd(
                    new FWCmdLockObject(m_project, obj, tr("Lock object ") +
                                        QString::fromUtf8(obj->getName().c_str())));
                FWObject* new_state = cmd->getNewState();
                new_state->setReadOnly(true);
                if (!cmd->getOldState()->cmp(new_state, true))
                    m_project->undoStack->push(cmd.release());
            }
        }
        // Arguably, locking an object should not change lastModified timestamp
        // because none of the attributes that affect generated policy change.
        //QCoreApplication::postEvent(
        //    mw, new dataModifiedEvent(m_project->getFileName(), 0));
    } catch (FWException &ex)
    {
        qDebug() << ex.toString().c_str();
    }
}
string PolicyCompiler_ipf::debugPrintRule(Rule *r)
{
    PolicyRule *rule=PolicyRule::cast(r);
//    FWOptions  *ruleopt =rule->getOptionsObject();

    ostringstream s;
    s << PolicyCompiler::debugPrintRule(rule) << " ";

    RuleElementItf *intf_re = rule->getItf();
    string rule_interfaces;
    int intf_count = 0;
    for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it)
    {
        FWObject *o   = *it;
        if (FWReference::cast(o)!=NULL) o = FWReference::cast(o)->getPointer();
        rule_interfaces += " " + o->getName();
        intf_count++;
    }
    if (intf_count > 0)
    {
        s << " intf: ";
        if (intf_count > 1) s << "{ ";
        s << rule_interfaces;
        if (intf_count > 1) s << " }";
    }
    else
        s << " intf: ?";

    s << " ";

    if (r->getBool("skip_check_for_duplicates")) s << "skip_check_for_duplicates ";
    if (r->getStr("skip_label")!="")             s << "skip_label: " << r->getStr("skip_label") << " ";
    if (r->getStr("skip_to")!="")                s << "skip_to: "    << r->getStr("skip_to")    << " ";
    if (r->getInt("no_to_skip")!=-1)             s << "no_to_skip: " << r->getInt("no_to_skip");

    s << " " << FWObjectDatabase::getStringId(r->getId()) << " (" << r->getId() << ")";

    return s.str();
}
void NATCompiler_pf::PrintRule::_printInterface(NATRule *rule)
{
    RuleElementItf *intf_re = rule->getItfOutb();
    QStringList rule_interfaces;

    if ( ! intf_re->isAny())
    {
        for (FWObject::iterator it=intf_re->begin(); it!=intf_re->end(); ++it)
        {
            FWObject *o = FWObjectReference::getObject(*it);
            rule_interfaces << o->getName().c_str();
        }
        if (rule_interfaces.size() > 1)
        {
            rule_interfaces.push_front("{");
            rule_interfaces.push_back("}");
        }
        compiler->output << "on "
                         << string((intf_re->getBool("single_object_negation")) ? "! " : " ")
                         << rule_interfaces.join(" ").toStdString()
                         << " ";
    }
}
FWObject* ObjectManipulator::actuallyPasteTo(FWObject *target,
                                              FWObject *obj,
                                              std::map<int,int> &map_ids)
{
    //FWObject *res = NULL;

    FWObject *ta = prepareForInsertion(target, obj);
    if (ta == NULL) return NULL;

    if (!isObjectAllowed(ta, obj)) return NULL;

    // we disable copy/cut/paste/duplicate menu items for objects that
    // can't be copied or duplicated in
    // ObjectManipulator::getMenuState() but will check here just in
    // case
    if (AttachedNetworks::isA(obj)) return NULL;

    if (fwbdebug)
        qDebug() << "ObjectManipulator::actuallyPasteTo"
                 << "target=" << target->getPath().c_str()
                 << "ta=" << ta->getPath().c_str();

    QString new_name = makeNameUnique(
        ta, obj->getName().c_str(), obj->getTypeName().c_str());

    try
    {
/* clipboard holds a copy of the object */
        if (obj->getRoot() != ta->getRoot())
        {
            if (fwbdebug) qDebug("Copy object %s (%d) to a different object tree",
                                 obj->getName().c_str(), obj->getId());
            FWCmdAddObject *cmd = new FWCmdAddObject(m_project, target, NULL,
                                                     QObject::tr("Paste object"));
            FWObject *new_state = cmd->getNewState();
            cmd->setNeedTreeReload(true);
            // recursivelyCopySubtree() needs access to the target tree root
            // when it copies subtree, so have to copy into the actual target
            // tree.
            FWObject *nobj = m_project->db()->recursivelyCopySubtree(target, obj, map_ids);
            if (new_name != nobj->getName().c_str())
                nobj->setName(string(new_name.toUtf8()));
            target->remove(nobj, false);
            new_state->add(nobj);
            m_project->undoStack->push(cmd);
            return nobj;
        }

        Group *grp = Group::cast(ta);
        if (grp!=NULL && !FWBTree().isSystem(ta))
        {
            if (fwbdebug) qDebug("Copy object %s (%d) to a regular group",
                                 obj->getName().c_str(), obj->getId());
/* check for duplicates. We just won't add an object if it is already there */
            int cp_id = obj->getId();
            list<FWObject*>::iterator j;
            for (j=grp->begin(); j!=grp->end(); ++j)
            {
                FWObject *o1=*j;
                if(cp_id==o1->getId()) return o1;

                FWReference *ref;
                if( (ref=FWReference::cast(o1))!=NULL &&
                    cp_id==ref->getPointerId()) return o1;
            }
            FWCmdChange *cmd = new FWCmdChange(
                m_project, grp,
                QObject::tr("Paste object"));
            //cmd->setNeedTreeReload(false);
            FWObject *new_state = cmd->getNewState();
            new_state->addRef(obj);
            m_project->undoStack->push(cmd);
            return obj;

        } else
        {
/* add a copy of the object to system group , or
 * add ruleset object to a firewall.
 */
            if (fwbdebug)
                qDebug("Copy object %s (%d) to a system group, "
                       "a ruleset to a firewall or an address to an interface",
                       obj->getName().c_str(), obj->getId());

            FWObject *nobj = m_project->db()->create(obj->getTypeName());
            assert(nobj!=NULL);
            //nobj->ref();
            nobj->duplicate(obj, true);
            if (new_name != nobj->getName().c_str())
                nobj->setName(string(new_name.toUtf8()));

            // If we paste interface, reset the type of the copy
            // See #299
            if (Interface::isA(obj) && Interface::isA(ta))
            {
                Interface *new_intf = Interface::cast(nobj);
                new_intf->getOptionsObject()->setStr("type", "ethernet");
                // see #391 : need to reset "mamagement" flag in the copy
                // to make sure we do not end up with two management interfaces
                new_intf->setManagement(false);
            }

            FWCmdChange *cmd = new FWCmdAddObject(m_project, ta, nobj,
                                                  QObject::tr("Paste object"));
            FWObject *new_state = cmd->getNewState();

            // adding object to new_state is reduntant but
            // FWCmdAddObject supports this for consistency
            new_state->add(nobj);
            m_project->undoStack->push(cmd);

            return nobj;
        }
    }
    catch(FWException &ex)
    {
        QMessageBox::warning(
            this,"Firewall Builder",
            ex.toString().c_str(),
            "&Continue", QString::null,QString::null,
            0, 1 );
    }

    return NULL;
}
string PolicyCompiler::debugPrintRule(Rule *r)
{
    PolicyRule *rule=PolicyRule::cast(r);

//    FWOptions *ruleopt =rule->getOptionsObject();

    RuleElementSrc *srcrel = rule->getSrc();
    RuleElementDst *dstrel = rule->getDst();
    RuleElementSrv *srvrel = rule->getSrv();
    RuleElementItf *itfrel = rule->getItf();

//    int iface_id = rule->getInterfaceId();
//    Interface *rule_iface = Interface::cast(dbcopy->findInIndex(iface_id));

    ostringstream str;

//    str << setw(70) << setfill('-') << "-";

    int no=0;
    FWObject::iterator i1=srcrel->begin();
    FWObject::iterator i2=dstrel->begin(); 
    FWObject::iterator i3=srvrel->begin();
    FWObject::iterator i4=itfrel->begin();

    while ( i1!=srcrel->end() || i2!=dstrel->end() || i3!=srvrel->end() ||
            i4!=itfrel->end())
    {
        str << endl;

        string src=" ";
        string dst=" ";
        string srv=" ";
        string itf=" ";

        int src_id = -1;
        int dst_id = -1;
        int srv_id = -1;

        if (srcrel->getNeg()) src = "!";
        if (dstrel->getNeg()) dst = "!";
        if (srvrel->getNeg()) srv = "!";
        if (itfrel->getNeg()) itf = "!";

        if (i1!=srcrel->end())
        {
            FWObject *o = FWReference::getObject(*i1);
            src += o->getName();
            src_id = o->getId();
        }

        if (i2!=dstrel->end())
        {
            FWObject *o = FWReference::getObject(*i2);
            dst += o->getName();
            dst_id = o->getId();
        }

        if (i3!=srvrel->end())
        {
            FWObject *o = FWReference::getObject(*i3);
            srv += o->getName();
            srv_id = o->getId();
        }

        if (i4!=itfrel->end())
        {
            ostringstream str;
            FWObject *o = FWReference::getObject(*i4);
            str << o->getName() << "(" << o->getId() << ")";
            itf += str.str();
        }

        int w = 0;
        if (no==0)
        {
            str << rule->getLabel();
            w = rule->getLabel().length();
        }
        
        str <<  setw(10-w)  << setfill(' ') << " ";

        str <<  setw(18) << setfill(' ') << src.c_str() << "(" << src_id << ")";
        str <<  setw(18) << setfill(' ') << dst.c_str() << "(" << dst_id << ")";
        str <<  setw(12) << setfill(' ') << srv.c_str() << "(" << srv_id << ")";
        str <<  setw(8)  << setfill(' ') << itf.c_str();

        if (no==0)
        {
            str <<  setw(9)  << setfill(' ') << rule->getActionAsString().c_str();
            str <<  setw(12)  << setfill(' ') << rule->getDirectionAsString().c_str();
            if (rule->getLogging()) str << " LOG";
        } else
            str <<  setw(18)  << setfill(' ') << " ";

        ++no;

        if ( i1!=srcrel->end() ) ++i1;
        if ( i2!=dstrel->end() ) ++i2;
        if ( i3!=srvrel->end() ) ++i3;
        if ( i4!=itfrel->end() ) ++i4;
    }
    return str.str();
}
void CompilerDriver_pix::pixClusterGroupChecks(ClusterGroup *cluster_group)
{
    FWObject *cluster = cluster_group;
    while (cluster && !Cluster::isA(cluster)) cluster = cluster->getParent();

    FWObject *cluster_interface = NULL;
    FWObject *p = cluster_group->getParent();
    if (Interface::isA(p)) cluster_interface = p;

    map<QString, const InetAddrMask*> addresses_and_masks;

    for (FWObjectTypedChildIterator it = cluster_group->findByType(FWObjectReference::TYPENAME);
         it != it.end(); ++it)
    {
        Interface *member_iface = Interface::cast(FWObjectReference::getObject(*it));
        assert(member_iface);
        FWObject *member = Host::getParentHost(member_iface);
        //FWObject *member = member_iface->getParentHost();

        if (cluster_interface)
        {
            // check consistency of the names.
            // In case of PIX the name of the cluster interface should match 
            // names of member interfaces
            if (cluster_interface->getName() != member_iface->getName())
            {
                QString err("Names of interfaces used in state synchronization "
                            "or failover group must match the name of the "
                            "cluster inetrface. Interface %1:%2 has the name "
                            "that is different from the cluster interface name %3");

                abort(cluster, NULL, NULL,
                      err.arg(member->getName().c_str())
                      .arg(member_iface->getName().c_str())
                      .arg(cluster_interface->getName().c_str()).toStdString());
                throw FatalErrorInSingleRuleCompileMode();
            }
        }

        if (StateSyncClusterGroup::isA(cluster_group) &&
            !member_iface->isDedicatedFailover())
        {
            QString err("Interface %1 is used in a state synchronization "
                        "but is not marked as 'Dedicated Failover' "
                        "interface. All interfaces used for the state "
                        "synchronization or failover must be marked "
                        "'Dedicated Failover'. ");

            abort(member, NULL, NULL,
                  err.arg(member_iface->getName().c_str()).toStdString());
            throw FatalErrorInSingleRuleCompileMode();
        }

        if (!member_iface->isRegular() || member_iface->countInetAddresses(true)==0)
        {
            QString err("Interface %1 which is used in state synchronization "
                        "or failover group does not have an IP address. "
                        "All interfaces used for the state "
                        "synchronization or failover must have ip addresses.");

            abort(member, NULL, NULL,
                  err.arg(member_iface->getName().c_str()).toStdString());
            throw FatalErrorInSingleRuleCompileMode();
        }
        QString key("%1:%2");

        FWObjectTypedChildIterator it_addr = member_iface->findByType(IPv4::TYPENAME);
        IPv4* addr = IPv4::cast(*it_addr);
        addresses_and_masks[key.arg(member->getName().c_str()).arg(member_iface->getName().c_str())] =
            addr->getInetAddrMaskObjectPtr();
    }
    
    if (addresses_and_masks.size() >= 2)
    {
        QString first_key;
        const InetAddr *first_network_addr = NULL;
        map<QString, const InetAddrMask*>::iterator it;
        for (it=addresses_and_masks.begin(); it!=addresses_and_masks.end(); ++it)
        {
            QString key = it->first;
            const InetAddrMask *am = it->second;
            if (first_network_addr == NULL)
            {
                first_key = key;
                first_network_addr = am->getNetworkAddressPtr();
            } else
            {
                const InetAddr *network_addr = am->getNetworkAddressPtr();
                if (*first_network_addr != *(network_addr))
                {
                    QString err("Interfaces used in state synchronization "
                                "or failover group must have IP addresses on "
                                "the same subnet. Interfaces %1 and %2 have "
                                "addresses on different subnets: %3 , %4");

                    abort(cluster, NULL, NULL,
                          err.arg(first_key).arg(key)
                          .arg(first_network_addr->toString().c_str())
                          .arg(network_addr->toString().c_str()).toStdString());
                    throw FatalErrorInSingleRuleCompileMode();
                }
            }
        }
    }
}
Exemple #22
0
int main(int argc, char * const *argv)
{   
    operands ops;

    string objtype;
    string name;
    string object;
    string group;
    string parent;
    string comment_txt;
    bool list_children = false;
    bool recursive = false;
    string list_format = "%path%";
    bool full_dump = false;
    string import_config;
    bool deduplicate = false;

    if (argc<=1)
    {
        usage();
        exit(1);
    }

    /*
     *  Command line format:
     *  fwbedit command [options]
     *
     *  argv[1] is always command
     */
    cmd_str = string(argv[1]);

    cmd = NONE;
    if (cmd_str=="new") cmd = NEWOBJECT;
    if (cmd_str=="delete") cmd = DELOBJECT;
    if (cmd_str=="modify") cmd = MODOBJECT;
    if (cmd_str=="add") cmd = ADDGRP;
    if (cmd_str=="remove") cmd = REMGRP;
    if (cmd_str=="list") cmd = LIST;
    if (cmd_str=="upgrade") cmd = UPGRADE;
    if (cmd_str=="checktree") cmd = STRUCT;
    if (cmd_str=="merge") cmd = MERGE;
    if (cmd_str=="import") cmd = IMPORT;

    char * const *args = argv;
    args++;
    argc--;

    int   opt;

    switch (cmd)
    {
    case NEWOBJECT:
    {
        // -f file.fwb -t objtype -n name -c comment -p parent [-a attrs]
        while( (opt=getopt(argc, args, "f:t:n:c:p:a:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 't': objtype = optarg; break;
            case 'n': name = optarg; break;
            case 'c': comment_txt = optarg; break;
            case 'p': parent = optarg; break;
            case 'a':
                int num=0;
                if (optarg!=NULL)
                {
                    string str = optarg;
                    num = splitStr(',', str, &ops);
                }
                break;
            }
        }

        if (filename=="")
        {
            usage_new();
            exit(1);
        }

        break;
    }

    case DELOBJECT:
        // -f file.fwb -o object_def
        // object_def can be either full path or object ID
        while( (opt=getopt(argc, args, "f:o:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 'o': object = optarg; break;
            }
        }

        if (filename.empty() || object.empty())
        {
            usage_delete();
            exit(1);
        }

        break;

    case MODOBJECT:
    {
        // -f file.fwb -o object -c comment [-a attrs]
        while( (opt=getopt(argc, args, "f:o:c:a:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 'o': object = optarg; break;
            case 'c': comment_txt = optarg; break;
            case 'a':
                int num=0;
                if (optarg!=NULL)
                {
                    string str = optarg;
                    num = splitStr(',', str, &ops);
                }
                break;
            }
        }

        if (filename.empty() || object.empty())
        {
            usage_modify();
            exit(1);
        }

        break;
    }

    case ADDGRP:
    case REMGRP:
        // -f file.fwb -p group -o object
        // Add/remove object to group
        // both group and object can be either path or ID
        while( (opt=getopt(argc, args, "f:g:o:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 'g': group = optarg; break;
            case 'o': object = optarg; break;
            }
        }

        if (filename.empty() || group.empty() || object.empty())
        {
            if (cmd == ADDGRP) usage_add();
            if (cmd == REMGRP) usage_remove();
            exit(1);
        }

        break;

    case LIST:
        // -f file.fwb -o object [-r] [-Fformat_string] [-d]
        // object can be either path or ID
        while( (opt=getopt(argc, args, "f:o:crdF:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 'o': object = optarg; break;
            case 'c': list_children = true; break;
            case 'r': recursive = true; break;
            case 'F': list_format = optarg; break;
            case 'd': full_dump = true; break;
            }
        }

        if (filename.empty() || object.empty())
        {
            usage_list();
            exit(1);
        }

        break;

    case UPGRADE:
        // -f file.fwb
        autoupgrade_flag = true;
        while( (opt=getopt(argc, args, "f:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            }
        }

        if (filename.empty())
        {
            usage_upgrade();
            exit(1);
        }

        break;

    case STRUCT:
        // -f file.fwb
        while( (opt=getopt(argc, args, "f:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            }
        }

        if (filename.empty())
        {
            usage_checktree();
            exit(1);
        }

        break;
    
    case MERGE:
        // -f file1.fwb -i file2.fwb
        while( (opt=getopt(argc, args, "f:i:c:")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 'i': filemerge = optarg; break;
            case 'c': conflict_res = atoi(optarg); break;
            }
        }

        if (filename.empty() || filemerge.empty())
        {
            usage_merge();
            exit(1);
        }

        break;

    case IMPORT:
        // -f file.fwb -i config.txt -o /User/Firewalls/new_firewall
        while( (opt=getopt(argc, args, "f:i:o:d")) != EOF )
        {
            switch(opt)
            {
            case 'f': filename = optarg; break;
            case 'i': import_config = optarg; break;
            case 'o': object = optarg; break;
            case 'd': deduplicate = true; break;
            }
        }

        if (filename.empty() || import_config.empty() || object.empty())
        {
            usage_import();
            exit(1);
        }

        break;

    case NONE:
        break;
    }

    if (cmd==NONE || filename=="")
    {
        usage();
        exit(1);
    }

    init(argv);

    try 
    {
        new Resources(Constants::getResourcesFilePath());

        /* create database */
        objdb = new FWObjectDatabase();

        /* load the data file */
        UpgradePredicate upgrade_predicate(autoupgrade_flag); 

        objdb->load(filename,  &upgrade_predicate, Constants::getDTDDirectory());
    
        if (cmd == MERGE)
        {
            if (filemerge.empty())
            {
                cerr << "The name of the file that should be merged is missing"
                     << endl;
                usage_merge();
                exit(1);
            }
            mergeTree(objdb, filemerge, conflict_res);
        }

        else if (cmd == IMPORT)
        {
            if (import_config.empty() || object.empty())
            {
                cerr << "Configuration file name and path to the new firewall "
                    "object are mandatory options for import" << endl;
                usage_import();
                exit(1);
            }

            QStringList components = QString::fromUtf8(object.c_str())
                .split("/", QString::SkipEmptyParts);
            string fw_name = components.last().toUtf8().constData();
            
            Library *library = NULL;
            while (library == NULL)
            {
                components.pop_back();
                string library_path = components.join("/").toUtf8().constData();

                list<FWObject*> objects;
                findObjects(library_path, objdb, objects);

                if (objects.size() == 0)
                {
                    cerr << "Library or folder '"
                         << library_path << "' not found" << endl;
                    usage_import();
                    exit(1);
                }

                library = Library::cast(objects.front());
            }

            cout << "Import firewall configuration from file "
                 << import_config
                 << endl;

            cout << "New firewall object '"
                 << fw_name
                 << "' will be created in library '"
                 << library->getName()
                 << "'"
                 << endl;

            importConfig(import_config, library, fw_name, deduplicate);
        }

        else if (cmd == STRUCT)
        {
            checkAndRepairTree(objdb);
        }

        else if (cmd == LIST)
        {
            listObject(objdb, object, list_children, recursive,
                       list_format, full_dump);
            return(0);
        }

        else if (cmd == UPGRADE)
        {
            cout << "File upgraded; current data format version: "
                 << libfwbuilder::Constants::getDataFormatVersion() << endl;
        }

        else  if (cmd == NEWOBJECT)
        {
            newObject(objdb, objtype, name, comment_txt, parent, ops);
        }

        else  if (cmd == DELOBJECT)
        {
            delObject(objdb, object);
        }

        else  if (cmd == MODOBJECT)
        {
            modObject(objdb, object, comment_txt, ops);
        }

        else
        {

            list<FWObject*> objects;
            findObjects(object, objdb, objects);
            if (objects.size()==0)
            {
                cout << "Object " << object << " not found" << endl;
                exit(-1);
            }

            for (list<FWObject*>::iterator it=objects.begin();
                 it!=objects.end(); ++it)
            {
                FWObject *obj = *it;

                if (cmd==ADDGRP)
                {
                    list<FWObject*> groups;
                    findObjects(group, objdb, groups);
                    if (groups.size()==0)
                    {
                        cout << "Group " << group << " not found" << endl;
                        exit(-1);
                    }
                    FWObject *grp = groups.front();
                    cout << "Adding object '" << obj->getName()
                         << "' to the group '" << grp->getName()
                         << "'" << endl;
                    grp->addRef(obj);
                }
                if (cmd==REMGRP)
                {
                    list<FWObject*> groups;
                    findObjects(group, objdb, groups);
                    if (groups.size()==0)
                    {
                        cout << "Group " << group << " not found" << endl;
                        exit(-1);
                    }
                    FWObject *grp = groups.front();
                    cout << "Removing object '" << obj->getName()
                         << "' from the group '" << grp->getName()
                         << "'" << endl;
                    grp->removeRef(obj);
                }
            }
        }

        QString filename_qstr = QString::fromUtf8(filename.c_str());
        QString bakfile = filename_qstr + ".bak";

        QFile bakf(bakfile);
        if (bakf.exists()) bakf.remove();

        QFile dataf(filename_qstr);
        if (dataf.rename(bakfile))
        {
            objdb->saveFile(filename);
        } else
        {
            cout << "Could not rename data file, abroting operation" << endl;
            cout << dataf.errorString().toStdString() << endl;
            exit(-1);
        }

    } catch(FWException &ex)  {
        cerr << ex.toString() << endl;
        exit(1);
    } catch (std::string s) {
        cerr << s;
        exit(1);
    } catch (std::exception ex) {
        cerr << ex.what();
        exit(1);
    } catch (...) {
        cerr << "Unsupported exception";
        exit(1);
    }

    return(0);
}
bool ProjectPanel::event(QEvent *event)
{
    if (event->type() >= QEvent::User)
    {
        fwbUpdateEvent *ev = dynamic_cast<fwbUpdateEvent*>(event);
        int event_code = event->type() - QEvent::User;
        QString data_file = ev->getFileName();
        int obj_id = ev->getObjectId();
        FWObject *obj = db()->findInIndex(obj_id);

        if (fwbdebug)
            qDebug() << this
                     << "rcs:"
                     << rcs
                     << "rcs->getFileName():"
                     << QString((rcs!=NULL) ? rcs->getFileName() : "")
                     << "file:"
                     << data_file
                     << "event:"
                     << ev->getEventName()
                     << "object:"
                     << ((obj!=NULL) ? QString::fromUtf8(obj->getName().c_str()) : "")
                     << "(" << ((obj!=NULL) ? obj->getTypeName().c_str() : "") << ")"
                     << "id=" << ((obj!=NULL) ? obj->getId() : -1);

        if (event_code == UPDATE_GUI_STATE_EVENT && mdiWindow != NULL)
        {
            m_panel->om->updateCreateObjectMenu(getCurrentLib());
            ev->accept();
            return true;
        }

        if ((rcs && rcs->getFileName() == data_file) ||
            (!rcs && data_file.isEmpty()))
        {
            switch (event_code)
            {
            case RELOAD_OBJECT_TREE_EVENT:
                registerTreeReloadRequest();
                ev->accept();
                return true;
                
            case RELOAD_OBJECT_TREE_IMMEDIATELY_EVENT:
                m_panel->om->reload();
                ev->accept();
                return true;
                
            case RELOAD_RULESET_EVENT:
                registerRuleSetRedrawRequest();
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;

            case MAKE_CURRENT_RULE_VISIBLE_IN_RULESET_EVENT:
            {
                RuleSetView* rsv = getCurrentRuleSetView();
                if (rsv) rsv->makeCurrentRuleVisible();
                ev->accept();
                return true;
            }
   
            case RELOAD_RULESET_IMMEDIATELY_EVENT:
                redrawRuleSets();
                //reopenFirewall();
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;
            }

            if (obj == NULL) return false;

            switch (event_code)
            {
            case DATA_MODIFIED_EVENT:
            {
                // This event does not trigger any updates in the UI,
                // this purely data structure update event. 

                FWObject *p = obj;
                while (p && Firewall::cast(p)==NULL) p = p->getParent();
                Firewall *f = Firewall::cast(p);
                // when user locks firewall object, this code tries to
                // update last_modified timestamp in it because it
                // depends on itself. Dont.
                if (f && !f->isReadOnly())
                {
                    f->updateLastModifiedTimestamp();
                    QCoreApplication::postEvent(
                        mw, new updateObjectInTreeEvent(data_file, f->getId()));
                }
                registerModifiedObject(obj);

                QCoreApplication::postEvent(mw, new updateGUIStateEvent());

                ev->accept();
                return true;
            }

            case UPDATE_OBJECT_EVERYWHERE_EVENT:
            {
                Rule *rule = NULL;
                RuleSet* current_ruleset = NULL;
                RuleSetView* rsv = getCurrentRuleSetView();
                RuleSetModel* md = NULL;
                if (rsv)
                {
                    md = (RuleSetModel*)rsv->model();
                    current_ruleset = md->getRuleSet();
                }
                if (RuleElement::cast(obj)) rule = Rule::cast(obj->getParent());
                if (Rule::cast(obj)) rule = Rule::cast(obj);

                if (rule && current_ruleset && md && rule->isChildOf(current_ruleset))
                {
                    md->rowChanged(md->index(rule, 0));
                    ev->accept();
                    return true;
                }

                if (rule)
                {
                    QCoreApplication::postEvent(
                        this, new showObjectInRulesetEvent(data_file, obj_id));
                    ev->accept();
                    return true;
                }

                if (rsv) rsv->updateObject(obj);

                if (Library::cast(obj))
                {
                    m_panel->om->updateLibName(obj);
                    m_panel->om->updateLibColor(obj);
                }

                QCoreApplication::postEvent(
                    mw, new updateObjectInTreeEvent(data_file, obj_id));

                // QCoreApplication::postEvent(
                //     this, new reloadRulesetEvent(data_file));

                ev->accept();
                return true;
            }

            case OBJECT_NAME_CHANGED_EVENT:
            {
                objectNameChangedEvent *name_change_event =
                    dynamic_cast<objectNameChangedEvent*>(event);
                m_panel->om->updateObjectInTree(obj);
                if (name_change_event->rename_children)
                {
                    // This performs automatic renaming of child objects if necessary
                    m_panel->om->autoRenameChildren(obj, name_change_event->old_name);
                }
                ev->accept();
                return true;
            }

            case UPDATE_LAST_COMPILED_TIMESTAMP_EVENT:
                if (rcs && !rcs->isRO() &&
                    Firewall::cast(obj) && !obj->isReadOnly())
                {
                    Firewall::cast(obj)->updateLastCompiledTimestamp();
                    QCoreApplication::postEvent(
                        mw, new updateObjectInTreeEvent(data_file, obj_id));
                    ev->accept();
                    return true;
                }
                break;

            case UPDATE_LAST_INSTALLED_TIMESTAMP_EVENT:
                if (rcs && !rcs->isRO() &&
                    Firewall::cast(obj) && !obj->isReadOnly())
                {
                    Firewall::cast(obj)->updateLastInstalledTimestamp();
                    QCoreApplication::postEvent(
                        mw, new updateObjectInTreeEvent(data_file, obj_id));
                    ev->accept();
                    return true;
                }
                break;
            }

            // Events below this should only be processed if
            // ProjectPanel has been attached to an MDI window.  There
            // is no MDI window right after project panel is created
            // but some operations may already be performed. See
            // FWWindow::fileOpen where ProjectPanel is cfeated and
            // file is opened before MDI window is attached. So the UI
            // update events below will only be processed if MDI
            // window exists.

            if (mdiWindow == NULL) return false;

            switch (event->type() - QEvent::User)
            {
            case INSERT_OBJECT_IN_TREE_EVENT:
            {
                FWObject *parent =
                    db()->findInIndex(
                        dynamic_cast<insertObjectInTreeEvent*>(event)->parent_id);
                m_panel->om->insertSubtree(parent, obj);
                ev->accept();
                return true;
            }

            case REMOVE_OBJECT_FROM_TREE_EVENT:
            {
                m_panel->om->removeObjectFromTreeView(obj);
                ev->accept();
                return true;
            }

            case ADD_TREE_PAGE_EVENT:
                m_panel->om->addLib(obj);
                ev->accept();
                return true;

            case REMOVE_TREE_PAGE_EVENT:
                m_panel->om->removeLib(obj);
                ev->accept();
                return true;

            case UPDATE_OBJECT_IN_TREE_EVENT:
                registerObjectToUpdateInTree(obj, false);
                ev->accept();
                return true;

            case UPDATE_OBJECT_AND_SUBTREE_IN_TREE_EVENT:
                registerObjectToUpdateInTree(obj, true);
                ev->accept();
                return true;

            case UPDATE_OBJECT_AND_SUBTREE_IMMEDIATELY_EVENT:
                m_panel->om->updateObjectInTree(obj, true);
                ev->accept();
                return true;

            case OPEN_RULESET_EVENT:
                openRuleSet(obj);
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;

            case OPEN_RULESET_IMMEDIATELY_EVENT:
                openRuleSet(obj, true);
                // update rule set title as well
                //updateFirewallName();
                ev->accept();
                return true;

            case SELECT_RULE_ELEMENT_EVENT:
            {
                RuleSetView* rsv = getCurrentRuleSetView();
                rsv->selectRE(Rule::cast(obj),
                              dynamic_cast<selectRuleElementEvent*>(event)->column_type);
                rsv->setFocus(Qt::OtherFocusReason);
                ev->accept();
                return true;
            }

            case SHOW_OBJECT_IN_RULESET_EVENT:
            {
                // if obj is child of RuleElement (i.e. a reference object)
                FWReference *ref = FWReference::cast(obj);
                if (ref)
                {
                    RuleSet* current_ruleset = NULL;
                    RuleSetView* rsv = getCurrentRuleSetView();
                    RuleSetModel* md = NULL;
                    if (rsv)
                    {
                        md = (RuleSetModel*)rsv->model();
                        current_ruleset = md->getRuleSet();
                    }

                    if (current_ruleset && obj->isChildOf(current_ruleset))
                    {
                        clearManipulatorFocus();
                        rsv->selectRE(ref);
                        rsv->setFocus(Qt::OtherFocusReason);
                    } else
                    {
                        FWObject *rs = obj;
                        while (rs && RuleSet::cast(rs)==NULL) rs = rs->getParent();
                        if (rs)
                        {
                            // reopen rule set right now, before we post event
                            // to show the object in it.
                            openRuleSet(rs);
                            QCoreApplication::postEvent(
                                this, new showObjectInRulesetEvent(data_file, obj_id));
                        }
                    }
                    ev->accept();
                    return true;
                }

                // if obj is RuleElement - select its first element
                RuleElement *re = RuleElement::cast(obj);
                if (re && re->size() > 0)
                {
                    QCoreApplication::postEvent(
                        this, new showObjectInRulesetEvent(data_file, obj->front()->getId()));
                    ev->accept();
                    return true;
                }

                // if obj is Rule - select its comment (the only common rule element)
                Rule *rule = Rule::cast(obj);
                if (rule)
                {
                    RuleSet* current_ruleset = NULL;
                    RuleSetView* rsv = getCurrentRuleSetView();
                    RuleSetModel* md = NULL;
                    if (rsv)
                    {
                        md = (RuleSetModel*)rsv->model();
                        current_ruleset = md->getRuleSet();
                    }
                    if (current_ruleset && rule->isChildOf(current_ruleset))
                    {
                        rsv->selectRE(rule, ColDesc::Comment);
                        rsv->setFocus(Qt::OtherFocusReason);
                        ev->accept();
                        return true;
                    } else
                    {
                        // this rule does not belong to the current ruleset
                        // reopen rule set right now, before we post event
                        // to show the object in it.
                        openRuleSet(rule->getParent(), true);
                        QCoreApplication::postEvent(
                            this, new showObjectInRulesetEvent(data_file, obj->getId()));
                    }
                    ev->accept();
                    return true;
                }

                ev->accept();
                return true;
            }

            case SHOW_OBJECT_IN_TREE_EVENT:
                //m_panel->om->setFocus();
                m_panel->om->openObjectInTree(obj);
                ev->accept();
                return true;

            case EXPAND_OBJECT_IN_TREE:
                m_panel->om->expandObjectInTree(obj);
                ev->accept();
                return true;

            case OPEN_LIBRARY_FOR_OBJECT_EVENT:
                m_panel->om->openLibForObject(obj);
                ev->accept();
                return true;

            case CLOSE_OBJECT_EVENT:
                if (RuleSet::cast(obj))
                {
                    if (visibleRuleSet == obj)
                    {
                        clearFirewallTabs();
                        closeRuleSet(obj);
                    }
                } else
                {
                    m_panel->om->closeObject();
                    mdiWindow->update();
                }
                ev->accept();
                return true;

            case ADD_USER_FOLDER_EVENT:
                m_panel->om->addUserFolderToTree(obj, dynamic_cast<addUserFolderEvent *>(event)->m_userFolder);
                ev->accept();
                return true;

            case REMOVE_USER_FOLDER_EVENT:
                m_panel->om->removeUserFolderFromTree(obj, dynamic_cast<removeUserFolderEvent *>(event)->m_userFolder);
                ev->accept();
                return true;

            case MOVE_TOFROM_USER_FOLDER_EVENT:
                moveToFromUserFolderEvent *moveEvent =
                    dynamic_cast<moveToFromUserFolderEvent *>(event);
                m_panel->om->moveToFromUserFolderInTree(obj, db()->findInIndex(moveEvent->m_objIdToMove), moveEvent->m_oldFolder, moveEvent->m_newFolder);
                ev->accept();
                return true;
            }
        }
        return false;
    }

    //if (fwbdebug) qDebug() << this << "event:" << event;
    
    return QWidget::event(event);
}
Exemple #24
0
void IPv4Dialog::DNSlookup()
{
    if (fwbdebug)
        qDebug("IPv4Dialog::DNSlookup()  dnsBusy=%d", dnsBusy);

    if (!dnsBusy)
    {
        QString name = m_dialog->obj_name->text().trimmed();
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
        if (fwbdebug) qDebug("IPv4Dialog::DNSlookup()  name=%s", name.toAscii().constData());
#else
        if (fwbdebug) qDebug("IPv4Dialog::DNSlookup()  name=%s", name.toLatin1().constData());
#endif
        dnsBusy=true;
        QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) );
        QString addr = getAddrByName(name, AF_INET);
        QApplication::restoreOverrideCursor();
        dnsBusy=false;
        if (fwbdebug) qDebug("IPv4Dialog::DNSlookup()  done");

        if (! addr.isEmpty())
        {
            m_dialog->address->setText( addr );
            changed();
            return;
        }

        if ( Interface::isA(obj->getParent()) )
        {
            FWObject *host = obj->getParent()->getParent();
            assert(host!=NULL);
            name = host->getName().c_str();

#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
            if (fwbdebug) qDebug("IPv4Dialog::DNSlookup()  name=%s",
                name.toAscii().constData());
#else
            if (fwbdebug) qDebug("IPv4Dialog::DNSlookup()  name=%s",
                name.toLatin1().constData());
#endif
            dnsBusy=true;
            QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) );
            QString addr = getAddrByName(name, AF_INET);
            QApplication::restoreOverrideCursor();
            dnsBusy=false;
            if (fwbdebug) qDebug("IPv4Dialog::DNSlookup()  done");
            if ( ! addr.isEmpty())
            {
                m_dialog->address->setText( addr );
                changed();
                return;
            }
            QMessageBox::warning(
                this,"Firewall Builder",
                tr("DNS lookup failed for both names of the address object '%1' and the name of the host '%2'.")
                .arg(m_dialog->obj_name->text()).arg(name),
                "&Continue", QString::null,QString::null, 0, 1 );
            return;
        }
        QMessageBox::warning(
            this,"Firewall Builder",
            tr("DNS lookup failed for name of the address object '%1'.")
            .arg(name),
            "&Continue", QString::null,QString::null, 0, 1 );
        return;
    }
}
int PolicyCompiler::prolog()
{
    Compiler::prolog();

    Policy *policy = Policy::cast(fw->getFirstByType(Policy::TYPENAME));
    assert(policy);

    if (source_ruleset == NULL) source_ruleset = policy;

    source_ruleset->renumberRules();

    temp_ruleset = new Policy();   // working copy of the policy
    fw->add( temp_ruleset );

    temp_ruleset->setName(source_ruleset->getName());

    int global_num = 0;

    string label_prefix = "";
    if (source_ruleset->getName() != "Policy") label_prefix = source_ruleset->getName();

    int rule_counter = 0;
    for (FWObject::iterator i=source_ruleset->begin(); i!=source_ruleset->end(); i++)
    {
	PolicyRule *r = PolicyRule::cast(*i);
        if (r == NULL) continue; // skip RuleSetOptions object

        /*
         * do not remove disabled rules just yet because some
         * compilers might use RuleSet::insertRuleAtTop() and other
         * similar methods from prolog() or
         * addPredefinedPolicyRules()() and these methods renumber
         * rules (labels stop matching rule positions when this is
         * done because labels are configured in prolog() method of
         * the base class. See fwbuilder ticket 1173)
         */
	//if (r->isDisabled()) continue;

        if (r->getLabel().empty())
        {
            RuleElementItf *itfre = r->getItf();
            assert(itfre);

            if (itfre->isAny())
            {
                r->setLabel( createRuleLabel(label_prefix, 
                                             "global", r->getPosition()) );
            } else
            {
                string interfaces = "";
                for (FWObject::iterator i=itfre->begin(); i!=itfre->end(); ++i)
                {
                    FWObject *o = FWReference::getObject(*i);
                    if (interfaces!="") interfaces += ",";
                    interfaces += o->getName();
                }
                r->setLabel( createRuleLabel(label_prefix, 
                                             interfaces, r->getPosition()) );
            }
        }

	r->setAbsRuleNumber(global_num);
        global_num++;
        rule_counter++;
    }

    initialized = true;

    return rule_counter;
}
bool ProjectPanel::exportLibraryTest(list<FWObject*> &selectedLibs)
{
/* VERY IMPORTANT: External library file must be self-contained,
 * otherwise it can not be exported.
 *
 * check if selected libraries have references to objects in other
 * libraries (not exported to the same file). Exporting such libraries
 * pulls in other ones because of these references. This is confusing
 * because it means we end up with multiple copies of such objects (in
 * exported library file and in user's data file). When user imports
 * this library and opens their file, it is impossible to say which
 * library an object belongs to.
 *
 * This is prohibited. We check if exported set of libraries has such
 * references and refuse to export it. The user is supposed to clean
 * it up by either moving objects into the library they are trying to
 * export, or by rearranging objects. The only exception for this is
 * library "Standard", which is assumed to be always present so we can
 * have references to objects in it.
 */
    QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) );

    list<FWReference*> externalRefs;
    for (list<FWObject*>::iterator i=selectedLibs.begin(); i!=selectedLibs.end(); ++i)
        findExternalRefs( *i, *i, externalRefs);

    QApplication::restoreOverrideCursor();

    if (fwbdebug) qDebug("LibExportDialog::accept  externalRefs.size()=%d",
                         int(externalRefs.size()) );

/*
 * if externalRefs.size()!=0, then there were some references pointing
 * outside of the libraries we export. Some of these references may
 * point at other libraries we export, lets find these.
 */
    list<FWReference*> externalRefs2;
    for (list<FWReference*>::iterator i=externalRefs.begin(); i!=externalRefs.end(); ++i)
    {
        FWObject *tgt    = (*i)->getPointer();
        FWObject *tgtlib = tgt->getLibrary();

        if (std::find(selectedLibs.begin(),selectedLibs.end(),tgtlib)!=selectedLibs.end()) continue;
        externalRefs2.push_back(*i);
    }

    if (externalRefs2.size()!=0)
    {
        QString objlist = "";
        QString s       = "";

        for (list<FWReference*>::iterator i=externalRefs2.begin();
             i!=externalRefs2.end(); ++i)
        {
            FWReference *robj   = *i;
            FWObject *selLib = robj->getLibrary();
            FWObject *pp     = robj->getParent();
            FWObject *tgt    = robj->getPointer();
            FWObject *tgtlib = tgt->getLibrary();

            if (fwbdebug)
            {
                qDebug("LibExportDialog::accept  tgt: %s pp_type: %s lib: %s",
                       tgt->getName().c_str(),
                       pp->getTypeName().c_str(),
                       tgtlib->getName().c_str());
            }

            if (std::find(selectedLibs.begin(),selectedLibs.end(),tgtlib)!=selectedLibs.end()) continue;

            if (RuleElement::cast(pp)!=nullptr)
            {
                FWObject *fw       = pp;
                FWObject *rule     = pp;
                FWObject *ruleset  = pp;
                FWObject *iface    = pp;

                while (rule!=nullptr && Rule::cast(rule)==nullptr)
                    rule=rule->getParent();
                while (ruleset!=nullptr && RuleSet::cast(ruleset)==nullptr)
                    ruleset=ruleset->getParent();
                while (iface!=nullptr && Interface::cast(iface)==nullptr)
                    iface=iface->getParent();
                while (fw!=nullptr && Firewall::cast(fw)==nullptr)
                    fw=fw->getParent();

                s = QObject::tr("Library %1: Firewall '%2' (%3 rule #%4) uses "
                                "object '%5' from library '%6'")
                    .arg(selLib->getName().c_str())
                    .arg(fw->getName().c_str())
                    .arg(ruleset->getTypeName().c_str())
                    .arg(Rule::cast(rule)->getPosition())
                    .arg(tgt->getName().c_str())
                    .arg(tgtlib->getName().c_str());

            } else
            {
                s =
                    QObject::tr("Library %1: Group '%2' uses object '%3' from library '%4'")
                        .arg(selLib->getName().c_str())
                        .arg(pp->getName().c_str())
                        .arg(tgt->getName().c_str())
                        .arg(tgtlib->getName().c_str());
            }
            s = s + "\n";

            if (fwbdebug) qDebug() << s;

            objlist = objlist + s;
        }

        longTextDialog ltd(
            this,
            tr("A library that you are trying to export contains references\n"
               "to objects in the other libraries and can not be exported.\n"
               "The following objects need to be moved outside of it or\n"
               "objects that they refer to moved in it:"),
            objlist );

        ltd.exec();
        return false;
    }
    return true;
}
Exemple #27
0
string TableFactory::PrintTables()
{
    if (tables.size() == 0) return "";

    stringstream output;
    output << endl;
    output << "# Tables: (" << tables.size() << ")" << endl;

    for (map<string,string>::const_iterator i=tblnames.begin();
         i!=tblnames.end(); i++)
    {
        string tblID = i->second;
        FWObject *grp = tables[tblID];
        output << "table ";
        output << "<" << grp->getName() << "> ";
        MultiAddressRunTime *atrt = MultiAddressRunTime::cast(grp);
        if (atrt!=nullptr &&
            atrt->getSubstitutionTypeName()==AddressTable::TYPENAME)
        {
            output << "persist";
            if ( !atrt->getSourceName().empty() )
            {
                string path =
                    atrt->getSourceNameAsPath(firewall->getOptionsObject());
                if (path.empty()) {
                    compiler->abort("Error: Firewall's data directory not set for address table: " + atrt->getName());
                }
                
                output << " file \"" << path << "\"";
            }

            output << endl;
            continue;
        }
        output << "{ ";
        for (FWObject::iterator i=grp->begin(); i!=grp->end(); i++)
        {
            if (i!=grp->begin())  output << ", ";
            FWObject *o = FWReference::getObject(*i);
            if (o==nullptr) compiler->abort("broken table object ");

            MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o);
            if (atrt!=nullptr)
            {
                if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME)
                {
                    output <<  atrt->getSourceName() << " ";
                }
                if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME)
                {
                    output << atrt->getSourceName() << ":network ";
                }
            } else
            {
                if (Interface::cast(o))
                {
                    output << o->getName();
                } else
                {
                    Address *A=Address::cast( o );
                    if (A==nullptr)
                        compiler->abort("table object must be an address: '" +
                                          o->getTypeName()+"'");

                    const InetAddr *addr = A->getAddressPtr();
                    InetAddr mask = *(A->getNetmaskPtr());

                    if (A->dimension()==1)
                    {
                        mask = InetAddr(InetAddr::getAllOnes());
                    }

                    output << addr->toString();
                    if (!mask.isHostMask())
                    {
                        output << "/" << mask.getLength();
                    }
                }
            }
            output << " ";
        }
        output << "} ";
        output << endl;
    }
    output << endl;
    return output.str();
}
Exemple #28
0
/**
 * finds interface of the firewall associated with the netzone
 * that object 'obj' belongs to.  Returns interface ID
 *
 */
int  Helper::findInterfaceByNetzone(const InetAddr *addr, const InetAddr *nm)
    throw(FWException)
{
#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByNetzone";
    cerr << " matching to";
    cerr << " addr=" << addr;
    if (addr) cerr << " " << addr->toString();
    cerr << " nm=" << nm;
    if (nm) cerr << " " << nm->toString();
    cerr << endl;
#endif

    Firewall *fw = compiler->fw;
    map<int,FWObject*> zones;
    list<FWObject*> l2 = fw->getByTypeDeep(Interface::TYPENAME);
    for (list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i)
    {
        Interface *iface = Interface::cast(*i);
        if (iface->isDedicatedFailover()) continue;
        if (iface->isUnprotected()) continue;

        // NOTE: "network_zone" is globally unique string ID
        int netzone_id =
            FWObjectDatabase::getIntId(iface->getStr("network_zone"));

        if (netzone_id != -1)
        {
            FWObject *netzone = fw->getRoot()->findInIndex(netzone_id);
            list<FWObject*> nz;
            expand_group_recursive(netzone, nz);

#if DEBUG_NETZONE_OPS
            cerr << "Helper::findInterfaceByNetzone";
            cerr << "  netzone_id=" << netzone_id
                 << "  " << iface->getStr("network_zone")
                 << "  " << netzone->getName()
                 << endl;
#endif

            for (list<FWObject*>::iterator j=nz.begin(); j!=nz.end(); ++j)
            {
                Address *netzone_addr = Address::cast(*j);
                
                if (netzone_addr == NULL) continue;

#if DEBUG_NETZONE_OPS
                cerr << "Helper::findInterfaceByNetzone";
                cerr << "    " << netzone_addr->getName()
                     << "  " << netzone_addr->getAddressPtr()->toString()
                     << endl;
#endif

                // if addr==NULL, return id of the interfacce that has
                // net_zone=="any"
                if (addr==NULL)
                {
                    if (netzone_addr->getId()==FWObjectDatabase::ANY_ADDRESS_ID)
                        return iface->getId(); // id of the interface
                } else
                {
                    // see SF bug 3213019
                    // skip ipv6 addresses in network zone group
                    if (netzone_addr->getAddressPtr()->addressFamily() !=
                        addr->addressFamily()) continue;

                    const InetAddr *nz_addr = netzone_addr->getAddressPtr();
                    const InetAddr *nz_netm = netzone_addr->getNetmaskPtr();
                    if (nm != NULL && nz_netm != NULL)
                    {
                        InetAddrMask nz_subnet(*nz_addr, *nz_netm);
                        InetAddrMask other_subnet(*addr, *nm);
                        vector<InetAddrMask> ovr =
                            libfwbuilder::getOverlap(nz_subnet,
                                                     other_subnet);
#if DEBUG_NETZONE_OPS
                        cerr << "Helper::findInterfaceByNetzone";
                        cerr << " addr=" << other_subnet.toString();
                        cerr << " nz=" << nz_subnet.toString();
                        cerr << " overlap:";
                        cerr << " ovr.size()=" << ovr.size();
                        if (ovr.size() > 0)
                            cerr << " ovr.front()=" << ovr.front().toString();
                        cerr << endl;
#endif
                        if (ovr.size()==0) continue;
                        // if nz_subnet is equal or wider than other_subnet,
                        // getOverlap() returns subnet object equal to other_subnet
                        // If other_subnet is wider, returned object is equal
                        // to nz_subnet. If they intersect but one does not fit
                        // completely in the other, returned object is not equal
                        // to either.
                        if (ovr.front() == other_subnet)
                        {
                            zones[iface->getId()] = netzone_addr;
#if DEBUG_NETZONE_OPS
                            cerr << "Helper::findInterfaceByNetzone";
                            cerr << "    match" << endl;
#endif
                        }
                    } else
                    {
                        if (netzone_addr->belongs(*addr))
                        {
                            zones[iface->getId()] = netzone_addr;

#if DEBUG_NETZONE_OPS
                            cerr << "Helper::findInterfaceByNetzone";
                            cerr << "    match" << endl;
#endif
                        }
                    }
                }
            }
        }
    }

/*
 * now compare dimensions of all netzones that contain address obj and
 * pick the one with smallest dimension
 */    
    int  res_id = -1;
    unsigned long res_dim = LONG_MAX;
    for (map<int,FWObject*>::iterator i=zones.begin(); i!=zones.end(); ++i) 
    {
        int iface_id = (*i).first;
        FWObject *netzone = (*i).second;
        unsigned long dim = calculateDimension(netzone);

#if DEBUG_NETZONE_OPS
        cerr << "Helper::findInterfaceByNetzone";
        cerr << "    netzone=" << netzone->getName()
             << "  dim=" << dim
             << "  res_dim=" << res_dim
             << endl;
#endif

        if (dim<=res_dim) 
        {
            res_id = iface_id;
            res_dim = dim;
        }
    }

#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByNetzone";
    cerr << " Result after scanning network zones: " << res_id << endl;
#endif

/*
 * Subnets defined by addresses of interfaces are automatically part
 * of the corresponding network zones
 */
    if (res_id == -1)
        res_id = findInterfaceByAddress(addr, nm);

    if (res_id == -1)
    {
        QString err = QObject::tr("Can not find interface with network zone "
                                  "that includes address '%1%2'");
        throw(FWException(err
                          .arg((addr)?addr->toString().c_str():"NULL")
                          .arg((nm)?QString("/%1").arg(nm->toString().c_str()):"")
                          .toStdString()));
    }

#if DEBUG_NETZONE_OPS
    cerr << "Helper::findInterfaceByNetzone";
    cerr << " returning " << res_id << endl;
#endif

    return res_id;
}