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);
                }
            }
        }
    }
}
示例#2
0
void MetricEditorPanel::loadFWObject(libfwbuilder::FWObject *obj)
{
    RoutingRule *r=RoutingRule::cast(obj);
    if (r==nullptr) return;
    rule=r;

    FWObject *o = r;
    while (o!=nullptr && Firewall::cast(o)==nullptr) o=o->getParent();
    assert(o!=nullptr);

    m_widget->spin_box->setMinimum( 0);
    m_widget->spin_box->setMaximum( 255);
    m_widget->spin_box->setValue( r->getMetric());
}
示例#3
0
clusterMembersDialog::clusterMembersDialog(QWidget *parent, FWObject *o)
    : QDialog(parent), table_update(false)
{
    m_dialog = new Ui::clusterMembersDialog_q;
    m_dialog->setupUi(this);
    setWindowModality(Qt::WindowModal);

    // assign clustergroup object
    obj = o;
    FWObject *parent_host = Host::getParentHost(obj);
    host_os = parent_host->getStr("host_OS").c_str();
    platform = parent_host->getStr("platform").c_str();

    // if empty, retry with parent of parent (interface level)
    if (host_os.isEmpty())
    {
        FWObject *parent = NULL;
        parent = obj->getParent();
        if (parent == NULL)
        {
            throw FWException("clusterMembersDialog: parent is NULL!");
        }
        parent = parent->getParent();
        if (parent == NULL)
        {
            throw FWException("clusterMembersDialog: parent is NULL!");
        }
        host_os = parent->getStr("host_OS").c_str();
        platform = parent->getStr("platform").c_str();
    }

    string type = obj->getStr("type");
    enable_master_column = Resources::os_res[host_os.toStdString()]->getResourceBool(
        "/FWBuilderResources/Target/protocols/" + type + "/needs_master");
    if (!enable_master_column) m_dialog->fwSelectedTable->hideColumn(2);

    // prepare lists of firewalls (selected, available)
    getSelectedMembers();
    getPossibleMembers();

    // init views
    updateAvailableTree();
    updateSelectedTable();
}
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);
        }
    }
}
示例#5
0
文件: Rule.cpp 项目: sirius/fwbuilder
RuleSet* PolicyRule::getBranch()
{
    if (getAction() != PolicyRule::Branch) return NULL;
    FWObject *fw = this;
    while (fw && Firewall::cast(fw) == NULL) fw = fw->getParent();
    assert(fw!=NULL);
    string branch_id = getOptionsObject()->getStr("branch_id");
    if (!branch_id.empty())
    {
        return RuleSet::cast(getRoot()->findInIndex(
                                 FWObjectDatabase::getIntId(branch_id)));
    } else
    {
        string branch_name = getOptionsObject()->getStr("branch_name");
        if (!branch_name.empty())
        {
            return RuleSet::cast(
                fw->findObjectByName(Policy::TYPENAME, branch_name));
        } else
            return NULL;
    }
}
void OSConfigurator_linux24::addVirtualAddressForNAT(const Address *addr)
{
    FWOptions* options=fw->getOptionsObject();
    if ( options->getBool("manage_virtual_addr") )
    {
        const InetAddr *addr_addr = addr->getAddressPtr();

        if (virtual_addresses.empty() || 
            find(virtual_addresses.begin(),
                 virtual_addresses.end(), *addr_addr) == virtual_addresses.end())
        {
            FWObject *vaddr = findAddressFor(addr, fw );
            if (vaddr!=nullptr)
            {
                Interface *iface = Interface::cast(vaddr->getParent());
                assert(iface!=nullptr);

                QStringList addresses;
                const InetAddr *vaddr_netm =
                    Address::cast(vaddr)->getNetmaskPtr();

                addresses.push_back(QString("%1/%2").
                                    arg(addr_addr->toString().c_str()).
                                    arg(vaddr_netm->getLength()));

                if (virtual_addresses_for_nat.count(iface->getName()) > 0)
                    addresses.push_front(virtual_addresses_for_nat[iface->getName()].c_str());

                virtual_addresses_for_nat[iface->getName()] =
                    addresses.join(" ").toStdString();
        
                virtual_addresses.push_back(*(addr_addr));
                registerVirtualAddressForNat();
            } else
                warning("Can not add virtual address for object " + addr->getName());
        }
        return;
    }
}
void RoutingRuleOptionsDialog::loadFWObject(FWObject *o)
{
    obj=o;

    FWObject *p = obj;
    while ( !Firewall::cast(p) ) p = p->getParent();
    platform = p->getStr("platform").c_str();

    Rule      *rule = dynamic_cast<Rule*>(o);
    FWOptions *ropt = rule->getOptionsObject();

    int wid = 0;
    if (platform=="iptables") wid = 0;
    else      wid = 1;

    /*
        if (platform=="ipf")      wid = 1;
        if (platform=="pf")       wid = 2;
        if (platform=="ipfw")     wid = 3;
    */

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

    data.clear();

    if (platform=="iptables")
    {
        data.registerOption(m_dialog->routing_non_critical_rule, ropt,  "no_fail");
    }

    init = true;
    data.loadAll();

    init = false;
}
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;
}
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();
                }
            }
        }
    }
}
bool NATCompiler_ipf::AssignInterface::processNext()
{
    NATRule *rule = getNext(); if (rule==NULL) return false;
    RuleElementItfOutb *itf_re = rule->getItfOutb();

    Address *a = NULL;

    switch (rule->getRuleType() )
    {

    case NATRule::Continue:
    case NATRule::NONAT:
    {
/* use heuristic to assign nonat rule to interfaces */
        Interface *iface;

        a=compiler->getFirstODst(rule);
        iface=compiler->findInterfaceFor( compiler->getFirstODst(rule) , 
                                          compiler->fw);
        if (iface!=NULL && !iface->isLoopback()) 
        { 
            if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface);
            // rule->setInterfaceId( iface->getId() );
            tmp_queue.push_back( rule );
            return true;
        }
/* slip into Redirect case to assign rule to all interfaces */
    }

    case NATRule::Redirect: 
    case NATRule::DNAT:
    case NATRule::DNetnat:
    case NATRule::LB:
    {
/*
 * we do not have network zones here, so our ability to pick right
 * interfaces is rather limited. First, we try to find interface that
 * is connected to the subnet OSrc belongs to. If that does not work,
 * we assign rule to all interfaces, except loopback 
 */
        a = NULL;
        if ( ! rule->getOSrc()->isAny() )  a = compiler->getFirstOSrc(rule);
        if ( a==NULL && ! rule->getODst()->isAny() )
            a = compiler->getFirstODst(rule);

        if (a!=NULL)
        {
            Interface *iface;
            iface = compiler->findInterfaceFor(a,compiler->fw);

            if (iface!=NULL && !iface->isLoopback()) 
            { 
                if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface);
                // rule->setInterfaceId( iface->getId() );
                tmp_queue.push_back(rule);
                return true;
            }
        }

        FWObjectTypedChildIterator j=compiler->fw->findByType(Interface::TYPENAME);
        for ( ; j!=j.end(); ++j ) 
        {
            Interface *iface = Interface::cast(*j);
            assert(iface);
            if ( iface->isUnnumbered() || 
                 iface->isBridgePort() || 
                 iface->isLoopback()) continue;

            NATRule *r = compiler->dbcopy->createNATRule();
            compiler->temp_ruleset->add(r);
            r->duplicate(rule);
            RuleElementItfOutb *itf_re = r->getItfOutb();
            if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface);
            //r->setInterfaceId( iface->getId() );
            tmp_queue.push_back( r );
        }
        return true;
    }

    case NATRule::SNAT:
    case NATRule::SNetnat:
    {
        a=compiler->getFirstTSrc(rule);

        if ( (Interface::isA(a) || IPv4::isA(a)) && a->isChildOf(compiler->fw))
        {
            FWObject *p = a;
            while ( ! Interface::isA(p) ) p = p->getParent();
            if ( ! itf_re->hasRef(p)) itf_re->addRef(p);
            // rule->setInterfaceId( p->getId() );
            tmp_queue.push_back(rule);
            return true;
        }

/* if we appear here, then TSrc is not an interface or address of an
 * interface. 
 */
        int n=0;
        list<FWObject*> l2=compiler->fw->getByType(Interface::TYPENAME);
        for (list<FWObject*>::iterator i=l2.begin(); i!=l2.end(); ++i) 
        {
            Interface *iface=Interface::cast(*i);
            assert(iface);

            if (iface->isLoopback() ||
                iface->isUnnumbered() ||
                iface->isBridgePort()) continue;

            NATRule *r = compiler->dbcopy->createNATRule();
            r->duplicate(rule);
            compiler->temp_ruleset->add(r);

            RuleElementItfOutb *itf_re = r->getItfOutb();
            if ( ! itf_re->hasRef(iface)) itf_re->addRef(iface);
            // r->setInterfaceId( iface->getId() );
            
            tmp_queue.push_back(r);
            n++;
        }
        if (n==0) tmp_queue.push_back(rule);

        return true;
    }
    default: ;
    }

    compiler->abort(rule,
                    "Could not assign NAT rule to the interface. "
                    "Perhaps one of the objects has address which does not "
                    "belong to any subnet the firewall has interface on");
    
    return true;
}
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);
}