예제 #1
0
FWObject* AddressObjectMaker::createObject(ObjectSignature &sig)
{
    FWObject *obj = nullptr;

    if (sig.type_name == AddressRange::TYPENAME)
        obj = createAddressRange(sig);

    if (sig.type_name == AddressTable::TYPENAME)
        obj = createAddressTable(sig);

    if (sig.type_name == DNSName::TYPENAME)
        obj = createDNSName(sig);

    if (obj == nullptr)
        obj = createAddress(sig);

    // Now I should build new signature because actual object type has
    // only been determined in createAddress()

    ObjectSignature new_sig(error_tracker);

    if ( ! sig.object_name.isEmpty())
    {
        obj->setName(sig.object_name.toUtf8().constData());
        obj->dispatch(&new_sig, (void*)(nullptr));
        registerNamedObject(new_sig, obj);
    } else
    {
        obj->dispatch(&new_sig, (void*)(nullptr));
        registerAnonymousObject(new_sig, obj);
    }

    return obj;
}
void ObjectManipulator::groupObjects()
{
    if (getCurrentObjectTree()->getNumSelected()==0) return;

    FWObject *co = getCurrentObjectTree()->getSelectedObjects().front();

    newGroupDialog ngd(this, m_project->db());

    if (ngd.exec()==QDialog::Accepted)
    {
        QString objName = ngd.m_dialog->obj_name->text();
        QString libName = ngd.m_dialog->libs->currentText();

        QString type = ObjectGroup::TYPENAME;
        if (Service::cast(co)!=NULL)  type=ServiceGroup::TYPENAME;
        if (Interval::cast(co)!=NULL) type=IntervalGroup::TYPENAME;

        FWObject *parent = NULL;
        FWObject *newgrp = NULL;

        list<FWObject*> ll = m_project->db()->getByType( Library::TYPENAME );
        for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++)
        {
            FWObject *lib=*i;
            if (libName==QString::fromUtf8(lib->getName().c_str()))
            {
/* TODO: need to show a dialog and say that chosen library is
 * read-only.  this is not critical though since newGroupDialog fills
 * the pull-down only with names of read-write libraries
 */
                if (lib->isReadOnly()) return;
                parent = FWBTree().getStandardSlotForObject(lib,type);
                if (parent==NULL)
                {
                    if (fwbdebug)
                        qDebug("ObjectManipulator::groupObjects(): could not find standard slot for object of type %s in library %s",
                               type.toAscii().constData(),lib->getName().c_str());
                    return;
                }
                newgrp = m_project->db()->create(type.toStdString());
                newgrp->setName(string(objName.toUtf8().constData()));
                break;
            }
        }
        if (newgrp==NULL) return;

        FWCmdAddObject *cmd = new FWCmdAddObject(
            m_project, parent, newgrp, QObject::tr("Create new group"));
        FWObject *new_state = cmd->getNewState();
        new_state->add(newgrp);

        vector<FWObject*> so = getCurrentObjectTree()->getSimplifiedSelection();
        for (vector<FWObject*>::iterator i=so.begin();  i!=so.end(); ++i)
            newgrp->addRef(*i);

        m_project->undoStack->push(cmd);
    }
}
예제 #3
0
void DNSTest::runTest()
{
    libfwbuilder::init();

    objdb = new FWObjectDatabase();

    FWObject *nlib = objdb->create(Library::TYPENAME);
    objdb->add(nlib);
    nlib->setName( "Library" );

    FWObject *o1 = objdb->create(ObjectGroup::TYPENAME);
    o1->setName("Objects");
    nlib->add(o1);

    FWObject *root = objdb->create(ObjectGroup::TYPENAME);
    root->setName("DNS Names");
    o1->add(root);

    InetAddr addr;
    char* test1[] = {"localhost", "127.0.0.1", NULL};
    CPPUNIT_ASSERT(testDNSNameObject(objdb, root, test1[0], &(test1[1])));

    char* test2[] = {"www.fwbuilder.org","70.85.175.170", NULL};
    CPPUNIT_ASSERT(testDNSNameObject(objdb, root, test2[0], &(test2[1])));

    char* test3[] = {"www.microsoft.com",
                     "65.55.21.250",
                     "207.46.232.182",
                     "207.46.197.32",
                     "207.46.19.254",
                     "207.46.192.254",
                     "207.46.193.254",
                     NULL};

    CPPUNIT_ASSERT(testDNSNameObject(objdb, root, test3[0], &(test3[1])));
}
예제 #4
0
FWObject* TableFactory::createTableObject(const string &tblname,
                                          const string &tblid)
{
    FWObject *tblgrp = dbroot->createObjectGroup();

    tblgrp->setName( tblname );
    tblgrp->setId(FWObjectDatabase::generateUniqueId()); //  "id_" + tblname );

    persistent_tables->add(tblgrp, false);
    dbroot->addToIndex(tblgrp);

    tblgrp->setBool("pf_table", true);
    tblgrp->setStr("pf_table_id", tblid);

    registerTable(tblname, tblid, tblgrp);

    return tblgrp;
}
예제 #5
0
/*
 * Load standard library objects
 */
void ProjectPanel::loadStandardObjects()
{
    if (fwbdebug) qDebug("ProjectPanel::load(): start");

    editingStandardLib = false;
    editingTemplateLib = false;

    MessageBoxUpgradePredicate upgrade_predicate(mainW);

    resetFD();

    try
    {
// need to drop read-only flag on the database before I load new objects

        if (objdb)
        {
            objdb->destroyChildren();
            delete objdb;
        }

        objdb = new FWObjectDatabase();
        objdb->setReadOnly( false );

        mw->showStatusBarMessage(tr("Loading system objects..."));

// always load system objects
        if (fwbdebug)
            qDebug("ProjectPanel::load(): sysfname = %s",
                   Constants::getStandardObjectsFilePath().c_str());

        objdb->load( Constants::getStandardObjectsFilePath(),
                     &upgrade_predicate, Constants::getDTDDirectory());
        objdb->setFileName("");

        if (fwbdebug) qDebug("ProjectPanel::load(): create User library");

        FWObject *userLib = FWBTree().createNewLibrary(objdb);

        userLib->setName("User");
        userLib->setStr("color","#d2ffd0");

        objdb->setDirty(false);
        objdb->setFileName("");

        createRCS("");

        //setWindowTitle(getPageTitle());
        QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent());

        loadObjects();
        setupAutoSave();

        time_t last_modified = objdb->getTimeLastModified();

        if (fwbdebug)
            qDebug("ProjectPanel::load(): done  last_modified=%s dirty=%d",
                   ctime(&last_modified), objdb->isDirty());

        // For Diff Viewer
        if (origObjdb)
            delete origObjdb;
        origObjdb = new FWObjectDatabase(*objdb);
        origObjdb->reIndex();

    } catch(FWException &ex)
    {
        QMessageBox::critical(
            this,"Firewall Builder",
            tr("Error loading file:\n%1").arg(ex.toString().c_str()),
            tr("&Continue"), QString::null,QString::null,
            0, 1 );
    }
}
예제 #6
0
void CompilerDriver_pix::pixNetworkZoneChecks(Firewall *fw,
                                              list<FWObject*> &all_interfaces)
{
    multimap<string, FWObject*> netzone_objects;
    Helper helper(NULL);

    for (std::list<FWObject*>::iterator i=all_interfaces.begin(); i!=all_interfaces.end(); ++i)
    {
        Interface *iface = dynamic_cast<Interface*>(*i);
        assert(iface);

        if (iface->getOptionsObject()->getBool("cluster_interface")) continue;
        if (iface->isDedicatedFailover()) continue;
        if (iface->isUnprotected()) continue;


        /*
         * in PIX, we need network zones to be defined for all
         * interfaces
         */
        string netzone_id = iface->getStr("network_zone");
        if (netzone_id=="")
        {
            QString err("Network zone definition is missing for interface '%1' (%2)");
            abort(fw, NULL, NULL,
                  err.arg(iface->getName().c_str())
                  .arg(iface->getLabel().c_str()).toStdString());
            throw FatalErrorInSingleRuleCompileMode();
        }

        FWObject *netzone = objdb->findInIndex(
            FWObjectDatabase::getIntId(netzone_id));
        if (netzone==NULL) 
        {
            QString err("Network zone points at nonexisting object for "
                        "interface '%1' (%2)");
            abort(fw, NULL, NULL,
                  err.arg(iface->getName().c_str())
                  .arg(iface->getLabel().c_str()).toStdString());
            throw FatalErrorInSingleRuleCompileMode();
        }
/*
 * netzone may be a group, in which case we need to expand it
 * (recursively). 
 * 
 * 1. We create new temporary object (type Group).
 *
 * 2. put it in the database somewhere
 *
 * 3. add all objects that belong to the network zone to this
 * group. We add objects directly, not as a reference.
 *
 * 4. finally replace reference to the old network zone object in the
 * interface with reference to this new group.
 *
 * 5. we store ID of the original network zone object 
 *    using iface->setStr("orig_netzone_id")
 *
 * This ensures netzones do not contain other groups and do not
 * require any recursive expanding anymore. Since objects were added
 * to netzones directly, we do not need to bother with dereferencing,
 * too.
 */
        list<FWObject*> ol;
        helper.expand_group_recursive(netzone, ol);

        FWObject *nz = objdb->createObjectGroup();
        assert(nz!=NULL);
        nz->setName("netzone_" + iface->getLabel());
        objdb->add(nz);

        for (list<FWObject*>::iterator j=ol.begin(); j!=ol.end(); ++j)
        {
            Address *addr = Address::cast(*j);
            if (addr == NULL || addr->getAddressPtr() == NULL)
            {
                QString err("Network zone of interface '%1' uses object '%2' "
                            "that is not an address");
                abort(fw, NULL, NULL,
                      err.arg(iface->getLabel().c_str())
                      .arg((*j)->getName().c_str()).toStdString());
                throw FatalErrorInSingleRuleCompileMode();
            }

/*
  Commented out for SF bug 3213019

  currently we do not support ipv6 with PIX/ASA and FWSM. If user
  creates a group to be used as network zone object and places ipv6
  address in it, this address should be ignored while compiling the
  policy but this should not be an error. Compiler uses network zone
  group to do various address matching operations when it tries to
  determine an interface for a rule where user did not specify
  one. Since we never (should) have ipv6 in policy and nat rules,
  compiler is not going to have anything to compare to ipv6 address in
  the network zone even if there is one and this ipv6 address is going
  to be ignored.


            if (addr->getAddressPtr()->isV6())
            {
                QString err("Network zone of interface '%1' uses object '%2' "
                            "that is IPv6 address");
                abort(fw, NULL, NULL,
                      err.arg(iface->getLabel().c_str())
                      .arg((*j)->getName().c_str()).toStdString());
                throw FatalErrorInSingleRuleCompileMode();
            }
*/
            netzone_objects.insert(
                pair<string,FWObject*>(iface->getLabel(),*j));
            nz->addRef(*j);
        }
        iface->setStr("orig_netzone_id", netzone_id );
        iface->setStr("network_zone",
                      FWObjectDatabase::getStringId(nz->getId()) );
    }


/*
 * the same object (network or host) can not belong to network zones
 * of two different interfaces. Map netzone_objects holds pairs
 * interface_id/object. We just make sure the same object does not
 * appear in two pairs with different interfaces.
 */
    multimap<string,FWObject*>::iterator k;
    for (k=netzone_objects.begin(); k!=netzone_objects.end(); ++k)
    {
        multimap<string,FWObject*>::iterator l;
        l=k;
        ++l;
        for ( ; l!=netzone_objects.end(); ++l)
        {
            if ( l->second->getId() == k->second->getId() )
            {
                if (k->first==l->first)
                {
                    QString err("Object %1 is used more than once in network "
                                "zone of interface '%2'");
                    abort(fw, NULL, NULL,
                          err.arg(l->second->getName().c_str())
                          .arg(k->first.c_str()).toStdString());
                    throw FatalErrorInSingleRuleCompileMode();
                } else
                {
                    QString err("Object %1 is used in network zones of "
                                "interfaces '%2' and '%3'");
                    abort(fw, NULL, NULL,
                          err.arg(l->second->getName().c_str())
                          .arg(k->first.c_str())
                          .arg(l->first.c_str()).toStdString());
                    throw FatalErrorInSingleRuleCompileMode();
                }
            }
        }
    }


}
void ObjectManipulator::deleteObject(FWObject *obj, QUndoCommand* macro)
{
    bool firstAction = true ;

    if (fwbdebug)
        qDebug() << "ObjectManipulator::deleteObject"
                 << "obj=" << obj
                 << "name=" << obj->getName().c_str();

    FWObject *object_library = obj->getLibrary();
    FWObject *parent = obj->getParent();
    FWObject *deleted_objects_lib = m_project->db()->findInIndex(
        FWObjectDatabase::DELETED_OBJECTS_ID );

    if (deleted_objects_lib == NULL)
    {
        FWObject *dobj = m_project->db()->createLibrary();
        dobj->setId(FWObjectDatabase::DELETED_OBJECTS_ID);
        dobj->setName("Deleted Objects");
        dobj->setReadOnly(false);
        m_project->db()->add(dobj);
        deleted_objects_lib = dobj;
    }

    if (object_library->getId() == FWObjectDatabase::STANDARD_LIB_ID)
        return;

    if (obj->isReadOnly()) return;

    if (obj->getId() == FWObjectDatabase::STANDARD_LIB_ID ||
        obj->getId() == FWObjectDatabase::DELETED_OBJECTS_ID) return;
    
    bool is_library = Library::isA(obj);
    bool is_firewall = Firewall::cast(obj) != NULL; // includes Cluster too
    bool is_deleted_object = (deleted_objects_lib!=NULL && obj->isChildOf(deleted_objects_lib));

    // ruleset_visible == true if 1) we delete firewall object and one of its
    // rulesets is visible in the project panel, or 2) we delete ruleset object
    // which is visible in the project panel
    bool ruleset_visible = (
        (is_firewall && m_project->getCurrentRuleSet()->isChildOf(obj)) ||
        (m_project->getCurrentRuleSet() == obj));

    mw->findObjectWidget->reset();

    QCoreApplication::postEvent(
        mw, new closeObjectEvent(m_project->getFileName(), obj->getId()));

#if 0
    // Remove object we are about to delete from the clipboard.
    // Sequence "delete then paste" is risky if the object is pasted into
    // a group or rule where only reference is added
    FWObjectClipboard::obj_clipboard->remove(obj);
#endif
 
    try
    {    
        if (fwbdebug)
            qDebug() << "ObjectManipulator::deleteObject"
                     << "is_library=" << is_library
                     << "is_firewall= " << is_firewall
                     << "ruleset_visible=" << ruleset_visible
                     << "is_deleted_object="<< is_deleted_object;

        if (is_deleted_object)
        {
            unselect();
            FWCmdDeleteObject *cmd = new FWCmdDeleteObject(
                m_project,
                obj,
                QString("Delete object"),
                macro);
            if (macro==0)
                m_project->undoStack->push(cmd);
            return;
        }

        if (is_library && obj->isReadOnly()) obj->setReadOnly(false);

        if (is_library) parent = m_project->db()->getFirstByType(Library::TYPENAME);

        actuallyDeleteObject(obj, macro);
        
        if (ruleset_visible) m_project->closeRuleSetPanel();
    }
    catch (FWException &ex)
    {
        if (fwbdebug)
            qDebug() << "ObjectManipulator::deleteObject:"
                     << "catch:  restoreOverrideCursor";
        QApplication::restoreOverrideCursor();
        QMessageBox::warning(
            this,"Firewall Builder",
            ex.toString().c_str(),
            "&Continue", QString::null,QString::null,
            0, 1 );
        throw(ex);
    }

    if (fwbdebug) qDebug("ObjectManipulator::deleteObject  done");

    firstAction = false ;
}
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;
}